From fca12418ca716cadc39ae498571bd6634ca3075e Mon Sep 17 00:00:00 2001 From: Josh French Date: Wed, 22 Mar 2023 13:39:55 -0400 Subject: [PATCH] Add activate/deactivate hooks (#452) --- bin/pyenv-sh-activate | 27 +++++++++++++++ bin/pyenv-sh-deactivate | 27 +++++++++++++++ test/activate.bats | 1 + test/conda-activate.bats | 5 +++ test/conda-deactivate.bats | 5 +++ test/deactivate.bats | 3 +- test/hooks.bats | 71 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 138 insertions(+), 1 deletion(-) diff --git a/bin/pyenv-sh-activate b/bin/pyenv-sh-activate index 7d17293..d01d0f1 100755 --- a/bin/pyenv-sh-activate +++ b/bin/pyenv-sh-activate @@ -25,6 +25,27 @@ resolve_link() { unset FORCE unset QUIET +# Define `before_activate` and `after_activate` functions that allow +# plugin hooks to register a string of code for execution before or +# after activating a virtualenv. +declare -a before_hooks after_hooks + +before_activate() { + local hook="$1" + before_hooks["${#before_hooks[@]}"]="$hook" +} + +after_activate() { + local hook="$1" + after_hooks["${#after_hooks[@]}"]="$hook" +} + +# Load plugin hooks. +OLDIFS="$IFS" +IFS=$'\n' scripts=(`pyenv-hooks activate`) +IFS="$OLDIFS" +for script in "${scripts[@]}"; do source "$script"; done + while [ $# -gt 0 ]; do case "$1" in "--complete" ) @@ -137,6 +158,9 @@ fi pyenv-sh-deactivate --force --quiet || true +# Execute `before_activate` hooks. +for hook in "${before_hooks[@]}"; do eval "$hook"; done + if [ -n "$PYENV_VIRTUALENV_VERBOSE_ACTIVATE" ]; then echo "pyenv-virtualenv: activate ${venv}" 1>&2 fi @@ -258,3 +282,6 @@ if [ -d "${prefix}/conda-meta" ] || esac shopt -u nullglob fi + +# Execute `after_activate` hooks. +for hook in "${after_hooks[@]}"; do eval "$hook"; done diff --git a/bin/pyenv-sh-deactivate b/bin/pyenv-sh-deactivate index 4793d6f..5a98142 100755 --- a/bin/pyenv-sh-deactivate +++ b/bin/pyenv-sh-deactivate @@ -16,6 +16,27 @@ fi unset FORCE unset QUIET +# Define `before_deactivate` and `after_deactivate` functions that allow +# plugin hooks to register a string of code for execution before or +# after deactivating a virtualenv. +declare -a before_hooks after_hooks + +before_deactivate() { + local hook="$1" + before_hooks["${#before_hooks[@]}"]="$hook" +} + +after_deactivate() { + local hook="$1" + after_hooks["${#after_hooks[@]}"]="$hook" +} + +# Load plugin hooks. +OLDIFS="$IFS" +IFS=$'\n' scripts=(`pyenv-hooks deactivate`) +IFS="$OLDIFS" +for script in "${scripts[@]}"; do source "$script"; done + while [ $# -gt 0 ]; do case "$1" in "-f" | "--force" ) @@ -54,6 +75,9 @@ else venv="${prefix##*/}" fi +# Execute `before_deactivate` hooks. +for hook in "${before_hooks[@]}"; do eval "$hook"; done + if [ -n "$PYENV_VIRTUALENV_VERBOSE_ACTIVATE" ]; then echo "pyenv-virtualenv: deactivate ${venv}" 1>&2 fi @@ -191,3 +215,6 @@ fi; EOS ;; esac + +# Execute `after_deactivate` hooks. +for hook in "${after_hooks[@]}"; do eval "$hook"; done diff --git a/test/activate.bats b/test/activate.bats index 8e74ce6..1379228 100644 --- a/test/activate.bats +++ b/test/activate.bats @@ -16,6 +16,7 @@ setup() { unset PYENV_VIRTUAL_ENV_DISABLE_PROMPT unset VIRTUAL_ENV_DISABLE_PROMPT unset _OLD_VIRTUAL_PS1 + stub pyenv-hooks "activate : echo" } @test "activate virtualenv from current version" { diff --git a/test/conda-activate.bats b/test/conda-activate.bats index bfdfb23..7469d83 100644 --- a/test/conda-activate.bats +++ b/test/conda-activate.bats @@ -17,6 +17,11 @@ setup() { unset PYENV_VIRTUAL_ENV_DISABLE_PROMPT unset VIRTUAL_ENV_DISABLE_PROMPT unset _OLD_VIRTUAL_PS1 + stub pyenv-hooks "activate : echo" +} + +teardown() { + unstub pyenv-hooks } @test "activate conda root from current version" { diff --git a/test/conda-deactivate.bats b/test/conda-deactivate.bats index 2abab60..905c7e5 100644 --- a/test/conda-deactivate.bats +++ b/test/conda-deactivate.bats @@ -16,6 +16,11 @@ setup() { unset PYENV_VIRTUAL_ENV_DISABLE_PROMPT unset VIRTUAL_ENV_DISABLE_PROMPT unset _OLD_VIRTUAL_PS1 + stub pyenv-hooks "deactivate : echo" +} + +teardown() { + unstub pyenv-hooks } @test "deactivate conda root" { diff --git a/test/deactivate.bats b/test/deactivate.bats index 53ed0cb..e6d366d 100644 --- a/test/deactivate.bats +++ b/test/deactivate.bats @@ -1,4 +1,4 @@ - #!/usr/bin/env bats + #!/usr/bin/env bats load test_helper @@ -16,6 +16,7 @@ setup() { unset PYENV_VIRTUAL_ENV_DISABLE_PROMPT unset VIRTUAL_ENV_DISABLE_PROMPT unset _OLD_VIRTUAL_PS1 + stub pyenv-hooks "deactivate : echo" } @test "deactivate virtualenv" { diff --git a/test/hooks.bats b/test/hooks.bats index 44352fe..3f7bfdf 100644 --- a/test/hooks.bats +++ b/test/hooks.bats @@ -40,3 +40,74 @@ OUT unstub pyenv-rehash teardown_version "3.5.1" } + +@test "pyenv-sh-activate hooks" { + cat > "${HOOK_PATH}/activate.bash" < "${HOOK_PATH}/deactivate.bash" </dev/null 2>&1; then + unset -f deactivate; +fi; +after +EOS + + unstub pyenv-hooks +}