ef32412bae4b563f65ed5f5b7ee0839bfe2be9cb

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

Message

Merge pull request #135 from MichaelAquilina/fix/poetry_activation_bug

Correctly detect poetry virtualenv location

Diff

  1diff --git a/CHANGELOG.rst b/CHANGELOG.rst
  2index 9573f998dfee98ecd055a94372f38e186b056f79..90f7a10245d310b35ec72fb2c5b51380045a3484 100644
  3--- a/CHANGELOG.rst
  4+++ b/CHANGELOG.rst
  5@@ -1,6 +1,10 @@
  6 Changelog
  7 =========
  8 
  9+3.0.1
 10+-----
 11+* Fix issue where poetry projects would not activate if another virtualenv is already activated (#134)
 12+
 13 3.0.0
 14 -----
 15 * Improve integration support for poetry and pipenv. The ``mkvenv`` and ``rmvenv`` commands work as expected.
 16diff --git a/autoswitch_virtualenv.plugin.zsh b/autoswitch_virtualenv.plugin.zsh
 17index 5742ddfa85e3ea59a92b8f7b9510bf270e2cee08..c27a2ab1c81123c7b367b8ca4bf2282473a688b9 100644
 18--- a/autoswitch_virtualenv.plugin.zsh
 19+++ b/autoswitch_virtualenv.plugin.zsh
 20@@ -1,4 +1,4 @@
 21-export AUTOSWITCH_VERSION="3.0.0"
 22+export AUTOSWITCH_VERSION="3.0.1"
 23 export AUTOSWITCH_FILE=".venv"
 24 
 25 RED="\e[31m"
 26@@ -121,17 +121,20 @@ function _maybeworkon() {
 27 function _check_path()
 28 {
 29     local check_dir="$1"
 30-    local check_file="$2"
 31 
 32-    if [[ -f "${check_dir}/$check_file" ]]; then
 33-        printf "${check_dir}/$check_file"
 34+    if [[ -f "${check_dir}/${AUTOSWITCH_FILE}" ]]; then
 35+        printf "${check_dir}/${AUTOSWITCH_FILE}"
 36         return
 37+    elif [[ -f "${check_dir}/poetry.lock" ]]; then
 38+        printf "${check_dir}/poetry.lock"
 39+    elif [[ -f "${check_dir}/Pipfile" ]]; then
 40+        printf "${check_dir}/Pipfile"
 41     else
 42         # Abort search at file system root or HOME directory (latter is a performance optimisation).
 43         if [[ "$check_dir" = "/" || "$check_dir" = "$HOME" ]]; then
 44             return
 45         fi
 46-        _check_path "$(dirname "$check_dir")" "$check_file"
 47+        _check_path "$(dirname "$check_dir")"
 48     fi
 49 }
 50 
 51@@ -139,16 +142,11 @@ function _check_path()
 52 function _activate_poetry() {
 53     # check if any environments exist before trying to activate
 54     # if env list is empty, then no environment exists that can be activated
 55-    if [[ -n "$(poetry env list)" ]]; then
 56-        # we need to infer the target virtualenv directory based on poetry's data
 57-        # to easiest way is to actually get the location of the python binary and
 58-        # infer the location of the virtualenv from there.
 59-        if poetry_python=$(poetry run which python); then
 60-            if venv_path="$(dirname $(dirname $poetry_python))"; then
 61-                _maybeworkon "$venv_path" "poetry"
 62-                return 0
 63-            fi
 64-        fi
 65+    name="$(poetry env list | cut -d' ' -f1)"
 66+    if [[ -n "$name" ]]; then
 67+        local venv_path="$HOME/.cache/pypoetry/virtualenvs/$name"
 68+        _maybeworkon "$venv_path" "poetry"
 69+        return 0
 70     fi
 71     return 1
 72 }
 73@@ -171,7 +169,7 @@ function check_venv()
 74     local file_permissions
 75 
 76     # Get the $AUTOSWITCH_FILE, scanning parent directories
 77-    local venv_path="$(_check_path "$PWD" "$AUTOSWITCH_FILE")"
 78+    local venv_path="$(_check_path "$PWD")"
 79 
 80     if [[ -n "$venv_path" ]]; then
 81 
 82@@ -193,24 +191,19 @@ function check_venv()
 83             printf "Reason: Found a $AUTOSWITCH_FILE file with weak permission settings ($file_permissions).\n"
 84             printf "Run the following command to fix this: ${PURPLE}\"chmod 600 $venv_path\"${NORMAL}\n"
 85         else
 86-            local switch_to="$(<"$venv_path")"
 87-            _maybeworkon "$(_virtual_env_dir "$switch_to")" "virtualenv"
 88-            return
 89-        fi
 90-    fi
 91-
 92-    # check if Pipfile exists rather than invoking pipenv as it is slow
 93-    local pipfile_path="$(_check_path "$PWD" "Pipfile")"
 94-    # Same logic applies to poetry
 95-    local poetry_lock="$(_check_path "$PWD" "poetry.lock")"
 96-
 97-    if [[ -n "$pipfile_path" ]] && type "pipenv" > /dev/null; then
 98-        if _activate_pipenv; then
 99-            return
100-        fi
101-    elif [[ -n "$poetry_lock" ]] && type "poetry" > /dev/null; then
102-        if _activate_poetry; then
103-            return
104+            if [[ "$venv_path" == *"/Pipfile" ]] && type "pipenv" > /dev/null; then
105+                if _activate_pipenv; then
106+                    return
107+                fi
108+            elif [[ "$venv_path" == *"/poetry.lock" ]] && type "poetry" > /dev/null; then
109+                if _activate_poetry; then
110+                    return
111+                fi
112+            else
113+                local switch_to="$(<"$venv_path")"
114+                _maybeworkon "$(_virtual_env_dir "$switch_to")" "virtualenv"
115+                return
116+            fi
117         fi
118     fi
119 
120diff --git a/tests/test_check_path.zunit b/tests/test_check_path.zunit
121index 8ee46795e835de214d6b17df6e691c670d23661b..5fde6998bff10a62a05f9c3aeb8a8ddeef8d16b4 100644
122--- a/tests/test_check_path.zunit
123+++ b/tests/test_check_path.zunit
124@@ -11,17 +11,17 @@
125     rm -rf "$TARGET"
126 }
127 
128-@test '_check_path - test finds in base directory' {
129+@test '_check_path - finds .venv in base directory' {
130     touch "$TARGET/.venv"
131 
132-    run _check_path "$TARGET" ".venv"
133+    run _check_path "$TARGET"
134 
135     assert $state equals 0
136     assert "$output" same_as "$TARGET/.venv"
137 }
138 
139 @test '_check_path - returns nothing if not found' {
140-   run _check_path "$TARGET" ".venv"
141+   run _check_path "$TARGET"
142 
143    assert $state equals 0
144    assert "$output" is_empty
145@@ -31,12 +31,22 @@
146     touch "$TARGET/Pipfile"
147     mkdir "$TARGET/foo"
148 
149-    run _check_path "$TARGET/foo" "Pipfile"
150+    run _check_path "$TARGET/foo"
151 
152     assert $state equals 0
153     assert "$output" same_as "$TARGET/Pipfile"
154 }
155 
156+@test '_check_path - finds in parent directories' {
157+    touch "$TARGET/poetry.lock"
158+    mkdir "$TARGET/foo"
159+
160+    run _check_path "$TARGET/foo"
161+
162+    assert $state equals 0
163+    assert "$output" same_as "$TARGET/poetry.lock"
164+}
165+
166 @test '_check_path - returns nothing with root path' {
167     run _check_path '/' ".venv"
168 
169diff --git a/tests/test_check_venv.zunit b/tests/test_check_venv.zunit
170index 64ea4cc195ff4d557bde2b640595aabd156db86b..f514c969d23c270f22ec7349b1bddba287d3d38d 100644
171--- a/tests/test_check_venv.zunit
172+++ b/tests/test_check_venv.zunit
173@@ -2,6 +2,10 @@
174 
175 @setup {
176 
177+    if [[ ! -d "$HOME/.cache/pypoetry/virtualenvs/poetry-foo" ]]; then
178+        echo "Creating poetry test virtualenv"
179+        run virtualenv "$HOME/.cache/pypoetry/virtualenvs/poetry-foo" --python=python3
180+    fi
181     if [[ ! -d "$HOME/.virtualenvs/foobar/" ]]; then
182         echo "Creating test virtualenv"
183         run virtualenv "$HOME/.virtualenvs/foobar" --python=python3
184@@ -63,6 +67,10 @@
185     PWD="$TARGET"
186     touch "$TARGET/poetry.lock"
187 
188+    function poetry {
189+        echo ""
190+    }
191+
192     run check_venv
193 
194     assert $status equals 0
195@@ -165,33 +173,20 @@
196 }
197 
198 @test 'check_venv - activate if .venv unavailable but poetry available' {
199-    PWD="$TARGET/sub-directory"  # Should also work in subdirectories where pyproject.toml is found
200+    PWD="$TARGET/sub-directory"  # Should also work in subdirectories where poetry.lock is found
201     touch "$TARGET/poetry.lock"
202 
203-    # Mimic "poetry run which python"
204+    # Mimic "poetry env list"
205     function poetry {
206-        echo "$HOME/.virtualenvs/foobar/bin/python"
207+        echo "poetry-foo (activated)"
208     }
209 
210     run check_venv
211 
212     assert $status equals 0
213-    assert "$output" same_as "Switching poetry: \e[1m\e[35mfoobar\e[0m \e[32m[๐Ÿ$PYTHON_VERSION]\e[0m"
214-
215-@test 'check_venv - poetry available but pyproject.toml is not setup for poetry' {
216-    PWD="$TARGET/sub-directory"  # Should also work in subdirectories where pyproject.toml is found
217-    touch "$TARGET/pyproject.toml"
218-
219-    function poetry {
220-        return 1
221-    }
222-
223-    run check_venv
224-    assert $status equals 0
225-    assert "$output" is_empty
226+    assert "$output" same_as "Switching poetry: \e[1m\e[35mpoetry-foo\e[0m \e[32m[๐Ÿ$PYTHON_VERSION]\e[0m"
227 }
228 
229-
230 @test 'check_venv - activate if .venv unavailable but pipenv available' {
231     PWD="$TARGET/sub-directory"  # Should also work in subdirectories where Pipfile is found
232     touch "$TARGET/Pipfile"