65bf8a0220f8b95b0b3309f09236917ce265ab1c

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

Message

Merge pull request #220 from Skesov/feature/fix-venv-directory-detection

fix: prioritize local .venv directory over parent project markers

Diff

  1diff --git a/autoswitch_virtualenv.plugin.zsh b/autoswitch_virtualenv.plugin.zsh
  2index a6c67d2d2df48303ded6943ddba51d481246e095..d7b13a71d23db25b13abc911066c9a468a3bee46 100644
  3--- a/autoswitch_virtualenv.plugin.zsh
  4+++ b/autoswitch_virtualenv.plugin.zsh
  5@@ -47,6 +47,11 @@ function _autoswitch_message() {
  6 }
  7 
  8 
  9+function _is_valid_virtualenv() {
 10+    [[ -d "$1" ]] && [[ -f "$1/bin/activate" ]]
 11+}
 12+
 13+
 14 function _get_venv_type() {
 15     local venv_dir="$1"
 16     local venv_type="${2:-virtualenv}"
 17@@ -126,6 +131,9 @@ function _check_path()
 18     if [[ -f "${check_dir}/${AUTOSWITCH_FILE}" ]]; then
 19         printf "${check_dir}/${AUTOSWITCH_FILE}"
 20         return
 21+    elif _is_valid_virtualenv "${check_dir}/${AUTOSWITCH_FILE}"; then
 22+        printf "${check_dir}/${AUTOSWITCH_FILE}"
 23+        return
 24     elif [[ -f "${check_dir}/poetry.lock" ]]; then
 25         printf "${check_dir}/poetry.lock"
 26     elif [[ -f "${check_dir}/Pipfile" ]]; then
 27@@ -218,8 +226,7 @@ function check_venv()
 28                 local switch_to="$(<"$venv_path")"
 29                 _maybeworkon "$(_virtual_env_dir "$switch_to")" "virtualenv"
 30                 return
 31-            # $venv_path actually is itself a virtualenv
 32-            elif [[ -d "$venv_path" ]] && [[ -f "$venv_path/bin/activate" ]]; then
 33+            elif _is_valid_virtualenv "$venv_path"; then
 34                 _maybeworkon "$venv_path" "virtualenv"
 35                 return
 36             fi
 37diff --git a/tests/test_check_path.zunit b/tests/test_check_path.zunit
 38index 34e16a5a2a51d4c7d9347c96c97e342a723a21f8..c13f802ed39ae92e7b1d3890585fe48071a19df5 100644
 39--- a/tests/test_check_path.zunit
 40+++ b/tests/test_check_path.zunit
 41@@ -53,3 +53,33 @@
 42     assert $state equals 0
 43     assert "$output" is_empty
 44 }
 45+
 46+@test '_check_path - finds .venv directory with bin/activate' {
 47+    mkdir -p "$TARGET/.venv/bin"
 48+    touch "$TARGET/.venv/bin/activate"
 49+
 50+    run _check_path "$TARGET"
 51+
 52+    assert $state equals 0
 53+    assert "$output" same_as "$TARGET/.venv"
 54+}
 55+
 56+@test '_check_path - ignores .venv directory without bin/activate' {
 57+    mkdir -p "$TARGET/.venv"
 58+
 59+    run _check_path "$TARGET"
 60+
 61+    assert $state equals 0
 62+    assert "$output" is_empty
 63+}
 64+
 65+@test '_check_path - finds local .venv directory instead of parent marker' {
 66+    touch "$TARGET/uv.lock"
 67+    mkdir -p "$TARGET/subdir/.venv/bin"
 68+    touch "$TARGET/subdir/.venv/bin/activate"
 69+
 70+    run _check_path "$TARGET/subdir"
 71+
 72+    assert $state equals 0
 73+    assert "$output" same_as "$TARGET/subdir/.venv"
 74+}
 75diff --git a/tests/test_is_valid_virtualenv.zunit b/tests/test_is_valid_virtualenv.zunit
 76new file mode 100644
 77index 0000000000000000000000000000000000000000..924946c908a91fbe97af7fad1d467ee1d8df1155
 78--- /dev/null
 79+++ b/tests/test_is_valid_virtualenv.zunit
 80@@ -0,0 +1,43 @@
 81+#!/usr/bin/env zunit
 82+
 83+
 84+@setup {
 85+    export DISABLE_AUTOSWITCH_VENV="1"
 86+    load "../autoswitch_virtualenv.plugin.zsh"
 87+    TARGET="$(mktemp -d)"
 88+}
 89+
 90+@teardown {
 91+    rm -rf "$TARGET"
 92+}
 93+
 94+@test '_is_valid_virtualenv - returns true for valid virtualenv' {
 95+    mkdir -p "$TARGET/.venv/bin"
 96+    touch "$TARGET/.venv/bin/activate"
 97+
 98+    run _is_valid_virtualenv "$TARGET/.venv"
 99+
100+    assert $state equals 0
101+}
102+
103+@test '_is_valid_virtualenv - returns false for directory without bin/activate' {
104+    mkdir -p "$TARGET/.venv/bin"
105+
106+    run _is_valid_virtualenv "$TARGET/.venv"
107+
108+    assert $state equals 1
109+}
110+
111+@test '_is_valid_virtualenv - returns false for non-existent path' {
112+    run _is_valid_virtualenv "$TARGET/.venv"
113+
114+    assert $state equals 1
115+}
116+
117+@test '_is_valid_virtualenv - returns false for file' {
118+    touch "$TARGET/.venv"
119+
120+    run _is_valid_virtualenv "$TARGET/.venv"
121+
122+    assert $state equals 1
123+}