Skip to content

Commit fca1241

Browse files
authored
Add activate/deactivate hooks (#452)
1 parent 13bc187 commit fca1241

File tree

7 files changed

+138
-1
lines changed

7 files changed

+138
-1
lines changed

bin/pyenv-sh-activate

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,27 @@ resolve_link() {
2525
unset FORCE
2626
unset QUIET
2727

28+
# Define `before_activate` and `after_activate` functions that allow
29+
# plugin hooks to register a string of code for execution before or
30+
# after activating a virtualenv.
31+
declare -a before_hooks after_hooks
32+
33+
before_activate() {
34+
local hook="$1"
35+
before_hooks["${#before_hooks[@]}"]="$hook"
36+
}
37+
38+
after_activate() {
39+
local hook="$1"
40+
after_hooks["${#after_hooks[@]}"]="$hook"
41+
}
42+
43+
# Load plugin hooks.
44+
OLDIFS="$IFS"
45+
IFS=$'\n' scripts=(`pyenv-hooks activate`)
46+
IFS="$OLDIFS"
47+
for script in "${scripts[@]}"; do source "$script"; done
48+
2849
while [ $# -gt 0 ]; do
2950
case "$1" in
3051
"--complete" )
@@ -137,6 +158,9 @@ fi
137158

138159
pyenv-sh-deactivate --force --quiet || true
139160

161+
# Execute `before_activate` hooks.
162+
for hook in "${before_hooks[@]}"; do eval "$hook"; done
163+
140164
if [ -n "$PYENV_VIRTUALENV_VERBOSE_ACTIVATE" ]; then
141165
echo "pyenv-virtualenv: activate ${venv}" 1>&2
142166
fi
@@ -258,3 +282,6 @@ if [ -d "${prefix}/conda-meta" ] ||
258282
esac
259283
shopt -u nullglob
260284
fi
285+
286+
# Execute `after_activate` hooks.
287+
for hook in "${after_hooks[@]}"; do eval "$hook"; done

bin/pyenv-sh-deactivate

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,27 @@ fi
1616
unset FORCE
1717
unset QUIET
1818

19+
# Define `before_deactivate` and `after_deactivate` functions that allow
20+
# plugin hooks to register a string of code for execution before or
21+
# after deactivating a virtualenv.
22+
declare -a before_hooks after_hooks
23+
24+
before_deactivate() {
25+
local hook="$1"
26+
before_hooks["${#before_hooks[@]}"]="$hook"
27+
}
28+
29+
after_deactivate() {
30+
local hook="$1"
31+
after_hooks["${#after_hooks[@]}"]="$hook"
32+
}
33+
34+
# Load plugin hooks.
35+
OLDIFS="$IFS"
36+
IFS=$'\n' scripts=(`pyenv-hooks deactivate`)
37+
IFS="$OLDIFS"
38+
for script in "${scripts[@]}"; do source "$script"; done
39+
1940
while [ $# -gt 0 ]; do
2041
case "$1" in
2142
"-f" | "--force" )
@@ -54,6 +75,9 @@ else
5475
venv="${prefix##*/}"
5576
fi
5677

78+
# Execute `before_deactivate` hooks.
79+
for hook in "${before_hooks[@]}"; do eval "$hook"; done
80+
5781
if [ -n "$PYENV_VIRTUALENV_VERBOSE_ACTIVATE" ]; then
5882
echo "pyenv-virtualenv: deactivate ${venv}" 1>&2
5983
fi
@@ -191,3 +215,6 @@ fi;
191215
EOS
192216
;;
193217
esac
218+
219+
# Execute `after_deactivate` hooks.
220+
for hook in "${after_hooks[@]}"; do eval "$hook"; done

test/activate.bats

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ setup() {
1616
unset PYENV_VIRTUAL_ENV_DISABLE_PROMPT
1717
unset VIRTUAL_ENV_DISABLE_PROMPT
1818
unset _OLD_VIRTUAL_PS1
19+
stub pyenv-hooks "activate : echo"
1920
}
2021

2122
@test "activate virtualenv from current version" {

test/conda-activate.bats

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ setup() {
1717
unset PYENV_VIRTUAL_ENV_DISABLE_PROMPT
1818
unset VIRTUAL_ENV_DISABLE_PROMPT
1919
unset _OLD_VIRTUAL_PS1
20+
stub pyenv-hooks "activate : echo"
21+
}
22+
23+
teardown() {
24+
unstub pyenv-hooks
2025
}
2126

2227
@test "activate conda root from current version" {

test/conda-deactivate.bats

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ setup() {
1616
unset PYENV_VIRTUAL_ENV_DISABLE_PROMPT
1717
unset VIRTUAL_ENV_DISABLE_PROMPT
1818
unset _OLD_VIRTUAL_PS1
19+
stub pyenv-hooks "deactivate : echo"
20+
}
21+
22+
teardown() {
23+
unstub pyenv-hooks
1924
}
2025

2126
@test "deactivate conda root" {

test/deactivate.bats

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env bats
1+
#!/usr/bin/env bats
22

33
load test_helper
44

@@ -16,6 +16,7 @@ setup() {
1616
unset PYENV_VIRTUAL_ENV_DISABLE_PROMPT
1717
unset VIRTUAL_ENV_DISABLE_PROMPT
1818
unset _OLD_VIRTUAL_PS1
19+
stub pyenv-hooks "deactivate : echo"
1920
}
2021

2122
@test "deactivate virtualenv" {

test/hooks.bats

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,74 @@ OUT
4040
unstub pyenv-rehash
4141
teardown_version "3.5.1"
4242
}
43+
44+
@test "pyenv-sh-activate hooks" {
45+
cat > "${HOOK_PATH}/activate.bash" <<OUT
46+
before_activate 'echo "before"'
47+
after_activate 'echo "after"'
48+
OUT
49+
export PYENV_VIRTUALENV_INIT=1
50+
51+
stub pyenv-version-name "echo venv"
52+
stub pyenv-virtualenv-prefix ""
53+
stub pyenv-prefix "venv : echo \"${PYENV_ROOT}/versions/venv\""
54+
stub pyenv-hooks "activate : echo '$HOOK_PATH'/activate.bash"
55+
stub pyenv-sh-deactivate ""
56+
57+
PYENV_SHELL="bash" PYENV_VERSION="venv" run pyenv-sh-activate
58+
59+
assert_success
60+
assert_output <<EOS
61+
before
62+
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv";
63+
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv";
64+
export _OLD_VIRTUAL_PS1="\${PS1:-}";
65+
export PS1="(venv) \${PS1:-}";
66+
after
67+
EOS
68+
69+
unstub pyenv-version-name
70+
unstub pyenv-virtualenv-prefix
71+
unstub pyenv-prefix
72+
unstub pyenv-hooks
73+
unstub pyenv-sh-deactivate
74+
}
75+
76+
@test "deactivate virtualenv" {
77+
cat > "${HOOK_PATH}/deactivate.bash" <<OUT
78+
before_deactivate 'echo "before"'
79+
after_deactivate 'echo "after"'
80+
OUT
81+
export PYENV_VIRTUALENV_INIT=1
82+
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"
83+
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"
84+
export PYENV_ACTIVATE_SHELL=
85+
stub pyenv-hooks "deactivate : echo '$HOOK_PATH'/deactivate.bash"
86+
87+
PYENV_SHELL="bash" run pyenv-sh-deactivate
88+
89+
assert_success
90+
assert_output <<EOS
91+
before
92+
unset PYENV_VIRTUAL_ENV;
93+
unset VIRTUAL_ENV;
94+
if [ -n "\${_OLD_VIRTUAL_PATH:-}" ]; then
95+
export PATH="\${_OLD_VIRTUAL_PATH}";
96+
unset _OLD_VIRTUAL_PATH;
97+
fi;
98+
if [ -n "\${_OLD_VIRTUAL_PYTHONHOME:-}" ]; then
99+
export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}";
100+
unset _OLD_VIRTUAL_PYTHONHOME;
101+
fi;
102+
if [ -n "\${_OLD_VIRTUAL_PS1:-}" ]; then
103+
export PS1="\${_OLD_VIRTUAL_PS1}";
104+
unset _OLD_VIRTUAL_PS1;
105+
fi;
106+
if declare -f deactivate 1>/dev/null 2>&1; then
107+
unset -f deactivate;
108+
fi;
109+
after
110+
EOS
111+
112+
unstub pyenv-hooks
113+
}

0 commit comments

Comments
 (0)