mirror of
https://github.com/asdf-vm/asdf.git
synced 2024-11-15 01:28:17 -07:00
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:
parent
59c1cc0b37
commit
9b27848d07
19
CHANGELOG.md
19
CHANGELOG.md
@ -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
|
||||
|
@ -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
59
bin/private/asdf-tool-exec
Executable 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
|
@ -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
|
||||
done
|
||||
for executable_path in $(plugin_executables "$plugin_name" "$full_version"); do
|
||||
write_shim_script "$plugin_name" "$full_version" "$executable_path"
|
||||
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
|
||||
}
|
||||
|
136
lib/utils.sh
136
lib/utils.sh
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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" {
|
||||
|
@ -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
281
test/shim_exec.bats
Normal 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" ]
|
||||
}
|
@ -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 ]
|
||||
}
|
||||
|
||||
|
@ -79,10 +79,10 @@ teardown() {
|
||||
}
|
||||
|
||||
@test "parse_asdf_version_file should output path version with spaces" {
|
||||
echo "dummy path:/some/dummy path" > $PROJECT_DIR/.tool-versions
|
||||
run parse_asdf_version_file $PROJECT_DIR/.tool-versions dummy
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$output" == "path:/some/dummy path" ]
|
||||
echo "dummy path:/some/dummy path" > $PROJECT_DIR/.tool-versions
|
||||
run parse_asdf_version_file $PROJECT_DIR/.tool-versions dummy
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$output" == "path:/some/dummy path" ]
|
||||
}
|
||||
|
||||
@test "find_version should return .tool-versions if legacy is disabled" {
|
||||
|
Loading…
Reference in New Issue
Block a user