71306f420bf5f8726c20694849bf46c52983ec02

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

Message

Merge pull request #120 from MichaelAquilina/fix/pipenv_subdirs

Fix detection of pipenv projects in subdirectories

Diff

  1diff --git a/CHANGELOG.rst b/CHANGELOG.rst
  2index bb748a33f658c6ca47da06ecfe9074492c19f458..51ae34eac38200d2c399cf51f1a0a35612898c3d 100644
  3--- a/CHANGELOG.rst
  4+++ b/CHANGELOG.rst
  5@@ -1,6 +1,10 @@
  6 Changelog
  7 =========
  8 
  9+1.15.1
 10+------
 11+* Fix detection of pipenv projects from subdirectories
 12+
 13 1.15.0
 14 ------
 15 * Add AUTOSWITCH_FILE configuration option
 16diff --git a/README.rst b/README.rst
 17index 08461a068f485b5252e66604bbac9e210c4e3ddf..4497ee65873b9c0f43ce3d05fce5c4b85c51b9f1 100644
 18--- a/README.rst
 19+++ b/README.rst
 20@@ -31,6 +31,8 @@ now activate every time you enter it.
 21 you to create a virtual environment if e.g. setup.py or requirements.txt is
 22 found in the current directory.
 23 
 24+**NOTE: Pipenv projects should not use ``mkvenv``. Use ``pipenv install`` instead**
 25+
 26 See the Commands_ section below for more detail.
 27 
 28 More Details
 29@@ -47,6 +49,9 @@ same name as the current directory but can be edited if needed). There
 30 is then a precommand hook that looks for a ``.venv`` file and switches
 31 to the name specified if one is found.
 32 
 33+For the case of pipenv projects, the plugin will look for a ``Pipfile``
 34+and activate pipenv if it detects an existing virtual environment for it.
 35+
 36 **NOTE**: you may want to add ``.venv`` to your ``.gitignore`` in git
 37 projects (or equivalent file for the Version Control you are using).
 38 
 39diff --git a/autoswitch_virtualenv.plugin.zsh b/autoswitch_virtualenv.plugin.zsh
 40index d91669ac9eb57b64ad974eea2a29b1bf18fb3136..7b68ca73e3850ea5e2430a18e8fc5688cd375c86 100644
 41--- a/autoswitch_virtualenv.plugin.zsh
 42+++ b/autoswitch_virtualenv.plugin.zsh
 43@@ -1,4 +1,4 @@
 44-export AUTOSWITCH_VERSION="1.15.0"
 45+export AUTOSWITCH_VERSION="1.15.1"
 46 export AUTOSWITCH_FILE=".venv"
 47 
 48 RED="\e[31m"
 49@@ -70,7 +70,8 @@ function _maybeworkon() {
 50         DEFAULT_MESSAGE_FORMAT="${DEFAULT_MESSAGE_FORMAT/🐍/}"
 51     fi
 52 
 53-    if [[ -z "$VIRTUAL_ENV" || "$venv_name" != "$(basename $VIRTUAL_ENV)" ]]; then
 54+    # Don't reactivate an already activated virtual environment
 55+    if [[ -z "$VIRTUAL_ENV" || "$venv_name" != "$(_get_venv_name $VIRTUAL_ENV $venv_type)" ]]; then
 56 
 57         if [[ ! -d "$venv_dir" ]]; then
 58             printf "Unable to find ${PURPLE}$venv_name${NORMAL} virtualenv\n"
 59@@ -97,20 +98,21 @@ function _maybeworkon() {
 60 }
 61 
 62 
 63-# Gives the path to the nearest parent $AUTOSWITCH_FILE or nothing if it gets to root
 64-function _check_venv_path()
 65+# Gives the path to the nearest target file
 66+function _check_path()
 67 {
 68     local check_dir="$1"
 69+    local check_file="$2"
 70 
 71-    if [[ -f "${check_dir}/$AUTOSWITCH_FILE" ]]; then
 72-        printf "${check_dir}/$AUTOSWITCH_FILE"
 73+    if [[ -f "${check_dir}/$check_file" ]]; then
 74+        printf "${check_dir}/$check_file"
 75         return
 76     else
 77         # Abort search at file system root or HOME directory (latter is a performance optimisation).
 78         if [[ "$check_dir" = "/" || "$check_dir" = "$HOME" ]]; then
 79             return
 80         fi
 81-        _check_venv_path "$(dirname "$check_dir")"
 82+        _check_path "$(dirname "$check_dir")" "$check_file"
 83     fi
 84 }
 85 
 86@@ -122,7 +124,7 @@ function check_venv()
 87     local file_permissions
 88 
 89     # Get the $AUTOSWITCH_FILE, scanning parent directories
 90-    local venv_path=$(_check_venv_path "$PWD")
 91+    local venv_path="$(_check_path "$PWD" "$AUTOSWITCH_FILE")"
 92 
 93     if [[ -n "$venv_path" ]]; then
 94 
 95@@ -151,7 +153,9 @@ function check_venv()
 96     fi
 97 
 98     # check if Pipfile exists rather than invoking pipenv as it is slow
 99-    if [[ -f "Pipfile" ]] && type "pipenv" > /dev/null; then
100+    local pipfile_path="$(_check_path "$PWD" "Pipfile")"
101+
102+    if [[ -n "$pipfile_path" ]] && type "pipenv" > /dev/null; then
103         if venv_path="$(PIPENV_IGNORE_VIRTUALENVS=1 pipenv --venv 2>/dev/null)"; then
104             _maybeworkon "$venv_path" "pipenv"
105             return
106diff --git a/tests/test_check_venv_path.zunit b/tests/test_check_path.zunit
107rename from tests/test_check_venv_path.zunit
108rename to tests/test_check_path.zunit
109index c844f40caa06de10a203ab1ff7c053bc0be6cf17..8ee46795e835de214d6b17df6e691c670d23661b 100644
110--- a/tests/test_check_venv_path.zunit
111+++ b/tests/test_check_path.zunit
112@@ -11,34 +11,34 @@
113     rm -rf "$TARGET"
114 }
115 
116-@test '_check_venv_path - test finds in base directory' {
117+@test '_check_path - test finds in base directory' {
118     touch "$TARGET/.venv"
119 
120-    run _check_venv_path "$TARGET"
121+    run _check_path "$TARGET" ".venv"
122 
123     assert $state equals 0
124     assert "$output" same_as "$TARGET/.venv"
125 }
126 
127-@test '_check_venv_path - returns nothing if not found' {
128-   run _check_venv_path "$TARGET"
129+@test '_check_path - returns nothing if not found' {
130+   run _check_path "$TARGET" ".venv"
131 
132    assert $state equals 0
133    assert "$output" is_empty
134 }
135 
136-@test '_check_venv_path - finds .venv in parent directories' {
137-    touch "$TARGET/.venv"
138+@test '_check_path - finds in parent directories' {
139+    touch "$TARGET/Pipfile"
140     mkdir "$TARGET/foo"
141 
142-    run _check_venv_path "$TARGET/foo"
143+    run _check_path "$TARGET/foo" "Pipfile"
144 
145     assert $state equals 0
146-    assert "$output" same_as "$TARGET/.venv"
147+    assert "$output" same_as "$TARGET/Pipfile"
148 }
149 
150-@test '_check_venv_path - returns nothing with root path' {
151-    run _check_venv_path '/'
152+@test '_check_path - returns nothing with root path' {
153+    run _check_path '/' ".venv"
154 
155     assert $state equals 0
156     assert "$output" is_empty
157diff --git a/tests/test_check_venv.zunit b/tests/test_check_venv.zunit
158index 058c815dddcf982768a170e03bc4b1cb2628f082..a1194b02108b45a8e3051f0d87059f805b94d5a7 100644
159--- a/tests/test_check_venv.zunit
160+++ b/tests/test_check_venv.zunit
161@@ -156,9 +156,8 @@
162 
163 
164 @test 'check_venv - activate if .venv unavailable but pipenv available' {
165-    PWD="$TARGET"
166-    VIRTUAL_ENV="foo"
167-    touch "Pipfile"
168+    PWD="$TARGET/sub-directory"  # Should also work in subdirectories where Pipfile is found
169+    touch "$TARGET/Pipfile"
170 
171     function pipenv {
172         echo "$HOME/.virtualenvs/foobar"