user configurable pre-post command hooks

Suppose a `foo` plugin is installed and provides a `bar` executable.
The following hooks will be executed when set in `.asdfrc`:

```shell
post_asdf_install_foo = echo installed foo version ${1}
post_asdf_reshim_foo = echo reshimmed foo version ${1}

pre_foo_bar = echo about to execute command bar from foo with args: ${@}
post_foo_bar = echo just executed command bar from foo with args: ${@}
```
This commit is contained in:
Victor Hugo Borja 2019-01-19 13:00:33 -06:00
parent 2c9621c1cc
commit 9a79ac9526
8 changed files with 125 additions and 6 deletions

View File

@ -4,6 +4,17 @@
Features Features
* Configurable command hooks from `.asdfrc`
Suppose a `foo` plugin is installed and provides a `bar` executable,
The following hooks will be executed when set:
```shell
post_asdf_install_foo = echo installed foo version ${1}
post_asdf_reshim_foo = echo reshimmed foo version ${1}
pre_foo_bar = echo about to execute command bar from foo with args: ${@}
post_foo_bar = echo just executed command bar from foo with args: ${@}
```
* New shim version meta-data allows shims to not depend on a particular plugin * New shim version meta-data allows shims to not depend on a particular plugin
nor on its relative executable path (#431) nor on its relative executable path (#431)
Upgrading requires shim re-generation and should happen automatically by `asdf-exec`: Upgrading requires shim re-generation and should happen automatically by `asdf-exec`:

View File

@ -35,19 +35,29 @@ if [ -z "$selected_version" ]; then
fi fi
if [ ! -z "$selected_version" ]; then if [ ! -z "$selected_version" ]; then
plugin=$(cut -d ' ' -f 1 <<< "$selected_version"); plugin_name=$(cut -d ' ' -f 1 <<< "$selected_version");
version=$(cut -d ' ' -f 2- <<< "$selected_version"); version=$(cut -d ' ' -f 2- <<< "$selected_version");
plugin_path=$(get_plugin_path "$plugin") plugin_path=$(get_plugin_path "$plugin_name")
plugin_exec_env $plugin $version plugin_exec_env $plugin_name $version
executable_path=$(command -v "$shim_name") executable_path=$(command -v "$shim_name")
if [ -x "${plugin_path}/bin/exec-path" ]; then if [ -x "${plugin_path}/bin/exec-path" ]; then
install_path=$(find_install_path "$plugin" "$version") install_path=$(find_install_path "$plugin_name" "$version")
executable_path=$(get_custom_executable_path "${plugin_path}" "${install_path}" "${executable_path}") executable_path=$(get_custom_executable_path "${plugin_path}" "${install_path}" "${executable_path}")
fi fi
exec "$executable_path" "${@:2}" asdf_run_hook "pre_${plugin_name}_${shim_name}" "${@:2}"
pre_status=$?
if [ "$pre_status" -eq 0 ]; then
"$executable_path" "${@:2}"
exit_status=$?
fi
if [ "${exit_status:-${pre_status}}" -eq 0 ]; then
asdf_run_hook "post_${plugin_name}_${shim_name}" "${@:2}"
post_status=$?
fi
exit "${post_status:-${exit_status:-${pre_status}}}"
fi fi
( (

View File

@ -102,6 +102,7 @@ install_tool_version() {
local exit_code=$? local exit_code=$?
if [ $exit_code -eq 0 ]; then if [ $exit_code -eq 0 ]; then
reshim_command "$plugin_name" "$full_version" reshim_command "$plugin_name" "$full_version"
asdf_run_hook "post_asdf_install_${plugin_name}" "$full_version"
else else
handle_failure "$install_path" handle_failure "$install_path"
fi fi

View File

@ -21,6 +21,7 @@ reshim_command() {
if [ "$full_version" != "" ]; then if [ "$full_version" != "" ]; then
# generate for the whole package version # generate for the whole package version
generate_shims_for_version "$plugin_name" "$full_version" generate_shims_for_version "$plugin_name" "$full_version"
asdf_run_hook "post_asdf_reshim_$plugin_name" "$full_version"
else else
# generate for all versions of the package # generate for all versions of the package
local plugin_installs_path local plugin_installs_path
@ -31,8 +32,10 @@ reshim_command() {
full_version_name=$(basename "$install" | sed 's/ref\-/ref\:/') full_version_name=$(basename "$install" | sed 's/ref\-/ref\:/')
generate_shims_for_version "$plugin_name" "$full_version_name" generate_shims_for_version "$plugin_name" "$full_version_name"
remove_obsolete_shims "$plugin_name" "$full_version_name" remove_obsolete_shims "$plugin_name" "$full_version_name"
asdf_run_hook "post_asdf_reshim_$plugin_name" "$full_version_name"
done done
fi fi
} }

View File

@ -310,7 +310,7 @@ get_asdf_config_value_from_file() {
fi fi
local result local result
result=$(grep -E "^\\s*$key\\s*=" "$config_path" | awk -F '=' '{ gsub(/ /, "", $2); print $2 }') result=$(grep -E "^\\s*$key\\s*=\\s*" "$config_path" | head | awk -F '=' '{print $2}' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
if [ -n "$result" ]; then if [ -n "$result" ]; then
echo "$result" echo "$result"
fi fi
@ -540,3 +540,15 @@ shim_plugin_versions() {
} }
asdf_run_hook() {
local hook_name=$1
local hook_cmd
hook_cmd="$(get_asdf_config_value "$hook_name")"
if [ -n "$hook_cmd" ]; then
asdf_hook_fun() {
unset asdf_hook_fun
ev'al' "$hook_cmd" # ignore banned command just here
}
asdf_hook_fun "${@:2}"
fi
}

View File

@ -138,3 +138,12 @@ teardown() {
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
[ ! -f $ASDF_DIR/installs/dummy/system/version ] [ ! -f $ASDF_DIR/installs/dummy/system/version ]
} }
@test "install command executes configured post plugin install hook" {
cat > $HOME/.asdfrc <<-'EOM'
post_asdf_install_dummy = eval echo HEY $version FROM $plugin_name
EOM
run install_command dummy 1.0
[ "$output" == "HEY 1.0 FROM dummy" ]
}

View File

@ -98,3 +98,14 @@ teardown() {
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
[ "1" -eq "$(ls $ASDF_DIR/shims/dummy* | wc -l)" ] [ "1" -eq "$(ls $ASDF_DIR/shims/dummy* | wc -l)" ]
} }
@test "reshim command executes configured post hook" {
run install_command dummy 1.0
cat > $HOME/.asdfrc <<-'EOM'
post_asdf_reshim_dummy = echo RESHIM
EOM
run reshim_command dummy 1.0
[ "$output" == "RESHIM" ]
}

View File

@ -279,3 +279,65 @@ teardown() {
run $ASDF_DIR/shims/dummy run $ASDF_DIR/shims/dummy
[ "$output" == "CUSTOM" ] [ "$output" == "CUSTOM" ]
} }
@test "shim exec executes configured pre-hook" {
run install_command dummy 1.0
echo dummy 1.0 > $PROJECT_DIR/.tool-versions
cat > $HOME/.asdfrc <<-'EOM'
pre_dummy_dummy = echo PRE $version $1 $2
EOM
run $ASDF_DIR/shims/dummy hello world
[ "$status" -eq 0 ]
echo "$output" | grep "PRE 1.0 hello world"
echo "$output" | grep "This is Dummy 1.0! world hello"
}
@test "shim exec doesnt execute command if pre-hook failed" {
run install_command dummy 1.0
echo dummy 1.0 > $PROJECT_DIR/.tool-versions
mkdir $HOME/hook
pre_cmd="$HOME/hook/pre"
echo 'echo $* && false' > "$pre_cmd"
chmod +x "$pre_cmd"
cat > $HOME/.asdfrc <<'EOM'
pre_dummy_dummy = pre $1 no $plugin_name $2
EOM
run env PATH=$PATH:$HOME/hook $ASDF_DIR/shims/dummy hello world
[ "$output" == "hello no dummy world" ]
[ "$status" -eq 1 ]
}
@test "shim exec executes configured post-hook if command was successful" {
run install_command dummy 1.0
echo dummy 1.0 > $PROJECT_DIR/.tool-versions
cat > $HOME/.asdfrc <<-'EOM'
post_dummy_dummy = echo POST $version $1 $2
EOM
run $ASDF_DIR/shims/dummy hello world
[ "$status" -eq 0 ]
echo "$output" | grep "This is Dummy 1.0! world hello"
echo "$output" | grep "POST 1.0 hello world"
}
@test "shim exec does not executes configured post-hook if command failed" {
run install_command dummy 1.0
echo dummy 1.0 > $PROJECT_DIR/.tool-versions
cat > $HOME/.asdfrc <<-'EOM'
post_dummy_dummy = echo POST
EOM
echo "false" > $ASDF_DIR/installs/dummy/1.0/bin/dummy
chmod +x $ASDF_DIR/installs/dummy/1.0/bin/dummy
run $ASDF_DIR/shims/dummy hello world
[ "$status" -eq 1 ]
[ "$output" == "" ]
}