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"