New shim metadata to allow many plugins with same executable names

Features

* New shim version meta-data allows shims to not depend on a particular plugin
  nor on its relative executable path (#431)
  Upgrading requires shim re-generation and should happen automatically
  by `asdf-exec`:
    `rm -rf ~/.asdf/shims/` followed by `asdf reshim`
* Added lots of tests for shim execution.
  We now make sure that shim execution obeys plugins hooks like
  `list-bin-paths` and `exec-path`.
* Shim exec is now performed by a new `bin/private/asdf-tool-exec` that might
  be faster for most common use case: (versions on local .tool-versions file)
  but fallbacks to slower `get_preset_version_for` which takes legacy formats
  into account.
* Shim exec recommends which plugins or versions to set when command is
  not found.

Fixed Bugs

* Allow many plugins to provide shims with same executable name (#431)
This commit is contained in:
Victor Hugo Borja 2019-01-19 04:12:52 -06:00
parent 59c1cc0b37
commit 9b27848d07
10 changed files with 585 additions and 211 deletions

View File

@ -20,6 +20,25 @@ Fixed Bugs
* Fixed user paths for fish (#420, #421)
* Custom exec path tests (#324, #424)
Features
* New shim version meta-data allows shims to not depend on a particular plugin
nor on its relative executable path (#431)
Upgrading requires shim re-generation and should happen automatically by `asdf-exec`:
`rm -rf ~/.asdf/shims/` followed by `asdf reshim`
* Added lots of tests for shim execution.
We now make sure that shim execution obeys plugins hooks like `list-bin-paths` and
`exec-path`.
* Shim exec is now performed by a new `bin/private/asdf-tool-exec` that might be faster
for most common use case: (versions on local .tool-versions file) but fallbacks to
slower `get_preset_version_for` which takes legacy formats into account.
* Shim exec recommends which plugins or versions to set when command is not found.
Fixed Bugs
* Allow many plugins to provide shims with same executable name (#431)
## 0.6.2
Fixed Bugs

View File

@ -1,54 +1,16 @@
#!/usr/bin/env bash
# remove this asdf-exec file when v0.7 becomes the stable version
echo "asdf is self upgrading shims to new asdf-tool-exec"
asdf_dir="$(dirname "$(dirname "$(dirname "$0")")")"
# shellcheck source=lib/utils.sh
source "$(dirname "$(dirname "$(dirname "$0")")")/lib/utils.sh"
source "$asdf_dir/lib/utils.sh"
rm "$(asdf_data_dir)"/shims/*
"$asdf_dir"/bin/asdf reshim
shim_name=$(basename "$2")
plugin_name=$1
executable_path=$2
echo "asdf: now running $shim_name"
plugin_path=$(get_plugin_path "$plugin_name")
check_if_plugin_exists "$plugin_name"
exec "$shim_name" "${@:3}"
full_version=$(get_preset_version_for "$plugin_name")
if [ "$full_version" == "" ]; then
display_no_version_set "$plugin_name"
exit 126
fi
# shellcheck disable=SC2162
IFS=' ' read -a versions <<< "$full_version"
for version in "${versions[@]}"; do
install_path=$(find_install_path "$plugin_name" "$version")
if [ "$version" != "system" ] && [ ! -d "$install_path" ]; then
echo "$plugin_name $version not installed"
exit 127
fi
executable_path=$(get_custom_executable_path "$plugin_path" "$install_path" "$executable_path")
if full_executable_path=$(get_executable_path "$plugin_name" "$version" "$executable_path"); then
if [ -f "$full_executable_path" ]; then
if [ -f "${plugin_path}/bin/exec-env" ]; then
export ASDF_INSTALL_TYPE=$install_type
export ASDF_INSTALL_VERSION=$version
export ASDF_INSTALL_PATH=$install_path
# shellcheck source=/dev/null
source "${plugin_path}/bin/exec-env"
# unset everything, we don't want to pollute
unset ASDF_INSTALL_TYPE
unset ASDF_INSTALL_VERSION
unset ASDF_INSTALL_PATH
fi
exec "$full_executable_path" "${@:3}"
fi
fi
done
echo "No such command in $full_version of $plugin_name"
exit 1

59
bin/private/asdf-tool-exec Executable file
View File

@ -0,0 +1,59 @@
#!/usr/bin/env bash
utils_path="$(dirname "$(dirname "$(dirname "$0")")")/lib/utils.sh"
# shellcheck source=lib/utils.sh
source $utils_path
shim_name="$1"
tool_versions() {
env | awk -F= '/^ASDF_[A-Z]+_VERSION/ {print $1" "$2}' | sed -e "s/^ASDF_//" | sed -e "s/_VERSION / /" | tr "[:upper:]_" "[:lower:]-"
local asdf_versions_path=$(find_tool_versions)
[ -f "${asdf_versions_path}" ] && cat "${asdf_versions_path}"
}
shim_versions() {
shim_plugin_versions "${shim_name}"
shim_plugin_versions "${shim_name}" | cut -d' ' -f 1 | awk '{print$1" system"}'
}
select_from_tool_versions() {
grep -f <(shim_versions) <(tool_versions) | head | xargs
}
preset_versions() {
shim_plugin_versions "${shim_name}" | cut -d' ' -f 1 | uniq | xargs -IPLUGIN bash -c "source $utils_path; echo PLUGIN \$(get_preset_version_for PLUGIN)"
}
select_from_preset_version() {
grep -f <(shim_versions) <(preset_versions) | head | xargs
}
selected_version=$(select_from_tool_versions)
if [ -z "$selected_version" ]; then
selected_version=$(select_from_preset_version)
fi
if [ ! -z "$selected_version" ]; then
plugin=$(cut -d ' ' -f 1 <<< "$selected_version");
version=$(cut -d ' ' -f 2- <<< "$selected_version");
plugin_path=$(get_plugin_path "$plugin")
plugin_exec_env $plugin $version
executable_path=$(command -v "$shim_name")
if [ -x "${plugin_path}/bin/exec-path" ]; then
install_path=$(find_install_path "$plugin" "$version")
executable_path=$(get_custom_executable_path "${plugin_path}" "${install_path}" "${executable_path}")
fi
exec "$executable_path" "${@:2}"
fi
(
echo "asdf: No version set for command ${shim_name}"
echo "you might want to add one of the following in your .tool-versions file:"
echo ""
shim_plugin_versions "${shim_name}"
) >&2
exit 126

View File

@ -1,19 +1,20 @@
shim_command() {
local plugin_name=$1
local executable_path=$2
local plugin_path
plugin_path=$(get_plugin_path "$plugin_name")
check_if_plugin_exists "$plugin_name"
ensure_shims_dir
generate_shim_for_executable "$plugin_name" "$executable_path"
}
reshim_command() {
local plugin_name=$1
local full_version=$2
local plugin_path
plugin_path=$(get_plugin_path "$plugin_name")
if [ -z "$plugin_name" ]; then
local plugins_path
plugins_path=$(get_plugin_path)
if ls "$plugins_path" &> /dev/null; then
for plugin_path in "$plugins_path"/* ; do
plugin_name=$(basename "$plugin_path")
reshim_command "$plugin_name"
done
fi
return 0
fi
check_if_plugin_exists "$plugin_name"
ensure_shims_dir
@ -47,26 +48,27 @@ write_shim_script() {
local plugin_name=$1
local version=$2
local executable_path=$3
if ! is_executable "$executable_path"; then
return 0
fi
local executable_name
executable_name=$(basename "$executable_path")
local plugin_shims_path
plugin_shims_path=$(get_plugin_path "$plugin_name")/shims
local shim_path
shim_path="$(asdf_data_dir)/shims/$executable_name"
if [ -f "$plugin_shims_path/$executable_name" ]; then
cp "$plugin_shims_path/$executable_name" "$shim_path"
elif [ -f "$shim_path" ]; then
if ! grep "# asdf-plugin-version: $version" "$shim_path" > /dev/null; then
sed -i.bak -e "s/\\(asdf-plugin: $plugin_name\\)/\\1\\"$'\n'"# asdf-plugin-version: $version/" "$shim_path"
if [ -f "$shim_path" ]; then
if ! grep "# asdf-plugin: ${plugin_name} ${version}" "$shim_path" >/dev/null; then
sed -i.bak -e "s/exec /# asdf-plugin: ${plugin_name} ${version}\\"$'\n''exec /' "$shim_path"
rm "$shim_path".bak
fi
else
cat <<EOF > "$shim_path"
#!/usr/bin/env bash
# asdf-plugin: ${plugin_name}
# asdf-plugin-version: ${version}
exec $(asdf_dir)/bin/private/asdf-exec ${plugin_name} ${executable_path} "\$@"
# asdf-plugin: ${plugin_name} ${version}
exec $(asdf_dir)/bin/private/asdf-tool-exec "${executable_name}" "\$@"
EOF
fi
@ -77,145 +79,67 @@ EOF
generate_shim_for_executable() {
local plugin_name=$1
local executable=$2
local plugin_path
plugin_path=$(get_plugin_path "$plugin_name")
check_if_plugin_exists "$plugin_name"
local version
IFS=':' read -r -a version_info <<< "$full_version"
if [ "${version_info[0]}" = "ref" ]; then
local install_type="${version_info[0]}"
local version="${version_info[1]}"
version="${version_info[1]}"
else
local install_type="version"
local version="${version_info[0]}"
version="${version_info[0]}"
fi
write_shim_script "$plugin_name" "$version" "$executable"
}
list_plugin_bin_paths() {
local plugin_name=$1
local version=$2
local install_type=$3
local plugin_path
plugin_path=$(get_plugin_path "$plugin_name")
local install_path
install_path=$(get_install_path "$plugin_name" "$install_type" "$version")
if [ -f "${plugin_path}/bin/list-bin-paths" ]; then
local space_separated_list_of_bin_paths
space_separated_list_of_bin_paths=$(
export ASDF_INSTALL_TYPE=$install_type
export ASDF_INSTALL_VERSION=$version
export ASDF_INSTALL_PATH=$install_path
bash "${plugin_path}/bin/list-bin-paths"
)
else
local space_separated_list_of_bin_paths="bin"
fi
echo "$space_separated_list_of_bin_paths"
}
generate_shims_for_version() {
local plugin_name=$1
local full_version=$2
check_if_plugin_exists "$plugin_name"
IFS=':' read -r -a version_info <<< "$full_version"
if [ "${version_info[0]}" = "ref" ]; then
local install_type="${version_info[0]}"
local version="${version_info[1]}"
else
local install_type="version"
local version="${version_info[0]}"
fi
space_separated_list_of_bin_paths="$(list_plugin_bin_paths "$plugin_name" "$version" "$install_type")"
IFS=' ' read -r -a all_bin_paths <<< "$space_separated_list_of_bin_paths"
local install_path
install_path=$(get_install_path "$plugin_name" "$install_type" "$version")
for bin_path in "${all_bin_paths[@]}"; do
for executable_file in "$install_path/$bin_path"/*; do
# because just $executable_file gives absolute path; We don't want version hardcoded in shim
local executable_path_relative_to_install_path
executable_path_relative_to_install_path="$bin_path"/$(basename "$executable_file")
if [[ (-f "$executable_file") && (-x "$executable_file") ]]; then
write_shim_script "$plugin_name" "$version" "$executable_path_relative_to_install_path"
fi
for executable_path in $(plugin_executables "$plugin_name" "$full_version"); do
write_shim_script "$plugin_name" "$full_version" "$executable_path"
done
done
}
shim_still_exists() {
local shim_name=$1
local install_path=$2
local space_separated_list_of_bin_paths=$3
IFS=' ' read -r -a all_bin_paths <<< "$space_separated_list_of_bin_paths"
for bin_path in "${all_bin_paths[@]}"; do
if [ -x "$install_path/$bin_path/$shim_name" ]; then
return 0
fi
done
return 1
}
remove_obsolete_shims() {
local plugin_name=$1
local full_version=$2
local shims_path
shims_path="$(asdf_data_dir)/shims"
IFS=':' read -r -a version_info <<< "$full_version"
if [ "${version_info[0]}" = "ref" ]; then
local install_type="${version_info[0]}"
local version="${version_info[1]}"
else
local install_type="version"
local version="${version_info[0]}"
fi
local shims
shims=$(plugin_shims "$plugin_name" "$full_version" | xargs -IX basename X | sort)
space_separated_list_of_bin_paths="$(list_plugin_bin_paths "$plugin_name" "$version" "$install_type")"
local exec_names
exec_names=$(plugin_executables "$plugin_name" "$full_version" | xargs -IX basename X | sort)
local install_path
install_path=$(get_install_path "$plugin_name" "$install_type" "$version")
local obsolete_shims
obsolete_shims=$(comm -23 <(echo "$shims") <(echo "$exec_names"))
for shim_path in "$shims_path"/*; do
local shim_name
shim_name="$(basename "$shim_path")"
if grep "# asdf-plugin: $plugin_name" "$shim_path" > /dev/null && \
grep "# asdf-plugin-version: $version" "$shim_path" > /dev/null && \
! shim_still_exists "$shim_name" "$install_path" "$space_separated_list_of_bin_paths"; then
remove_shim_for_version "$plugin_name" "$shim_name" "$version"
fi
for shim_name in $obsolete_shims; do
remove_shim_for_version "$plugin_name" "$version" "$shim_name"
done
}
remove_shim_for_version() {
local plugin_name=$1
local executable_name=$2
local version=$3
local plugin_shims_path
plugin_shims_path=$(get_plugin_path "$plugin_name")/shims
local version=$2
local shim_name
shim_name=$(basename "$3")
local shim_path
shim_path="$(asdf_data_dir)/shims/$executable_name"
shim_path="$(asdf_data_dir)/shims/$shim_name"
local count_installed
count_installed=$(list_installed_versions "$plugin_name" | wc -l)
if ! grep "# asdf-plugin: $plugin_name" "$shim_path" > /dev/null 2>&1; then
if ! grep "# asdf-plugin: $plugin_name $version" "$shim_path" > /dev/null 2>&1; then
return 0
fi
sed -i.bak -e "/# asdf-plugin-version: $version/d" "$shim_path"
sed -i.bak -e "/# asdf-plugin: $plugin_name $version/d" "$shim_path"
rm "$shim_path".bak
if [ ! -f "$plugin_shims_path/$executable_name" ] && \
! grep "# asdf-plugin-version" "$shim_path" > /dev/null || \
if ! grep "# asdf-plugin:" "$shim_path" > /dev/null || \
[ "$count_installed" -eq 0 ]; then
rm "$shim_path"
fi
@ -224,24 +148,7 @@ remove_shim_for_version() {
remove_shims_for_version() {
local plugin_name=$1
local full_version=$2
check_if_plugin_exists "$plugin_name"
IFS=':' read -r -a version_info <<< "$full_version"
if [ "${version_info[0]}" = "ref" ]; then
local install_type="${version_info[0]}"
local version="${version_info[1]}"
else
local install_type="version"
local version="${version_info[0]}"
fi
space_separated_list_of_bin_paths="$(list_plugin_bin_paths "$plugin_name" "$version" "$install_type")"
IFS=' ' read -r -a all_bin_paths <<< "$space_separated_list_of_bin_paths"
for bin_path in "${all_bin_paths[@]}"; do
for executable_file in "$install_path/$bin_path"/*; do
local executable_name
executable_name="$(basename "$executable_file")"
remove_shim_for_version "$plugin_name" "$executable_name" "$version"
done
for shim_path in $(plugin_shims "$plugin_name" "$full_version"); do
remove_shim_for_version "$plugin_name" "$version" "$shim_path"
done
}

View File

@ -226,7 +226,7 @@ get_custom_executable_path() {
local executable_path=$3
# custom plugin hook for executable path
if [ -f "${plugin_path}/bin/exec-path" ]; then
if [ -x "${plugin_path}/bin/exec-path" ]; then
cmd=$(basename "$executable_path")
executable_path="$("${plugin_path}/bin/exec-path" "$install_path" "$cmd" "$executable_path")"
fi
@ -406,3 +406,137 @@ resolve_symlink() {
;;
esac
}
list_plugin_bin_paths() {
local plugin_name=$1
local version=$2
local install_type=$3
local plugin_path
plugin_path=$(get_plugin_path "$plugin_name")
local install_path
install_path=$(get_install_path "$plugin_name" "$install_type" "$version")
if [ -f "${plugin_path}/bin/list-bin-paths" ]; then
local space_separated_list_of_bin_paths
# shellcheck disable=SC2030
space_separated_list_of_bin_paths=$(
export ASDF_INSTALL_TYPE=$install_type
export ASDF_INSTALL_VERSION=$version
export ASDF_INSTALL_PATH=$install_path
bash "${plugin_path}/bin/list-bin-paths"
)
else
local space_separated_list_of_bin_paths="bin"
fi
echo "$space_separated_list_of_bin_paths"
}
list_plugin_exec_paths() {
local plugin_name=$1
local full_version=$2
check_if_plugin_exists "$plugin_name"
IFS=':' read -r -a version_info <<< "$full_version"
if [ "${version_info[0]}" = "ref" ]; then
local install_type="${version_info[0]}"
local version="${version_info[1]}"
else
local install_type="version"
local version="${version_info[0]}"
fi
local plugin_shims_path
plugin_shims_path=$(get_plugin_path "$plugin_name")/shims
if [ -d "$plugin_shims_path" ]; then
echo "$plugin_shims_path"
fi
space_separated_list_of_bin_paths="$(list_plugin_bin_paths "$plugin_name" "$version" "$install_type")"
IFS=' ' read -r -a all_bin_paths <<< "$space_separated_list_of_bin_paths"
local install_path
install_path=$(get_install_path "$plugin_name" "$install_type" "$version")
for bin_path in "${all_bin_paths[@]}"; do
echo "$install_path/$bin_path"
done
}
plugin_exec_env() {
local plugin_name=$1
local version=$2
if [ "$version" = "system" ]; then
PATH=$(echo "$PATH" | sed -e "s|$(asdf_data_dir)/shims||g; s|::|:|g")
export PATH
return 0
fi
check_if_plugin_exists "$plugin_name"
local plugin_path
plugin_path=$(get_plugin_path "$plugin_name")
PATH="$(list_plugin_exec_paths "$plugin_name" "$version" | tr '\n' ':'):$PATH"
export PATH
if [ -f "${plugin_path}/bin/exec-env" ]; then
ASDF_INSTALL_TYPE=$install_type
ASDF_INSTALL_VERSION=$version
ASDF_INSTALL_PATH=$install_path
export ASDF_INSTALL_TYPE
export ASDF_INSTALL_VERSION
export ASDF_INSTALL_PATH
# shellcheck source=/dev/null
source "${plugin_path}/bin/exec-env"
# unset everything, we don't want to pollute
unset ASDF_INSTALL_TYPE
unset ASDF_INSTALL_VERSION
unset ASDF_INSTALL_PATH
fi
}
plugin_executables() {
local plugin_name=$1
local full_version=$2
for bin_path in $(list_plugin_exec_paths "$plugin_name" "$full_version"); do
for executable_file in "$bin_path"/*; do
if is_executable "$executable_file"; then
echo "$executable_file"
fi
done
done
}
is_executable() {
local executable_path=$1
if [[ (-f "$executable_path") && (-x "$executable_path") ]]; then
return 0
fi
return 1
}
plugin_shims() {
local plugin_name=$1
local full_version=$2
grep -l "# asdf-plugin: $plugin_name $full_version" "$(asdf_data_dir)/shims"/* 2>/dev/null
}
shim_plugin_versions() {
local executable_name
executable_name=$(basename "$1")
local shim_path
shim_path="$(asdf_data_dir)/shims/${executable_name}"
if [ -x "$shim_path" ]; then
grep -y "# asdf-plugin: " "$shim_path" 2>/dev/null | sed -e "s/# asdf-plugin: //" | uniq
else
echo "asdf: unknown shim $executable_name"
return 1
fi
}

View File

@ -55,28 +55,29 @@ teardown() {
run install_command dummy 1.0
[ "$status" -eq 0 ]
[ -f $ASDF_DIR/installs/dummy/1.0/env ]
run grep "asdf-plugin: dummy" $ASDF_DIR/shims/dummy
[ "$status" -eq 0 ]
run grep "asdf-plugin-version: 1.0" $ASDF_DIR/shims/dummy
run grep "asdf-plugin: dummy 1.0" $ASDF_DIR/shims/dummy
[ "$status" -eq 0 ]
}
@test "install_command should create a shim with asdf-plugin-version metadata" {
@test "install_command on two versions should create a shim with asdf-plugin metadata" {
run install_command dummy 1.1
[ "$status" -eq 0 ]
run grep "asdf-plugin-version: 1.1" $ASDF_DIR/shims/dummy
run grep "asdf-plugin: dummy 1.1" $ASDF_DIR/shims/dummy
[ "$status" -eq 0 ]
run grep "asdf-plugin-version: 1.0" $ASDF_DIR/shims/dummy
run grep "asdf-plugin: dummy 1.0" $ASDF_DIR/shims/dummy
[ "$status" -eq 1 ]
run install_command dummy 1.0
[ "$status" -eq 0 ]
run grep "asdf-plugin-version: 1.0" $ASDF_DIR/shims/dummy
run grep "asdf-plugin: dummy 1.0" $ASDF_DIR/shims/dummy
[ "$status" -eq 0 ]
lines_count=$(grep "asdf-plugin-version: 1.1" $ASDF_DIR/shims/dummy | wc -l)
run grep "# asdf-plugin: dummy 1.0"$'\n'"# asdf-plugin: dummy 1.1" $ASDF_DIR/shims/dummy
[ "$status" -eq 0 ]
lines_count=$(grep "asdf-plugin: dummy 1.1" $ASDF_DIR/shims/dummy | wc -l)
[ "$lines_count" -eq "1" ]
}
@ -99,8 +100,9 @@ teardown() {
run install_command
# execute the generated shim
[ "$($ASDF_DIR/shims/dummy world hello)" == "This is Dummy 1.0! hello world" ]
run $ASDF_DIR/shims/dummy world hello
[ "$status" -eq 0 ]
[ "$output" == "This is Dummy 1.0! hello world" ]
}
@test "install_command fails when the name or version are not specified" {

View File

@ -41,9 +41,9 @@ teardown() {
run reshim_command dummy
[ "$status" -eq 0 ]
[ -f "$ASDF_DIR/shims/dummy" ]
run grep "asdf-plugin-version: 1.0" "$ASDF_DIR/shims/dummy"
run grep "asdf-plugin: dummy 1.0" "$ASDF_DIR/shims/dummy"
[ "$status" -eq 1 ]
run grep "asdf-plugin-version: 1.1" "$ASDF_DIR/shims/dummy"
run grep "asdf-plugin: dummy 1.1" "$ASDF_DIR/shims/dummy"
[ "$status" -eq 0 ]
}
@ -88,3 +88,13 @@ teardown() {
[ "0" -eq "$(ls $ASDF_DIR/shims/subdir* | wc -l)" ]
}
@test "reshim without arguments reshims all installed plugins" {
run install_command dummy 1.0
run rm $ASDF_DIR/shims/*
[ "$status" -eq 0 ]
[ "0" -eq "$(ls $ASDF_DIR/shims/dummy* | wc -l)" ]
run reshim_command
[ "$status" -eq 0 ]
[ "1" -eq "$(ls $ASDF_DIR/shims/dummy* | wc -l)" ]
}

281
test/shim_exec.bats Normal file
View File

@ -0,0 +1,281 @@
#!/usr/bin/env bats
load test_helpers
. $(dirname $BATS_TEST_DIRNAME)/lib/commands/reshim.sh
. $(dirname $BATS_TEST_DIRNAME)/lib/commands/install.sh
setup() {
setup_asdf_dir
install_dummy_plugin
PROJECT_DIR=$HOME/project
mkdir -p $PROJECT_DIR
cd $PROJECT_DIR
# asdf lib needed to run generated shims
cp -rf $BATS_TEST_DIRNAME/../{bin,lib} $ASDF_DIR/
}
teardown() {
clean_asdf_dir
}
@test "shim exec should pass all arguments to executable" {
echo "dummy 1.0" > $PROJECT_DIR/.tool-versions
run install_command
run $ASDF_DIR/shims/dummy world hello
[ "$output" == "This is Dummy 1.0! hello world" ]
[ "$status" -eq 0 ]
}
@test "shim exec should pass stdin to executable" {
echo "dummy 1.0" > $PROJECT_DIR/.tool-versions
run install_command
echo "tr [:lower:] [:upper:]" > $ASDF_DIR/installs/dummy/1.0/bin/upper
chmod +x $ASDF_DIR/installs/dummy/1.0/bin/upper
run reshim_command dummy 1.0
run echo $(echo hello | $ASDF_DIR/shims/upper)
[ "$output" == "HELLO" ]
[ "$status" -eq 0 ]
}
@test "shim exec should fail if no version is selected" {
run install_command dummy 1.0
touch $PROJECT_DIR/.tool-versions
run $ASDF_DIR/shims/dummy world hello
[ "$status" -eq 126 ]
echo "$output" | grep -q "No version set for command dummy" 2>/dev/null
}
@test "shim exec should suggest which plugin to use when no version is selected" {
run install_command dummy 1.0
run install_command dummy 2.0
touch $PROJECT_DIR/.tool-versions
run $ASDF_DIR/shims/dummy world hello
[ "$status" -eq 126 ]
echo "$output" | grep -q "No version set for command dummy" 2>/dev/null
echo "$output" | grep -q "you might want to add one of the following in your .tool-versions file" 2>/dev/null
echo "$output" | grep -q "dummy 1.0" 2>/dev/null
echo "$output" | grep -q "dummy 2.0" 2>/dev/null
}
@test "shim exec should suggest different plugins providing same tool when no version is selected" {
# Another fake plugin with 'dummy' executable
cp -rf $ASDF_DIR/plugins/dummy $ASDF_DIR/plugins/mummy
run install_command dummy 1.0
run install_command mummy 3.0
touch $PROJECT_DIR/.tool-versions
run $ASDF_DIR/shims/dummy world hello
[ "$status" -eq 126 ]
echo "$output" | grep -q "No version set for command dummy" 2>/dev/null
echo "$output" | grep -q "you might want to add one of the following in your .tool-versions file" 2>/dev/null
echo "$output" | grep -q "dummy 1.0" 2>/dev/null
echo "$output" | grep -q "mummy 3.0" 2>/dev/null
}
@test "shim exec should execute first plugin that is installed and set" {
run install_command dummy 3.0
echo "dummy 1.0" > $PROJECT_DIR/.tool-versions
echo "dummy 3.0" >> $PROJECT_DIR/.tool-versions
echo "dummy 2.0" >> $PROJECT_DIR/.tool-versions
run $ASDF_DIR/shims/dummy world hello
[ "$status" -eq 0 ]
echo "$output" | grep -q "This is Dummy 3.0! hello world" 2>/dev/null
}
@test "shim exec should determine correct executable on two projects using different plugins that provide the same tool" {
# Another fake plugin with 'dummy' executable
cp -rf $ASDF_DIR/plugins/dummy $ASDF_DIR/plugins/mummy
sed -i -e 's/Dummy/Mummy/' $ASDF_DIR/plugins/mummy/bin/install
run install_command mummy 3.0
run install_command dummy 1.0
mkdir $PROJECT_DIR/{A,B}
echo "dummy 1.0" > $PROJECT_DIR/A/.tool-versions
echo "mummy 3.0" > $PROJECT_DIR/B/.tool-versions
cd $PROJECT_DIR/A
run $ASDF_DIR/shims/dummy world hello
[ "$output" == "This is Dummy 1.0! hello world" ]
[ "$status" -eq 0 ]
cd $PROJECT_DIR/B
run $ASDF_DIR/shims/dummy world hello
[ "$output" == "This is Mummy 3.0! hello world" ]
[ "$status" -eq 0 ]
}
@test "shim exec should determine correct executable on a project with two plugins set that provide the same tool" {
# Another fake plugin with 'dummy' executable
cp -rf $ASDF_DIR/plugins/dummy $ASDF_DIR/plugins/mummy
sed -i -e 's/Dummy/Mummy/' $ASDF_DIR/plugins/mummy/bin/install
run install_command dummy 1.0
run install_command mummy 3.0
echo "dummy 2.0" > $PROJECT_DIR/.tool-versions
echo "mummy 3.0" >> $PROJECT_DIR/.tool-versions
echo "dummy 1.0" >> $PROJECT_DIR/.tool-versions
run $ASDF_DIR/shims/dummy world hello
[ "$output" == "This is Mummy 3.0! hello world" ]
[ "$status" -eq 0 ]
}
@test "shim exec should fallback to system executable when specified version is system" {
run install_command dummy 1.0
echo "dummy system" > $PROJECT_DIR/.tool-versions
mkdir $PROJECT_DIR/foo/
echo "echo System" > $PROJECT_DIR/foo/dummy
chmod +x $PROJECT_DIR/foo/dummy
run env PATH=$PATH:$PROJECT_DIR/foo $ASDF_DIR/shims/dummy hello
[ "$output" == "System" ]
}
@test "shim exec should execute system if set first" {
run install_command dummy 2.0
echo "dummy system" > $PROJECT_DIR/.tool-versions
echo "dummy 2.0" >> $PROJECT_DIR/.tool-versions
mkdir $PROJECT_DIR/foo/
echo "echo System" > $PROJECT_DIR/foo/dummy
chmod +x $PROJECT_DIR/foo/dummy
run env PATH=$PATH:$PROJECT_DIR/foo $ASDF_DIR/shims/dummy hello
[ "$output" == "System" ]
}
@test "shim exec should use custom exec-env for tool" {
run install_command dummy 2.0
echo "export FOO=sourced" > $ASDF_DIR/plugins/dummy/bin/exec-env
mkdir $ASDF_DIR/plugins/dummy/shims
echo 'echo $FOO custom' > $ASDF_DIR/plugins/dummy/shims/foo
chmod +x $ASDF_DIR/plugins/dummy/shims/foo
run reshim_command dummy 2.0
echo "dummy 2.0" > $PROJECT_DIR/.tool-versions
run $ASDF_DIR/shims/foo
[ "$output" == "sourced custom" ]
}
@test "shim exec doest not use custom exec-env for system version" {
run install_command dummy 2.0
echo "export FOO=sourced" > $ASDF_DIR/plugins/dummy/bin/exec-env
mkdir $ASDF_DIR/plugins/dummy/shims
echo 'echo $FOO custom' > $ASDF_DIR/plugins/dummy/shims/foo
chmod +x $ASDF_DIR/plugins/dummy/shims/foo
run reshim_command dummy 2.0
echo "dummy system" > $PROJECT_DIR/.tool-versions
mkdir $PROJECT_DIR/sys/
echo 'echo x$FOO System' > $PROJECT_DIR/sys/foo
chmod +x $PROJECT_DIR/sys/foo
run env PATH=$PATH:$PROJECT_DIR/sys $ASDF_DIR/shims/foo
[ "$output" == "x System" ]
}
@test "shim exec should prepend the plugin paths on execution" {
run install_command dummy 2.0
mkdir $ASDF_DIR/plugins/dummy/shims
echo 'which dummy' > $ASDF_DIR/plugins/dummy/shims/foo
chmod +x $ASDF_DIR/plugins/dummy/shims/foo
run reshim_command dummy 2.0
echo "dummy 2.0" > $PROJECT_DIR/.tool-versions
run $ASDF_DIR/shims/foo
[ "$output" == "$ASDF_DIR/installs/dummy/2.0/bin/dummy" ]
}
@test "shim exec should remove shim_path from path on system version execution" {
run install_command dummy 2.0
echo "dummy system" > $PROJECT_DIR/.tool-versions
mkdir $PROJECT_DIR/sys/
echo 'which dummy' > $PROJECT_DIR/sys/dummy
chmod +x $PROJECT_DIR/sys/dummy
run env PATH=$PATH:$PROJECT_DIR/sys $ASDF_DIR/shims/dummy
[ "$output" == "$PROJECT_DIR/sys/dummy" ]
}
@test "shim exec can take version from legacy file if configured" {
run install_command dummy 2.0
echo "legacy_version_file = yes" > $HOME/.asdfrc
echo "2.0" > $PROJECT_DIR/.dummy-version
run $ASDF_DIR/shims/dummy world hello
[ "$output" == "This is Dummy 2.0! hello world" ]
}
@test "shim exec can take version from environment variable" {
run install_command dummy 2.0
run env ASDF_DUMMY_VERSION=2.0 $ASDF_DIR/shims/dummy world hello
[ "$output" == "This is Dummy 2.0! hello world" ]
}
@test "shim exec uses plugin list-bin-paths" {
exec_path="$ASDF_DIR/plugins/dummy/bin/list-bin-paths"
custom_path="$ASDF_DIR/installs/dummy/1.0/custom"
echo "echo bin custom" > $exec_path
chmod +x $exec_path
run install_command dummy 1.0
echo "dummy 1.0" > $PROJECT_DIR/.tool-versions
mkdir $custom_path
echo "echo CUSTOM" > $custom_path/foo
chmod +x $custom_path/foo
run reshim_command dummy 1.0
run $ASDF_DIR/shims/foo
[ "$output" == "CUSTOM" ]
}
@test "shim exec uses plugin custom exec-path hook" {
run install_command dummy 1.0
exec_path="$ASDF_DIR/plugins/dummy/bin/exec-path"
custom_dummy="$PROJECT_DIR/custom"
echo "echo $custom_dummy" > $exec_path
chmod +x $exec_path
echo "echo CUSTOM" > $custom_dummy
chmod +x $custom_dummy
echo "dummy 1.0" > $PROJECT_DIR/.tool-versions
run $ASDF_DIR/shims/dummy
[ "$output" == "CUSTOM" ]
}

View File

@ -62,7 +62,7 @@ teardown() {
[ -f $ASDF_DIR/shims/dummy ]
}
@test "uninstall_command should remove relevant asdf-plugin-version metadata" {
@test "uninstall_command should remove relevant asdf-plugin metadata" {
run install_command dummy 1.0
[ -f $ASDF_DIR/installs/dummy/1.0/bin/dummy ]
@ -70,9 +70,9 @@ teardown() {
[ -f $ASDF_DIR/installs/dummy/1.1/bin/dummy ]
run uninstall_command dummy 1.0
run grep "asdf-plugin-version: 1.1" $ASDF_DIR/shims/dummy
run grep "asdf-plugin: dummy 1.1" $ASDF_DIR/shims/dummy
[ "$status" -eq 0 ]
run grep "asdf-plugin-version: 1.0" $ASDF_DIR/shims/dummy
run grep "asdf-plugin: dummy 1.0" $ASDF_DIR/shims/dummy
[ "$status" -eq 1 ]
}