94ea7b4516561c8a7587c7b74351bd6dd4f74583

Author
Dom Sekotill <dom.sekotill@kodo.org.uk>
Committer
GitHub <noreply@github.com>
Date

Message

fix(virtualenvwrapper): several changes for checking git directory, including fixes (#5663)

* Test only for the presence of a .git directory in virtualenvwrapper

Instead of using both $(git rev-parse --show-toplevel) and a check for
a .git directory, use just the latter. As well as being redundant
the former does not work quite so well when using multiple worktrees;
each worktree will be treated as a separate project.

* Unset ENV_NAME & deactivate if no virtualenv found

This addresses #4603 without breaking current behaviour (where current
behaviour is correct).

When changing directories, if there is no environment matching
ENV_NAME, ENV_NAME is emptied and deactivate called if there is a
current environment active (based on CD_VIRTUAL_ENV).

* Use path comparison not string comparison for paths

This will solve part of issue #4255 where WORKON_HOME is defined with a
trailing slash or not normalised in some way, as well as instances
where symlinks are used, and any other instances where constructed
paths don't exactly match even though they go to the same file.

Co-authored-by: Robby Russell <robby@planetargon.com>

Diff

 1diff --git a/plugins/virtualenvwrapper/virtualenvwrapper.plugin.zsh b/plugins/virtualenvwrapper/virtualenvwrapper.plugin.zsh
 2index 88217a7f5bcc74a7bc8c7573b0db829cca850bd2..c30216f51b326b6c2c8a22ded568d02fb8db53c5 100644
 3--- a/plugins/virtualenvwrapper/virtualenvwrapper.plugin.zsh
 4+++ b/plugins/virtualenvwrapper/virtualenvwrapper.plugin.zsh
 5@@ -35,27 +35,19 @@ if [[ ! $DISABLE_VENV_CD -eq 1 ]]; then
 6   function workon_cwd {
 7     if [[ -z "$WORKON_CWD" ]]; then
 8       local WORKON_CWD=1
 9-      # Check if this is a Git repo
10-      local GIT_REPO_ROOT=""
11-      local GIT_TOPLEVEL="$(git rev-parse --show-toplevel 2> /dev/null)"
12-      if [[ $? == 0 ]]; then
13-        GIT_REPO_ROOT="$GIT_TOPLEVEL"
14-      fi
15       # Get absolute path, resolving symlinks
16       local PROJECT_ROOT="${PWD:A}"
17       while [[ "$PROJECT_ROOT" != "/" && ! -e "$PROJECT_ROOT/.venv" \
18-               && ! -d "$PROJECT_ROOT/.git"  && "$PROJECT_ROOT" != "$GIT_REPO_ROOT" ]]; do
19+          && ! -d "$PROJECT_ROOT/.git" ]]; do
20         PROJECT_ROOT="${PROJECT_ROOT:h}"
21       done
22-      if [[ "$PROJECT_ROOT" == "/" ]]; then
23-        PROJECT_ROOT="."
24-      fi
25+
26       # Check for virtualenv name override
27       if [[ -f "$PROJECT_ROOT/.venv" ]]; then
28         ENV_NAME="$(cat "$PROJECT_ROOT/.venv")"
29       elif [[ -f "$PROJECT_ROOT/.venv/bin/activate" ]];then
30         ENV_NAME="$PROJECT_ROOT/.venv"
31-      elif [[ "$PROJECT_ROOT" != "." ]]; then
32+      elif [[ "$PROJECT_ROOT" != "/" ]]; then
33         ENV_NAME="${PROJECT_ROOT:t}"
34       else
35         ENV_NAME=""
36@@ -68,14 +60,21 @@ if [[ ! $DISABLE_VENV_CD -eq 1 ]]; then
37       fi
38       if [[ "$ENV_NAME" != "" ]]; then
39         # Activate the environment only if it is not already active
40-        if [[ "$VIRTUAL_ENV" != "$WORKON_HOME/$ENV_NAME" ]]; then
41+        if [[ ! "$VIRTUAL_ENV" -ef "$WORKON_HOME/$ENV_NAME" ]]; then
42           if [[ -e "$WORKON_HOME/$ENV_NAME/bin/activate" ]]; then
43             workon "$ENV_NAME" && export CD_VIRTUAL_ENV="$ENV_NAME"
44           elif [[ -e "$ENV_NAME/bin/activate" ]]; then
45             source $ENV_NAME/bin/activate && export CD_VIRTUAL_ENV="$ENV_NAME"
46+          else
47+            ENV_NAME=""
48           fi
49         fi
50       fi
51+      if [[ "$ENV_NAME" == "" && -n $CD_VIRTUAL_ENV && -n $VIRTUAL_ENV ]]; then
52+        # We've just left the repo, deactivate the environment
53+        # Note: this only happens if the virtualenv was activated automatically
54+        deactivate && unset CD_VIRTUAL_ENV
55+      fi
56     fi
57   }
58