-
Notifications
You must be signed in to change notification settings - Fork 0
/
autovenv.plugin.zsh
99 lines (85 loc) · 2.75 KB
/
autovenv.plugin.zsh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# Perform an update (leaving, entering, switching virtual environments).
_autovenv_update () {
env_path="$(_autovenv_find_env_path)"
if [ -n "$env_path" ]; then
if _autovenv_in_virtual_env; then
if [ "${env_path:P}" != "${VIRTUAL_ENV:P}" ]; then
echo "autovenv: switching from $VIRTUAL_ENV -> $env_path"
deactivate
source "$env_path"/bin/activate
_autovenv_post-activate_sanity_check "$env_path"
fi
else
echo "autovenv: activating $env_path"
source "$env_path"/bin/activate
_autovenv_post-activate_sanity_check "$env_path"
fi
else
if _autovenv_in_virtual_env; then
echo "autovenv: leaving virtual environment at $VIRTUAL_ENV"
deactivate
fi
fi
}
# Check wether a virtual environment is currently active.
_autovenv_in_virtual_env () {
typeset -f deactivate >/dev/null && [ -v VIRTUAL_ENV ]
return $?
}
_autovenv_post-activate_sanity_check () {
local env_path="$1"
# Check that $VIRTUAL_ENV was set.
if [ ! -v VIRTUAL_ENV ]; then
cat >&2 <<-EOF
autovenv: warning: $env_path/bin/activate did not set \$VIRTUAL_ENV.
The autovenv plugin uses this variable to detect if it's inside a
virtual environment and won't work without it.
EOF
return
fi
# Check if activation script has outdated location.
if [ "${env_path:P}" != "${VIRTUAL_ENV:P}" ]; then
cat >&2 <<-EOF
autovenv: warning: the activation script located at
$env_path/bin/activate
set \$VIRTUAL_ENV to,
${VIRTUAL_ENV:P}
when the expected value was
${env_path:P}
If you moved the parent folder after creating the virtual environment,
you must delete it and create it anew as the activation script still
thinks it's in the old location. The autovenv plugin will behave
strangely becuase of this.
EOF
return
fi
# Check that deactivate function was defined.
if ! typeset -f deactivate >/dev/null; then
cat >&2 <<-EOF
autovenv: warning: $env_path/bin/activate did not define the shell
function \`disable\`. The autovenv plugin uses this variable to detect
if it's inside a virtual environment and won't work without it.
EOF
return
fi
}
# Find closest parent folder that contains a virtual environment.
#
# A directory is said to contain a virtual environment if it contains a child
# directory which contains a file named `pyvenv.cfg`. This function prints the
# name of that child directory.
_autovenv_find_env_path () {
local dir="$PWD"
while [ "$dir" != "/" ]; do
find "$dir" -maxdepth 1 -type d -print0 | while IFS= read -r -d '' subdir; do
if [ -f "$subdir"/pyvenv.cfg ]; then
echo "${subdir:P}"
return
fi
done
dir="${dir:h}"
done
}
# Update between prompts. This allows us to elegantly handle file system
# changes (as opposed to the chpwd-hook).
add-zsh-hook precmd _autovenv_update