ccc99f3bfe6dcdf0b42fb1504c51523126b994ea

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

Message

Correctly detect poetry virtualenv location

Diff

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