diff --git a/.github/workflows/python-publish.yaml b/.github/workflows/python-publish.yaml index 3a33b00..1080258 100644 --- a/.github/workflows/python-publish.yaml +++ b/.github/workflows/python-publish.yaml @@ -14,25 +14,25 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.x' - name: Install dependencies run: | python -m pip install --upgrade pip - pip install setuptools wheel twine pbr + pip install .[build] - name: Build sdist and wheel run: | - python setup.py sdist bdist_wheel + python -m build - name: Publish distribution to PyPI # This condition prevents PRs from being published as part of # the test job. if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') - uses: pypa/gh-action-pypi-publish@v1.8.11 + uses: pypa/gh-action-pypi-publish@v1.14.0 with: password: ${{ secrets.PYPI_API_TOKEN }} verbose: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fdf092d..aeee5e8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,12 +23,12 @@ jobs: - "3.12" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} @@ -48,12 +48,12 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" @@ -77,14 +77,15 @@ jobs: - 3.9 - "3.10" - "3.11" + - "3.12" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} @@ -108,12 +109,12 @@ jobs: - pkglint steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" @@ -132,12 +133,12 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: # Pin this to the same version used on in .readthedocs.yaml python-version: "3.11" diff --git a/.mergify.yml b/.mergify.yml index 390f4eb..d898af4 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -81,6 +81,7 @@ pull_request_rules: - "check-success=Test macOS (3.9)" - "check-success=Test macOS (3.10)" - "check-success=Test macOS (3.11)" + - "check-success=Test macOS (3.12)" - "check-success=Test Ubuntu (3.8)" - "check-success=Test Ubuntu (3.9)" - "check-success=Test Ubuntu (3.10)" diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 67875cf..fba7a7d 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,5 +1,8 @@ version: 2 +sphinx: + configuration: docs/source/conf.py + build: os: "ubuntu-20.04" tools: diff --git a/README.txt b/README.txt index 415130e..6cd1554 100644 --- a/README.txt +++ b/README.txt @@ -61,7 +61,7 @@ we will link to it from this page. Python Versions =============== -virtualenvwrapper is tested under Python 3.8 - 3.11. +virtualenvwrapper is tested under Python 3.8 - 3.12 on macOS and Linux. ======= Support diff --git a/docs/source/design.rst b/docs/source/design.rst index d5eb387..c77e704 100644 --- a/docs/source/design.rst +++ b/docs/source/design.rst @@ -163,14 +163,12 @@ what virtualenvwrapper is doing, it's a natural fit. .. seealso:: - * `Advanced Programming in the UNIX Environment`_ by W. Richard + * *Advanced Programming in the UNIX Environment* by W. Richard Stevens & Stephen A. Rago * `Fork (operating system)`_ on Wikipedia * `Environment variable`_ on Wikipedia * `Linux implementation of fork()`_ -.. _Advanced Programming in the UNIX Environment: https://www.amazon.com/gp/product/0321637739/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0321637739&linkCode=as2&tag=hellflynet-20 - .. _Fork (operating system): https://en.wikipedia.org/wiki/Fork_(operating_system) .. _Environment variable: https://en.wikipedia.org/wiki/Environment_variable diff --git a/docs/source/history.rst b/docs/source/history.rst index 0d46a23..df6b5cf 100644 --- a/docs/source/history.rst +++ b/docs/source/history.rst @@ -1,11 +1,25 @@ CHANGES ======= -Unreleased ----------- +6.1.0 +----- + +* Look for `./.virtualenvwrapper/postactivate` and + `./.virtualenvwrapper/predeactivate` hook scripts. Same effect as + :ref:`scripts-postactivate` and :ref:`scripts-predeactivate`. + +6.0.0.0a5 +--------- * add a --version option to the hook loader * modernize packaging +* docs: update requirements for build on rtd +* docs: add read the docs configuration file +* Changed workon's env switching to use OR not $? by @Nealium (pull request #59) +* Fix issues for python 3.12 by @parona-source (pull request #68) +* Fix shell completion on FreeBSD by @bendikro (pull request #86) +* add python 3.12 to test matrix +* Improve error message for IOErrors by @kerel-fs (pull request #81) 6.0.0.0a1 --------- diff --git a/docs/source/install.rst b/docs/source/install.rst index c7429dd..4af1f06 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -57,7 +57,7 @@ or:: Depending on your MSYS setup, you may need to install the `MSYS mktemp binary`_ in the ``MSYS_HOME/bin`` folder. -.. _MSYS mktemp binary: https://sourceforge.net/projects/mingw/files/MSYS/ +.. _MSYS mktemp binary: https://sourceforge.net/projects/mingw/files/MSYS/Extension/mktemp/ PowerShell ---------- diff --git a/docs/source/projects.rst b/docs/source/projects.rst index d5f6e63..d8e5c84 100644 --- a/docs/source/projects.rst +++ b/docs/source/projects.rst @@ -31,6 +31,22 @@ site, combine the :ref:`templates-bitbucket` and $ mkproject -t bitbucket -t django my_site +Project Hook Files +================== + +The project directory can include additional hook files for the +`postactivate` and `predeactivate` hooks. Placing hook scripts in the +project hook directory, `.virtualenvwrapper`, allows them to be +checked into version control and shared more easily. + +When the :ref:`scripts-postactivate` hook runs, it looks for +`.virtualenvwrapper/postactivate` within the project directory and if +it is found it sources the file. + +When the :ref:`scripts-predeactivate` hook runs, it looks for +`.virtualenvwrapper/predeactivate` within the project directory and if +it is found it sources the file. + .. seealso:: * :ref:`extensions-templates` diff --git a/pyproject.toml b/pyproject.toml index 3e56976..8223276 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,16 @@ dependencies = [ "stevedore", ] +[project.optional-dependencies] +linter = [ + "flake8", +] +build = [ + "build", + "twine", + "check-python-versions", +] + # https://github.com/pypa/setuptools_scm/ [tool.setuptools_scm] write_to = "virtualenvwrapper/version.py" @@ -83,6 +93,7 @@ project = "virtualenvwrapper.project:post_activate_source" user_scripts = "virtualenvwrapper.user_scripts:post_activate_source" [project.entry-points."virtualenvwrapper.pre_deactivate_source"] +project = "virtualenvwrapper.project:pre_deactivate_source" user_scripts = "virtualenvwrapper.user_scripts:pre_deactivate_source" [project.entry-points."virtualenvwrapper.post_deactivate_source"] diff --git a/tests/test_project.sh b/tests/test_project.sh index 6f2c576..10cb53e 100755 --- a/tests/test_project.sh +++ b/tests/test_project.sh @@ -52,4 +52,24 @@ test_virtualenvwrapper_verify_project_home_missing_dir() { PROJECT_HOME="$old_home" } +test_virtualenvwrapper_postactivate_hook() { + load_wrappers + mkproject "test_project_hook" + mkdir .virtualenvwrapper + echo "export TEST_PROJECT_HOOK_VAR=true" > .virtualenvwrapper/postactivate + echo "unset TEST_PROJECT_HOOK_VAR" > .virtualenvwrapper/predeactivate + deactivate + + # Variable should not be set to start + assertSame "${TEST_PROJECT_HOOK_VAR}" "" + + # Activating the env should set it + workon "test_project_hook" + assertSame "true" "${TEST_PROJECT_HOOK_VAR}" + + # Deactivating should unset it + deactivate + assertSame "" "${TEST_PROJECT_HOOK_VAR}" +} + . "$test_dir/shunit2" diff --git a/tox.ini b/tox.ini index ab01679..f4ce1b6 100644 --- a/tox.ini +++ b/tox.ini @@ -20,9 +20,12 @@ setenv = FAIL_FAST = true [testenv:style] -deps = flake8 +deps = .[linter] commands = flake8 virtualenvwrapper docs/source/conf.py +[flake8] +max-line-length = 200 + [testenv:zsh] setenv = USING_TOX = 1 @@ -35,13 +38,15 @@ deps = -r{toxinidir}/docs/requirements.txt commands = sphinx-build -W -j auto -b html -d docs/build/doctrees docs/source docs/build/html + +[testenv:linkcheck] +deps = + -r{toxinidir}/docs/requirements.txt +commands = sphinx-build -W -j auto -b linkcheck -d docs/build/doctrees docs/source docs/build/linkcheck [testenv:pkglint] -deps= - build - twine - check-python-versions +deps=.[build] commands= python -m build twine check dist/*.tar.gz dist/*.whl diff --git a/virtualenvwrapper.sh b/virtualenvwrapper.sh index 66f0f07..26a9452 100644 --- a/virtualenvwrapper.sh +++ b/virtualenvwrapper.sh @@ -96,14 +96,11 @@ export VIRTUALENVWRAPPER_WORKON_CD=${VIRTUALENVWRAPPER_WORKON_CD:-1} # Remember where we are running from. if [ -z "${VIRTUALENVWRAPPER_SCRIPT:-}" ] then - if [ -n "$BASH" ] + if [ -n "${BASH_SOURCE:-}" ] then export VIRTUALENVWRAPPER_SCRIPT="$BASH_SOURCE" - elif [ -n "$ZSH_VERSION" ] - then - export VIRTUALENVWRAPPER_SCRIPT="$0" else - export VIRTUALENVWRAPPER_SCRIPT="${.sh.file}" + export VIRTUALENVWRAPPER_SCRIPT="$0" fi fi @@ -117,12 +114,11 @@ fi # cd because we are trying to change the state of the current shell, # so we use "builtin". function virtualenvwrapper_cd { - if [ -n "${BASH:-}" ] - then - builtin \cd "$@" - elif [ -n "${ZSH_VERSION:-}" ] + if [ -n "${ZSH_VERSION:-}" ] then builtin \cd -q "$@" + else + builtin \cd "$@" fi } @@ -375,7 +371,7 @@ function virtualenvwrapper_verify_active_environment { # Help text for mkvirtualenv function virtualenvwrapper_mkvirtualenv_help { - echo "Usage: mkvirtualenv [-a project_path] [-i package] [-r requirements_file] [virtualenv options] env_name" + echo "Usage: mkvirtualenv [-a project_path] [-i package] [-r requirements_file] [-p python_interpreter] [virtualenv options] env_name" echo echo " -a project_path" echo @@ -391,6 +387,12 @@ function virtualenvwrapper_mkvirtualenv_help { echo echo " Provide a pip requirements file to install a base set of packages" echo " into the new environment." + echo + echo " -p python_interpreter, --python=python_interpreter" + echo + echo " The Python interpreter to use for the new environment." + echo " This can be specified as -p python3.8 or --python=/path/to/python" + echo echo; echo 'virtualenv help:'; echo; @@ -425,7 +427,7 @@ function mkvirtualenv { i=0 tst="-lt" fi - while [ $i $tst $# ] + while test $i $tst $# do a="${in_args[$i]}" # echo "arg $i : $a" @@ -707,7 +709,7 @@ function workon { tst="-lt" fi typeset cd_after_activate=$VIRTUALENVWRAPPER_WORKON_CD - while [ $i $tst $# ] + while test $i $tst $# do a="${in_args[$i]}" case "$a" in @@ -1106,7 +1108,7 @@ function mkproject { i=0 tst="-lt" fi - while [ $i $tst $# ] + while test $i $tst $# do a="${in_args[$i]}" case "$a" in @@ -1213,7 +1215,7 @@ function mktmpenv { tst="-lt" fi typeset cd_after_activate=$VIRTUALENVWRAPPER_WORKON_CD - while [ $i $tst $# ] + while test $i $tst $# do a="${in_args[$i]}" case "$a" in diff --git a/virtualenvwrapper/project.py b/virtualenvwrapper/project.py index 51ec50b..a255081 100644 --- a/virtualenvwrapper/project.py +++ b/virtualenvwrapper/project.py @@ -8,7 +8,7 @@ import logging import os -from virtualenvwrapper.user_scripts import make_hook, run_global, PERMISSIONS +from virtualenvwrapper.user_scripts import PERMISSIONS, make_hook, run_global log = logging.getLogger(__name__) @@ -58,4 +58,19 @@ def post_activate_source(args): -a "$VIRTUALENVWRAPPER_PROJECT_CD" = 1 ] && \ virtualenvwrapper_cd \ "$(cat \"$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME\")" +if [ -f "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME" ]; then + if [ -f "$(cat \"$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME\")/.virtualenvwrapper/postactivate" ]; then + source "$(cat \"$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME\")/.virtualenvwrapper/postactivate" + fi +fi +""" + + +def pre_deactivate_source(args): + return """ +if [ -f "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME" ]; then + if [ -f "$(cat \"$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME\")/.virtualenvwrapper/predeactivate" ]; then + source "$(cat \"$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME\")/.virtualenvwrapper/predeactivate" + fi +fi """