1ac90f84ec20521bab16dd85a6e3288c96d9ab16

Author
Michael Aquilina <michaelaquilina@gmail.com>
Committer
GitHub <noreply@github.com>
Date

Message

Merge pull request #129 from MichaelAquilina/feat/poetry_support

Add support for autoswitching poetry

Diff

  1diff --git a/CHANGELOG.rst b/CHANGELOG.rst
  2index 9c8d8ea8a42989f1c72b6880db5b9e1f51463b33..70b11915ac8e50840cadf5141cc5d45fd6ce9c49 100644
  3--- a/CHANGELOG.rst
  4+++ b/CHANGELOG.rst
  5@@ -1,6 +1,10 @@
  6 Changelog
  7 =========
  8 
  9+2.0.0
 10+-----
 11+* Support autoswitching of poetry projects
 12+
 13 1.16.2
 14 ------
 15 * Output messages to stderr instead of stdout
 16diff --git a/README.rst b/README.rst
 17index dda588d9d7db00f3a6fbb769df095881508c6983..fec802919df3622d64ccd919e2d43dcf89a58054 100644
 18--- a/README.rst
 19+++ b/README.rst
 20@@ -6,7 +6,7 @@ Autoswitch Python Virtualenv
 21 *zsh-autoswitch-virtualenv* is a simple and quick ZSH plugin that switches python
 22 virtualenvs automatically as you move between directories.
 23 
 24-*zsh-autoswitch-virtualenv* also automatically detects and activates your **Pipenv** projects
 25+*zsh-autoswitch-virtualenv* also automatically detects and activates your **Pipenv** and **Poetry** projects
 26 without any setup necessary.
 27 
 28 * `How it Works`_
 29@@ -31,7 +31,9 @@ now activate every time you enter it.
 30 you to create a virtual environment if e.g. setup.py or requirements.txt is
 31 found in the current directory.
 32 
 33-**NOTE: Pipenv projects should not use 'mkvenv'. Use 'pipenv install' instead**
 34+**NOTE: Pipenv and Poetry projects should not use 'mkvenv'.**
 35+
 36+**Use 'pipenv install' or 'poetry install' respectively instead**
 37 
 38 See the Commands_ section below for more detail.
 39 
 40@@ -50,7 +52,10 @@ is then a precommand hook that looks for a ``.venv`` file and switches
 41 to the name specified if one is found.
 42 
 43 For the case of pipenv projects, the plugin will look for a ``Pipfile``
 44-and activate pipenv if it detects an existing virtual environment for it.
 45+and activates pipenv if it detects an existing virtual environment for it.
 46+
 47+For the case of poetry projects, the plugin will look for a ``pyproject.toml``
 48+and activates poetry if it detects an existing virtual environment for it.
 49 
 50 **NOTE**: you may want to add ``.venv`` to your ``.gitignore`` in git
 51 projects (or equivalent file for the Version Control you are using).
 52@@ -232,7 +237,7 @@ By default, the following message is displayed in bold when an alias is found:
 53 
 54 Where the following variables represent:
 55 
 56-* ``%venv_type`` - the type of virtualenv being activated (virtualenv, pipenv)
 57+* ``%venv_type`` - the type of virtualenv being activated (virtualenv, pipenv, poetry)
 58 * ``%venv_name`` - the name of the virtualenv being activated
 59 * ``%py_version`` - the version of python used by the virtualenv being activated
 60 
 61diff --git a/autoswitch_virtualenv.plugin.zsh b/autoswitch_virtualenv.plugin.zsh
 62index 605c2544b5d5623563161012493c5da030513dde..dd34416d374fc5c38ae788c487322389e90c0757 100644
 63--- a/autoswitch_virtualenv.plugin.zsh
 64+++ b/autoswitch_virtualenv.plugin.zsh
 65@@ -1,4 +1,4 @@
 66-export AUTOSWITCH_VERSION="1.16.2"
 67+export AUTOSWITCH_VERSION="2.0.0"
 68 export AUTOSWITCH_FILE=".venv"
 69 
 70 RED="\e[31m"
 71@@ -54,6 +54,10 @@ function _get_venv_type() {
 72         venv_type="pipenv"
 73     elif [[ -f "$venv_dir/requirements.txt" || -f "$venv_dir/setup.py" ]]; then
 74         venv_type="virtualenv"
 75+    # TODO: this is not technically correct as lots of tools use pyproject.toml
 76+    # however it's probably a good enough approximation for this function
 77+    elif [[ -f "$venv_dir/pyproject.toml" ]]; then
 78+        venv_type="poetry"
 79     fi
 80     printf "%s" "$venv_type"
 81 }
 82@@ -170,6 +174,8 @@ function check_venv()
 83 
 84     # check if Pipfile exists rather than invoking pipenv as it is slow
 85     local pipfile_path="$(_check_path "$PWD" "Pipfile")"
 86+    # Same logic applies to poetry
 87+    local pyproject_path="$(_check_path "$PWD" "pyproject.toml")"
 88 
 89     if [[ -n "$pipfile_path" ]] && type "pipenv" > /dev/null; then
 90         # unfortunately running pipenv each time we are in a pipenv project directory is slow :(
 91@@ -177,6 +183,12 @@ function check_venv()
 92             _maybeworkon "$venv_path" "pipenv"
 93             return
 94         fi
 95+    elif [[ -n "$pyproject_path" ]] && type "poetry" > /dev/null; then
 96+        # we need to infer the target virtualenv directory based on poetry's data
 97+        if venv_path="$(dirname $(dirname $(poetry run which python)))"; then
 98+            _maybeworkon "$venv_path" "poetry"
 99+            return
100+        fi
101     fi
102 
103     local venv_type="$(_get_venv_type "$PWD" "unknown")"
104diff --git a/tests/test_check_venv.zunit b/tests/test_check_venv.zunit
105index a1194b02108b45a8e3051f0d87059f805b94d5a7..d942a1e99a274590d0f6f57becd9dc3751370a32 100644
106--- a/tests/test_check_venv.zunit
107+++ b/tests/test_check_venv.zunit
108@@ -154,6 +154,25 @@
109     assert "$output" same_as "Switching virtualenv: \e[1m\e[35mfoodefault\e[0m \e[32m[๐Ÿ$PYTHON_VERSION]\e[0m"
110 }
111 
112+@test 'check_venv - activate if .venv unavailable but poetry available' {
113+    PWD="$TARGET/sub-directory"  # Should also work in subdirectories where pyproject.toml is found
114+    touch "$TARGET/pyproject.toml"
115+
116+    # Mimic poetry run which python
117+    function poetry {
118+        if [[ "$@" == "run which python" ]]; then
119+            echo "$HOME/.virtualenvs/foobar/bin/python"
120+        else
121+            echo "ERROR - wrong command from what was expected ran!"
122+        fi
123+    }
124+
125+    run check_venv
126+
127+    assert $status equals 0
128+    assert "$output" same_as "Switching poetry: \e[1m\e[35mfoobar\e[0m \e[32m[๐Ÿ$PYTHON_VERSION]\e[0m"
129+}
130+
131 
132 @test 'check_venv - activate if .venv unavailable but pipenv available' {
133     PWD="$TARGET/sub-directory"  # Should also work in subdirectories where Pipfile is found