fix: don't invoke asdf inside asdf commands (#1208)

* fix: don't invoke asdf inside asdf commands

Recursive calls have a number of disadvantages:

* Poorer performance since each invocation spawns and new process and re-executes all the code in bin/asdf
* Makes debugging more difficult
* More likely to introduce subtle bugs and the possibility for infinite loops
This commit is contained in:
Trevor Brown 2022-04-25 08:45:19 -04:00 committed by GitHub
parent 713bcebaa7
commit 27f7ef7852
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 813 additions and 780 deletions

View File

@ -1,4 +1,6 @@
# -*- sh -*-
# shellcheck source=lib/functions/plugins.bash
. "$(dirname "$(dirname "$0")")/lib/functions/plugins.bash"
# shellcheck disable=SC2059
plugin_current_command() {
@ -48,7 +50,8 @@ current_command() {
# printf "$terminal_format" "PLUGIN" "VERSION" "SET BY CONFIG" # disbale this until we release headings across the board
if [ $# -eq 0 ]; then
for plugin in $(asdf plugin list); do
# shellcheck disable=SC2119
for plugin in $(plugin_list_command); do
plugin_current_command "$plugin" "$terminal_format"
done
else

View File

@ -1,4 +1,6 @@
# -*- sh -*-
# shellcheck source=lib/functions/versions.bash
. "$(dirname "$(dirname "$0")")/lib/functions/versions.bash"
# Output from this command must be executable shell code
shell_command() {
@ -36,7 +38,7 @@ shell_command() {
exit 0
fi
if [ "$version" = "latest" ]; then
version=$(asdf latest "$plugin")
version=$(latest_command "$plugin")
fi
if ! (check_if_version_exists "$plugin" "$version"); then
version_not_installed_text "$plugin" "$version" 1>&2

View File

@ -1,4 +1,6 @@
# -*- sh -*-
# shellcheck source=lib/functions/versions.bash
. "$(dirname "$(dirname "$0")")/lib/functions/versions.bash"
asdf_help() {
printf "version: %s\\n\\n" "$(asdf_version)"
@ -53,7 +55,7 @@ help_command() {
if [ "${version_info[0]}" = "latest" ]; then
local version
version=$(asdf latest "$plugin_name" "${version_info[1]}")
version=$(latest_command "$plugin_name" "${version_info[1]}")
else
local version="${version_info[0]}"
fi

View File

@ -1,11 +1,13 @@
# -*- sh -*-
# shellcheck source=lib/functions/plugins.bash
. "$(dirname "$(dirname "$0")")/lib/functions/plugins.bash"
info_command() {
printf "%s:\\n%s\\n\\n" "OS" "$(uname -a)"
printf "%s:\\n%s\\n\\n" "SHELL" "$($SHELL --version)"
printf "%s:\\n%s\\n\\n" "ASDF VERSION" "$(asdf_version)"
printf "%s:\\n%s\\n\\n" "ASDF ENVIRONMENT VARIABLES" "$(env | grep -E "ASDF_DIR|ASDF_DATA_DIR|ASDF_CONFIG_FILE|ASDF_DEFAULT_TOOL_VERSIONS_FILENAME")"
printf "%s:\\n%s\\n\\n" "ASDF INSTALLED PLUGINS" "$(asdf plugin list --urls --refs)"
printf "%s:\\n%s\\n\\n" "ASDF INSTALLED PLUGINS" "$(plugin_list_command --urls --refs)"
}
info_command "$@"

View File

@ -1,243 +1,9 @@
# -*- sh -*-
handle_failure() {
local install_path="$1"
rm -rf "$install_path"
exit 1
}
handle_cancel() {
local install_path="$1"
printf "\\nreceived sigint, cleaning up"
handle_failure "$install_path"
}
install_command() {
local plugin_name=$1
local full_version=$2
local extra_args="${*:3}"
if [ "$plugin_name" = "" ] && [ "$full_version" = "" ]; then
install_local_tool_versions "$extra_args"
elif [[ $# -eq 1 ]]; then
install_one_local_tool "$plugin_name"
else
install_tool_version "$plugin_name" "$full_version" "$extra_args"
fi
}
get_concurrency() {
if command -v nproc >/dev/null 2>&1; then
nproc
elif command -v sysctl >/dev/null 2>&1 && sysctl hw.ncpu >/dev/null 2>&1; then
sysctl -n hw.ncpu
elif [ -f /proc/cpuinfo ]; then
grep -c processor /proc/cpuinfo
else
printf "1\\n"
fi
}
install_one_local_tool() {
local plugin_name=$1
local search_path
search_path=$(pwd)
local plugin_versions
local plugin_version
local plugin_version_and_path
plugin_version_and_path="$(find_versions "$plugin_name" "$search_path")"
if [ -n "$plugin_version_and_path" ]; then
local plugin_version
some_tools_installed='yes'
plugin_versions=$(cut -d '|' -f 1 <<<"$plugin_version_and_path")
for plugin_version in $plugin_versions; do
install_tool_version "$plugin_name" "$plugin_version"
done
else
printf "No versions specified for %s in config files or environment\\n" "$plugin_name"
exit 1
fi
}
install_local_tool_versions() {
local plugins_path
plugins_path=$(get_plugin_path)
local search_path
search_path=$(pwd)
local some_tools_installed
local some_plugin_not_installed
local tool_versions_path
tool_versions_path=$(find_tool_versions)
# Locate all the plugins installed in the system
local plugins_installed
if find "$plugins_path" -mindepth 1 -type d &>/dev/null; then
for plugin_path in "$plugins_path"/*; do
local plugin_name
plugin_name=$(basename "$plugin_path")
plugins_installed="$plugins_installed $plugin_name"
done
plugins_installed=$(printf "%s" "$plugins_installed" | tr " " "\n")
fi
if [ -z "$plugins_installed" ]; then
printf "Install plugins first to be able to install tools\\n"
exit 1
fi
# Locate all the plugins defined in the versions file.
local tools_file
if [ -f "$tool_versions_path" ]; then
tools_file=$(strip_tool_version_comments "$tool_versions_path" | cut -d ' ' -f 1)
for plugin_name in $tools_file; do
if ! printf '%s\n' "${plugins_installed[@]}" | grep -q "^$plugin_name\$"; then
printf "%s plugin is not installed\n" "$plugin_name"
some_plugin_not_installed='yes'
fi
done
fi
if [ -n "$some_plugin_not_installed" ]; then
exit 1
fi
if [ -n "$plugins_installed" ]; then
for plugin_name in $plugins_installed; do
local plugin_version_and_path
plugin_version_and_path="$(find_versions "$plugin_name" "$search_path")"
if [ -n "$plugin_version_and_path" ]; then
local plugin_version
some_tools_installed='yes'
plugin_versions=$(cut -d '|' -f 1 <<<"$plugin_version_and_path")
for plugin_version in $plugin_versions; do
install_tool_version "$plugin_name" "$plugin_version"
done
fi
done
fi
if [ -z "$some_tools_installed" ]; then
printf "Either specify a tool & version in the command\\n"
printf "OR add .tool-versions file in this directory\\n"
printf "or in a parent directory\\n"
exit 1
fi
}
install_tool_version() {
local plugin_name=$1
local full_version=$2
local flags=$3
local keep_download
local plugin_path
plugin_path=$(get_plugin_path "$plugin_name")
check_if_plugin_exists "$plugin_name"
for flag in $flags; do
case "$flag" in
"--keep-download")
keep_download=true
shift
;;
*)
shift
;;
esac
done
if [ "$full_version" = "system" ]; then
return
fi
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"
if [ "${version_info[0]}" = "latest" ]; then
local version
version=$(asdf latest "$plugin_name" "${version_info[1]}")
full_version=$version
else
local version="${version_info[0]}"
fi
fi
local install_path
install_path=$(get_install_path "$plugin_name" "$install_type" "$version")
local download_path
download_path=$(get_download_path "$plugin_name" "$install_type" "$version")
local concurrency
concurrency=$(get_concurrency)
trap 'handle_cancel $install_path' INT
if [ -d "$install_path" ]; then
printf "%s %s is already installed\\n" "$plugin_name" "$full_version"
else
if [ -f "${plugin_path}/bin/download" ]; then
# Not a legacy plugin
# Run the download script
(
# shellcheck disable=SC2030
export ASDF_INSTALL_TYPE=$install_type
# shellcheck disable=SC2030
export ASDF_INSTALL_VERSION=$version
# shellcheck disable=SC2030
export ASDF_INSTALL_PATH=$install_path
# shellcheck disable=SC2030
export ASDF_DOWNLOAD_PATH=$download_path
mkdir "$download_path"
asdf_run_hook "pre_asdf_download_${plugin_name}" "$full_version"
"${plugin_path}"/bin/download
)
fi
local download_exit_code=$?
if [ $download_exit_code -eq 0 ]; then
(
# shellcheck disable=SC2031
export ASDF_INSTALL_TYPE=$install_type
# shellcheck disable=SC2031
export ASDF_INSTALL_VERSION=$version
# shellcheck disable=SC2031
export ASDF_INSTALL_PATH=$install_path
# shellcheck disable=SC2031
export ASDF_DOWNLOAD_PATH=$download_path
# shellcheck disable=SC2031
export ASDF_CONCURRENCY=$concurrency
mkdir "$install_path"
asdf_run_hook "pre_asdf_install_${plugin_name}" "$full_version"
"${plugin_path}"/bin/install
)
fi
local install_exit_code=$?
if [ $install_exit_code -eq 0 ] && [ $download_exit_code -eq 0 ]; then
# Remove download directory if --keep-download flag or always_keep_download config setting are not set
always_keep_download=$(get_asdf_config_value "always_keep_download")
if [ ! "$keep_download" = "true" ] && [ ! "$always_keep_download" = "yes" ] && [ -d "$download_path" ]; then
rm -r "$download_path"
fi
asdf reshim "$plugin_name" "$full_version"
asdf_run_hook "post_asdf_install_${plugin_name}" "$full_version"
else
handle_failure "$install_path"
fi
fi
}
# shellcheck source=lib/functions/versions.bash
. "$(dirname "$(dirname "$0")")/lib/functions/versions.bash"
# shellcheck source=lib/commands/reshim.bash
. "$(dirname "$ASDF_CMD_FILE")/reshim.bash"
# shellcheck source=lib/functions/installs.bash
. "$(dirname "$(dirname "$0")")/lib/functions/installs.bash"
install_command "$@"

View File

@ -1,87 +1,5 @@
# -*- sh -*-
latest_command() {
DEFAULT_QUERY="[0-9]"
local plugin_name=$1
local query=$2
local plugin_path
if [ "$plugin_name" == "--all" ]; then
latest_all
fi
[[ -z $query ]] && query="$DEFAULT_QUERY"
plugin_path=$(get_plugin_path "$plugin_name")
check_if_plugin_exists "$plugin_name"
local versions
if [ -f "${plugin_path}/bin/latest-stable" ]; then
versions=$("${plugin_path}"/bin/latest-stable "$query")
if [ -z "${versions}" ]; then
# this branch requires this print to mimic the error from the list-all branch
printf "No compatible versions available (%s %s)\n" "$plugin_name" "$query" >&2
exit 1
fi
else
# pattern from xxenv-latest (https://github.com/momo-lab/xxenv-latest)
versions=$(asdf list-all "$plugin_name" "$query" |
grep -ivE "(^Available versions:|-src|-dev|-latest|-stm|[-\\.]rc|-alpha|-beta|[-\\.]pre|-next|(a|b|c)[0-9]+|snapshot|master)" |
sed 's/^[[:space:]]\+//' |
tail -1)
if [ -z "${versions}" ]; then
exit 1
fi
fi
printf "%s\n" "$versions"
}
latest_all() {
local plugins_path
plugins_path=$(get_plugin_path)
if find "$plugins_path" -mindepth 1 -type d &>/dev/null; then
for plugin_path in "$plugins_path"/*; do
plugin_name=$(basename "$plugin_path")
# Retrieve the version of the plugin
local version
if [ -f "${plugin_path}/bin/latest-stable" ]; then
# We can't filter by a concrete query because different plugins might
# have different queries.
version=$("${plugin_path}"/bin/latest-stable "")
if [ -z "${version}" ]; then
version="unknown"
fi
else
# pattern from xxenv-latest (https://github.com/momo-lab/xxenv-latest)
version=$(asdf list-all "$plugin_name" |
grep -ivE "(^Available version:|-src|-dev|-latest|-stm|[-\\.]rc|-alpha|-beta|[-\\.]pre|-next|(a|b|c)[0-9]+|snapshot|master)" |
sed 's/^[[:space:]]\+//' |
tail -1)
if [ -z "${version}" ]; then
version="unknown"
fi
fi
local installed_status
installed_status="missing"
local installed_versions
installed_versions=$(list_installed_versions "$plugin_name")
if [ -n "$installed_versions" ] && printf '%s\n' "$installed_versions" | grep -q "^$version\$"; then
installed_status="installed"
fi
printf "%s\\t%s\\t%s\\n" "$plugin_name" "$version" "$installed_status"
done
else
printf "%s\\n" 'No plugins installed'
fi
exit 0
}
# shellcheck source=lib/functions/versions.bash
. "$(dirname "$(dirname "$0")")/lib/functions/versions.bash"
latest_command "$@"

View File

@ -1,50 +1,5 @@
# -*- sh -*-
list_all_command() {
local plugin_name=$1
local query=$2
local plugin_path
local std_out_file
local std_err_file
local output
plugin_path=$(get_plugin_path "$plugin_name")
check_if_plugin_exists "$plugin_name"
# Capture return code to allow error handling
std_out_file="$(mktemp "/tmp/asdf-command-list-all-${plugin_name}.stdout.XXXXXX")"
std_err_file="$(mktemp "/tmp/asdf-command-list-all-${plugin_name}.stderr.XXXXXX")"
return_code=0 && "${plugin_path}/bin/list-all" >"$std_out_file" 2>"$std_err_file" || return_code=$?
if [[ $return_code -ne 0 ]]; then
# Printing all output to allow plugin to handle error formatting
printf "Plugin %s's list-all callback script failed with output:\\n" "${plugin_name}" >&2
printf "%s\\n" "$(cat "$std_err_file")" >&2
printf "%s\\n" "$(cat "$std_out_file")" >&2
rm "$std_out_file" "$std_err_file"
exit 1
fi
if [[ $query ]]; then
output=$(tr ' ' '\n' <"$std_out_file" |
grep -E "^\\s*$query" |
tr '\n' ' ')
else
output=$(cat "$std_out_file")
fi
if [ -z "$output" ]; then
display_error "No compatible versions available ($plugin_name $query)"
exit 1
fi
IFS=' ' read -r -a versions_list <<<"$output"
for version in "${versions_list[@]}"; do
printf "%s\\n" "${version}"
done
# Remove temp files if they still exist
rm "$std_out_file" "$std_err_file" || true
}
# shellcheck source=lib/functions/versions.bash
. "$(dirname "$(dirname "$0")")/lib/functions/versions.bash"
list_all_command "$@"

View File

@ -3,30 +3,4 @@
# shellcheck source=lib/commands/version_commands.bash
. "$(dirname "$ASDF_CMD_FILE")/version_commands.bash"
local_command() {
local parent=false
local positional=()
while [[ $# -gt 0 ]]; do
case $1 in
-p | --parent)
parent="true"
shift # past value
;;
*)
positional+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${positional[@]}" # restore positional parameters
if [ $parent = true ]; then
version_command local-tree "$@"
else
version_command local "$@"
fi
}
local_command "$@"

View File

@ -1,58 +1,5 @@
# -*- sh -*-
plugin_add_command() {
if [[ $# -lt 1 || $# -gt 2 ]]; then
display_error "usage: asdf plugin add <name> [<git-url>]"
exit 1
fi
local plugin_name=$1
if ! printf "%s" "$plugin_name" | grep -q -E "^[a-zA-Z0-9_-]+$"; then
display_error "$plugin_name is invalid. Name must match regex ^[a-zA-Z0-9_-]+$"
exit 1
fi
if [ -n "$2" ]; then
local source_url=$2
else
initialize_or_update_repository
local source_url
source_url=$(get_plugin_source_url "$plugin_name")
fi
if [ -z "$source_url" ]; then
display_error "plugin $plugin_name not found in repository"
exit 1
fi
local plugin_path
plugin_path=$(get_plugin_path "$plugin_name")
mkdir -p "$(asdf_data_dir)/plugins"
if [ -d "$plugin_path" ]; then
display_error "Plugin named $plugin_name already added"
exit 2
else
asdf_run_hook "pre_asdf_plugin_add" "$plugin_name"
asdf_run_hook "pre_asdf_plugin_add_${plugin_name}"
if ! git clone -q "$source_url" "$plugin_path"; then
exit 1
fi
if [ -f "${plugin_path}/bin/post-plugin-add" ]; then
(
export ASDF_PLUGIN_SOURCE_URL=$source_url
export ASDF_PLUGIN_PATH=$plugin_path
"${plugin_path}/bin/post-plugin-add"
)
fi
asdf_run_hook "post_asdf_plugin_add" "$plugin_name"
asdf_run_hook "post_asdf_plugin_add_${plugin_name}"
fi
}
# shellcheck source=lib/functions/plugins.bash
. "$(dirname "$(dirname "$0")")/lib/functions/plugins.bash"
plugin_add_command "$@"

View File

@ -1,53 +1,5 @@
# -*- sh -*-
plugin_list_command() {
local plugins_path
plugins_path=$(get_plugin_path)
local show_repo
local show_ref
while [ -n "$*" ]; do
case "$1" in
"--urls")
show_repo=true
shift
;;
"--refs")
show_ref=true
shift
;;
*)
shift
;;
esac
done
if find "$plugins_path" -mindepth 1 -type d &>/dev/null; then
(
for plugin_path in "$plugins_path"/*; do
plugin_name=$(basename "$plugin_path")
printf "%s" "$plugin_name"
if [ -n "$show_repo" ]; then
printf "\\t%s" "$(git --git-dir "$plugin_path/.git" remote get-url origin 2>/dev/null)"
fi
if [ -n "$show_ref" ]; then
local branch
local gitref
branch=$(git --git-dir "$plugin_path/.git" rev-parse --abbrev-ref HEAD 2>/dev/null)
gitref=$(git --git-dir "$plugin_path/.git" rev-parse --short HEAD 2>/dev/null)
printf "\\t%s\\t%s" "$branch" "$gitref"
fi
printf "\\n"
done
) | awk '{ if (NF > 1) { printf("%-28s", $1) ; $1="" }; print $0}'
else
display_error 'No plugins installed'
exit 1
fi
}
# shellcheck source=lib/functions/plugins.bash
. "$(dirname "$(dirname "$0")")/lib/functions/plugins.bash"
plugin_list_command "$@"

View File

@ -1,4 +1,12 @@
# -*- sh -*-
# shellcheck source=lib/functions/versions.bash
. "$(dirname "$(dirname "$0")")/lib/functions/versions.bash"
# shellcheck source=lib/functions/plugins.bash
. "$(dirname "$(dirname "$0")")/lib/functions/plugins.bash"
# shellcheck source=lib/commands/reshim.bash
. "$(dirname "$ASDF_CMD_FILE")/reshim.bash"
# shellcheck source=lib/functions/installs.bash
. "$(dirname "$(dirname "$0")")/lib/functions/installs.bash"
plugin_test_command() {
@ -66,15 +74,16 @@ plugin_test_command() {
# shellcheck disable=SC1090
. "$ASDF_DIR/asdf.sh"
if ! (asdf plugin add "$plugin_name" "$plugin_url"); then
if ! (plugin_add_command "$plugin_name" "$plugin_url"); then
fail_test "could not install $plugin_name from $plugin_url"
fi
if ! (asdf plugin-list | grep "^$plugin_name$" >/dev/null); then
# shellcheck disable=SC2119
if ! (plugin_list_command | grep "^$plugin_name$" >/dev/null); then
fail_test "$plugin_name was not properly installed"
fi
if ! (asdf plugin-update "$plugin_name" "$plugin_gitref"); then
if ! (plugin_update_command "$plugin_name" "$plugin_gitref"); then
fail_test "failed to checkout $plugin_name gitref: $plugin_gitref"
fi
@ -102,7 +111,7 @@ plugin_test_command() {
local versions
# shellcheck disable=SC2046
if ! read -r -a versions <<<$(asdf list-all "$plugin_name"); then
if ! read -r -a versions <<<$(list_all_command "$plugin_name"); then
fail_test "list-all exited with an error"
fi
@ -115,7 +124,7 @@ plugin_test_command() {
# Use the version passed in if it was set. Otherwise grab the latest
# version from the versions list
if [ -z "$tool_version" ] || [[ "$tool_version" == *"latest"* ]]; then
version="$(asdf latest "$plugin_name" "$(sed -e 's#latest##;s#^:##' <<<"$tool_version")")"
version="$(latest_command "$plugin_name" "$(sed -e 's#latest##;s#^:##' <<<"$tool_version")")"
if [ -z "$version" ]; then
fail_test "could not get latest version"
fi
@ -123,17 +132,17 @@ plugin_test_command() {
version="$tool_version"
fi
if ! (asdf install "$plugin_name" "$version"); then
if ! (install_command "$plugin_name" "$version"); then
fail_test "install exited with an error"
fi
cd "$TEST_DIR" || fail_test "could not cd $TEST_DIR"
if ! (asdf local "$plugin_name" "$version"); then
if ! (local_command "$plugin_name" "$version"); then
fail_test "install did not add the requested version"
fi
if ! (asdf reshim "$plugin_name"); then
if ! (reshim_command "$plugin_name"); then
fail_test "could not reshim plugin"
fi

View File

@ -1,66 +1,5 @@
# -*- sh -*-
plugin_update_command() {
if [ "$#" -lt 1 ]; then
display_error "usage: asdf plugin-update {<name> [git-ref] | --all}"
exit 1
fi
local plugin_name="$1"
local gitref="${2}"
local plugins=
if [ "$plugin_name" = "--all" ]; then
if [ -d "$(asdf_data_dir)"/plugins ]; then
plugins=$(find "$(asdf_data_dir)"/plugins -mindepth 1 -maxdepth 1 -type d)
while IFS= read -r dir; do
update_plugin "$(basename "$dir")" "$dir" "$gitref" &
done <<<"$plugins"
wait
fi
else
local plugin_path
plugin_path="$(get_plugin_path "$plugin_name")"
check_if_plugin_exists "$plugin_name"
update_plugin "$plugin_name" "$plugin_path" "$gitref"
fi
}
update_plugin() {
local plugin_name=$1
local plugin_path=$2
plugin_remote_default_branch=$(git --git-dir "$plugin_path/.git" --work-tree "$plugin_path" ls-remote --symref origin HEAD | awk '{ sub(/refs\/heads\//, ""); print $2; exit }')
local gitref=${3:-${plugin_remote_default_branch}}
logfile=$(mktemp)
local common_git_options=(--git-dir "$plugin_path/.git" --work-tree "$plugin_path")
local prev_ref=
local post_ref=
{
asdf_run_hook "pre_asdf_plugin_update" "$plugin_name"
asdf_run_hook "pre_asdf_plugin_update_${plugin_name}"
printf "Updating %s to %s\\n" "$plugin_name" "$gitref"
git "${common_git_options[@]}" fetch --prune --update-head-ok origin "$gitref:$gitref"
prev_ref=$(git "${common_git_options[@]}" rev-parse --short HEAD)
post_ref=$(git "${common_git_options[@]}" rev-parse --short "${gitref}")
git "${common_git_options[@]}" -c advice.detachedHead=false checkout --force "$gitref"
if [ -f "${plugin_path}/bin/post-plugin-update" ]; then
(
export ASDF_PLUGIN_PATH=$plugin_path
export ASDF_PLUGIN_PREV_REF=$prev_ref
export ASDF_PLUGIN_POST_REF=$post_ref
"${plugin_path}/bin/post-plugin-update"
)
fi
asdf_run_hook "post_asdf_plugin_update" "$plugin_name"
asdf_run_hook "post_asdf_plugin_update_${plugin_name}"
} >"$logfile" 2>&1
cat "$logfile"
rm "$logfile"
}
# shellcheck source=lib/functions/plugins.bash
. "$(dirname "$(dirname "$0")")/lib/functions/plugins.bash"
plugin_update_command "$@"

View File

@ -3,141 +3,4 @@
# shellcheck source=lib/commands/reshim.bash
. "$(dirname "$ASDF_CMD_FILE")/reshim.bash"
reshim_command() {
local plugin_name=$1
local full_version=$2
if [ -z "$plugin_name" ]; then
local plugins_path
plugins_path=$(get_plugin_path)
if find "$plugins_path" -mindepth 1 -type d &>/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
if [ "$full_version" != "" ]; then
# generate for the whole package version
asdf_run_hook "pre_asdf_reshim_$plugin_name" "$full_version"
generate_shims_for_version "$plugin_name" "$full_version"
asdf_run_hook "post_asdf_reshim_$plugin_name" "$full_version"
else
# generate for all versions of the package
local plugin_installs_path
plugin_installs_path="$(asdf_data_dir)/installs/${plugin_name}"
for install in "${plugin_installs_path}"/*/; do
local full_version_name
full_version_name=$(basename "$install" | sed 's/ref\-/ref\:/')
asdf_run_hook "pre_asdf_reshim_$plugin_name" "$full_version_name"
generate_shims_for_version "$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
fi
}
ensure_shims_dir() {
# Create shims dir if doesn't exist
if [ ! -d "$(asdf_data_dir)/shims" ]; then
mkdir "$(asdf_data_dir)/shims"
fi
}
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 shim_path
shim_path="$(asdf_data_dir)/shims/$executable_name"
if [ -f "$shim_path" ]; then
if ! grep -x "# 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 -f "$shim_path".bak
fi
else
cat <<EOF >"$shim_path"
#!/usr/bin/env bash
# asdf-plugin: ${plugin_name} ${version}
exec $(asdf_dir)/bin/asdf exec "${executable_name}" "\$@"
EOF
fi
chmod +x "$shim_path"
}
generate_shim_for_executable() {
local plugin_name=$1
local executable=$2
check_if_plugin_exists "$plugin_name"
local version
IFS=':' read -r -a version_info <<<"$full_version"
if [ "${version_info[0]}" = "ref" ]; then
version="${version_info[1]}"
else
version="${version_info[0]}"
fi
write_shim_script "$plugin_name" "$version" "$executable"
}
generate_shims_for_version() {
local plugin_name=$1
local full_version=$2
local all_executable_paths
IFS=$'\n' read -rd '' -a all_executable_paths <<<"$(plugin_executables "$plugin_name" "$full_version")"
for executable_path in "${all_executable_paths[@]}"; do
write_shim_script "$plugin_name" "$full_version" "$executable_path"
done
}
remove_obsolete_shims() {
local plugin_name=$1
local full_version=$2
local shims
shims=$(plugin_shims "$plugin_name" "$full_version" | xargs -IX basename X | sort)
local exec_names
exec_names=$(plugin_executables "$plugin_name" "$full_version" | xargs -IX basename X | sort)
local obsolete_shims
local formatted_shims
local formatted_exec_names
# comm only takes to files, so we write this data to temp files so we can
# pass it to comm.
formatted_shims=$(mktemp /tmp/asdf-command-reshim-formatted-shims.XXXXXX)
printf "%s\\n" "$shims" >"$formatted_shims"
formatted_exec_names=$(mktemp /tmp/asdf-command-reshim-formatted-exec-names.XXXXXX)
printf "%s\\n" "$exec_names" >"$formatted_exec_names"
obsolete_shims=$(comm -23 "$formatted_shims" "$formatted_exec_names")
rm -f "$formatted_exec_names" "$formatted_shims"
for shim_name in $obsolete_shims; do
remove_shim_for_version "$plugin_name" "$full_version" "$shim_name"
done
}
reshim_command "$@"

View File

@ -23,3 +23,140 @@ remove_shim_for_version() {
rm -f "$shim_path"
fi
}
reshim_command() {
local plugin_name=$1
local full_version=$2
if [ -z "$plugin_name" ]; then
local plugins_path
plugins_path=$(get_plugin_path)
if find "$plugins_path" -mindepth 1 -type d &>/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
if [ "$full_version" != "" ]; then
# generate for the whole package version
asdf_run_hook "pre_asdf_reshim_$plugin_name" "$full_version"
generate_shims_for_version "$plugin_name" "$full_version"
asdf_run_hook "post_asdf_reshim_$plugin_name" "$full_version"
else
# generate for all versions of the package
local plugin_installs_path
plugin_installs_path="$(asdf_data_dir)/installs/${plugin_name}"
for install in "${plugin_installs_path}"/*/; do
local full_version_name
full_version_name=$(basename "$install" | sed 's/ref\-/ref\:/')
asdf_run_hook "pre_asdf_reshim_$plugin_name" "$full_version_name"
generate_shims_for_version "$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
fi
}
ensure_shims_dir() {
# Create shims dir if doesn't exist
if [ ! -d "$(asdf_data_dir)/shims" ]; then
mkdir "$(asdf_data_dir)/shims"
fi
}
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 shim_path
shim_path="$(asdf_data_dir)/shims/$executable_name"
if [ -f "$shim_path" ]; then
if ! grep -x "# 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 -f "$shim_path".bak
fi
else
cat <<EOF >"$shim_path"
#!/usr/bin/env bash
# asdf-plugin: ${plugin_name} ${version}
exec $(asdf_dir)/bin/asdf exec "${executable_name}" "\$@"
EOF
fi
chmod +x "$shim_path"
}
generate_shim_for_executable() {
local plugin_name=$1
local executable=$2
check_if_plugin_exists "$plugin_name"
local version
IFS=':' read -r -a version_info <<<"$full_version"
if [ "${version_info[0]}" = "ref" ]; then
version="${version_info[1]}"
else
version="${version_info[0]}"
fi
write_shim_script "$plugin_name" "$version" "$executable"
}
generate_shims_for_version() {
local plugin_name=$1
local full_version=$2
local all_executable_paths
IFS=$'\n' read -rd '' -a all_executable_paths <<<"$(plugin_executables "$plugin_name" "$full_version")"
for executable_path in "${all_executable_paths[@]}"; do
write_shim_script "$plugin_name" "$full_version" "$executable_path"
done
}
remove_obsolete_shims() {
local plugin_name=$1
local full_version=$2
local shims
shims=$(plugin_shims "$plugin_name" "$full_version" | xargs -IX basename X | sort)
local exec_names
exec_names=$(plugin_executables "$plugin_name" "$full_version" | xargs -IX basename X | sort)
local obsolete_shims
local formatted_shims
local formatted_exec_names
# comm only takes to files, so we write this data to temp files so we can
# pass it to comm.
formatted_shims=$(mktemp /tmp/asdf-command-reshim-formatted-shims.XXXXXX)
printf "%s\\n" "$shims" >"$formatted_shims"
formatted_exec_names=$(mktemp /tmp/asdf-command-reshim-formatted-exec-names.XXXXXX)
printf "%s\\n" "$exec_names" >"$formatted_exec_names"
obsolete_shims=$(comm -23 "$formatted_shims" "$formatted_exec_names")
rm -f "$formatted_exec_names" "$formatted_shims"
for shim_name in $obsolete_shims; do
remove_shim_for_version "$plugin_name" "$full_version" "$shim_name"
done
}

View File

@ -1,67 +1,3 @@
# -*- sh -*-
version_command() {
local cmd=$1
local plugin_name=$2
if [ "$#" -lt "3" ]; then
if [ "$cmd" = "global" ]; then
printf "Usage: asdf global <name> <version>\\n"
else
printf "Usage: asdf local <name> <version>\\n"
fi
exit 1
fi
shift 2
local versions=("$@")
local file
if [ "$cmd" = "global" ]; then
file=${ASDF_DEFAULT_TOOL_VERSIONS_FILENAME:-$HOME/.tool-versions}
elif [ "$cmd" = "local-tree" ]; then
file=$(find_tool_versions)
else # cmd = local
file="$(pwd)/.tool-versions"
fi
if [ -L "$file" ]; then
# Resolve file path if symlink
file="$(resolve_symlink "$file")"
fi
check_if_plugin_exists "$plugin_name"
declare -a resolved_versions
local item
for item in "${!versions[@]}"; do
IFS=':' read -r -a version_info <<<"${versions[$item]}"
if [ "${version_info[0]}" = "latest" ] && [ -n "${version_info[1]}" ]; then
version=$(asdf latest "$plugin_name" "${version_info[1]}")
elif [ "${version_info[0]}" = "latest" ] && [ -z "${version_info[1]}" ]; then
version=$(asdf latest "$plugin_name")
else
# if branch handles ref: || path: || normal versions
version="${versions[$item]}"
fi
# check_if_version_exists should probably handle if either param is empty string
if [ -z "$version" ]; then
exit 1
fi
if ! (check_if_version_exists "$plugin_name" "$version"); then
version_not_installed_text "$plugin_name" "$version" 1>&2
exit 1
fi
resolved_versions+=("$version")
done
if [ -f "$file" ] && grep "^$plugin_name " "$file" >/dev/null; then
sed -i.bak -e "s|^$plugin_name .*$|$plugin_name ${resolved_versions[*]}|" "$file"
rm -f "$file".bak
else
printf "%s %s\\n" "$plugin_name" "${resolved_versions[*]}" >>"$file"
fi
}
# shellcheck source=lib/functions/versions.bash
. "$(dirname "$(dirname "$0")")/lib/functions/versions.bash"

239
lib/functions/installs.bash Normal file
View File

@ -0,0 +1,239 @@
handle_failure() {
local install_path="$1"
rm -rf "$install_path"
exit 1
}
handle_cancel() {
local install_path="$1"
printf "\\nreceived sigint, cleaning up"
handle_failure "$install_path"
}
install_command() {
local plugin_name=$1
local full_version=$2
local extra_args="${*:3}"
if [ "$plugin_name" = "" ] && [ "$full_version" = "" ]; then
install_local_tool_versions "$extra_args"
elif [[ $# -eq 1 ]]; then
install_one_local_tool "$plugin_name"
else
install_tool_version "$plugin_name" "$full_version" "$extra_args"
fi
}
get_concurrency() {
if command -v nproc >/dev/null 2>&1; then
nproc
elif command -v sysctl >/dev/null 2>&1 && sysctl hw.ncpu >/dev/null 2>&1; then
sysctl -n hw.ncpu
elif [ -f /proc/cpuinfo ]; then
grep -c processor /proc/cpuinfo
else
printf "1\\n"
fi
}
install_one_local_tool() {
local plugin_name=$1
local search_path
search_path=$(pwd)
local plugin_versions
local plugin_version
local plugin_version_and_path
plugin_version_and_path="$(find_versions "$plugin_name" "$search_path")"
if [ -n "$plugin_version_and_path" ]; then
local plugin_version
some_tools_installed='yes'
plugin_versions=$(cut -d '|' -f 1 <<<"$plugin_version_and_path")
for plugin_version in $plugin_versions; do
install_tool_version "$plugin_name" "$plugin_version"
done
else
printf "No versions specified for %s in config files or environment\\n" "$plugin_name"
exit 1
fi
}
install_local_tool_versions() {
local plugins_path
plugins_path=$(get_plugin_path)
local search_path
search_path=$(pwd)
local some_tools_installed
local some_plugin_not_installed
local tool_versions_path
tool_versions_path=$(find_tool_versions)
# Locate all the plugins installed in the system
local plugins_installed
if find "$plugins_path" -mindepth 1 -type d &>/dev/null; then
for plugin_path in "$plugins_path"/*; do
local plugin_name
plugin_name=$(basename "$plugin_path")
plugins_installed="$plugins_installed $plugin_name"
done
plugins_installed=$(printf "%s" "$plugins_installed" | tr " " "\n")
fi
if [ -z "$plugins_installed" ]; then
printf "Install plugins first to be able to install tools\\n"
exit 1
fi
# Locate all the plugins defined in the versions file.
local tools_file
if [ -f "$tool_versions_path" ]; then
tools_file=$(strip_tool_version_comments "$tool_versions_path" | cut -d ' ' -f 1)
for plugin_name in $tools_file; do
if ! printf '%s\n' "${plugins_installed[@]}" | grep -q "^$plugin_name\$"; then
printf "%s plugin is not installed\n" "$plugin_name"
some_plugin_not_installed='yes'
fi
done
fi
if [ -n "$some_plugin_not_installed" ]; then
exit 1
fi
if [ -n "$plugins_installed" ]; then
for plugin_name in $plugins_installed; do
local plugin_version_and_path
plugin_version_and_path="$(find_versions "$plugin_name" "$search_path")"
if [ -n "$plugin_version_and_path" ]; then
local plugin_version
some_tools_installed='yes'
plugin_versions=$(cut -d '|' -f 1 <<<"$plugin_version_and_path")
for plugin_version in $plugin_versions; do
install_tool_version "$plugin_name" "$plugin_version"
done
fi
done
fi
if [ -z "$some_tools_installed" ]; then
printf "Either specify a tool & version in the command\\n"
printf "OR add .tool-versions file in this directory\\n"
printf "or in a parent directory\\n"
exit 1
fi
}
install_tool_version() {
local plugin_name=$1
local full_version=$2
local flags=$3
local keep_download
local plugin_path
plugin_path=$(get_plugin_path "$plugin_name")
check_if_plugin_exists "$plugin_name"
for flag in $flags; do
case "$flag" in
"--keep-download")
keep_download=true
shift
;;
*)
shift
;;
esac
done
if [ "$full_version" = "system" ]; then
return
fi
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"
if [ "${version_info[0]}" = "latest" ]; then
local version
version=$(latest_command "$plugin_name" "${version_info[1]}")
full_version=$version
else
local version="${version_info[0]}"
fi
fi
local install_path
install_path=$(get_install_path "$plugin_name" "$install_type" "$version")
local download_path
download_path=$(get_download_path "$plugin_name" "$install_type" "$version")
local concurrency
concurrency=$(get_concurrency)
trap 'handle_cancel $install_path' INT
if [ -d "$install_path" ]; then
printf "%s %s is already installed\\n" "$plugin_name" "$full_version"
else
if [ -f "${plugin_path}/bin/download" ]; then
# Not a legacy plugin
# Run the download script
(
# shellcheck disable=SC2030
export ASDF_INSTALL_TYPE=$install_type
# shellcheck disable=SC2030
export ASDF_INSTALL_VERSION=$version
# shellcheck disable=SC2030
export ASDF_INSTALL_PATH=$install_path
# shellcheck disable=SC2030
export ASDF_DOWNLOAD_PATH=$download_path
mkdir "$download_path"
asdf_run_hook "pre_asdf_download_${plugin_name}" "$full_version"
"${plugin_path}"/bin/download
)
fi
local download_exit_code=$?
if [ $download_exit_code -eq 0 ]; then
(
# shellcheck disable=SC2031
export ASDF_INSTALL_TYPE=$install_type
# shellcheck disable=SC2031
export ASDF_INSTALL_VERSION=$version
# shellcheck disable=SC2031
export ASDF_INSTALL_PATH=$install_path
# shellcheck disable=SC2031
export ASDF_DOWNLOAD_PATH=$download_path
# shellcheck disable=SC2031
export ASDF_CONCURRENCY=$concurrency
mkdir "$install_path"
asdf_run_hook "pre_asdf_install_${plugin_name}" "$full_version"
"${plugin_path}"/bin/install
)
fi
local install_exit_code=$?
if [ $install_exit_code -eq 0 ] && [ $download_exit_code -eq 0 ]; then
# Remove download directory if --keep-download flag or always_keep_download config setting are not set
always_keep_download=$(get_asdf_config_value "always_keep_download")
if [ ! "$keep_download" = "true" ] && [ ! "$always_keep_download" = "yes" ] && [ -d "$download_path" ]; then
rm -r "$download_path"
fi
reshim_command "$plugin_name" "$full_version"
asdf_run_hook "post_asdf_install_${plugin_name}" "$full_version"
else
handle_failure "$install_path"
fi
fi
}

167
lib/functions/plugins.bash Normal file
View File

@ -0,0 +1,167 @@
plugin_list_command() {
local plugins_path
plugins_path=$(get_plugin_path)
local show_repo
local show_ref
while [ -n "$*" ]; do
case "$1" in
"--urls")
show_repo=true
shift
;;
"--refs")
show_ref=true
shift
;;
*)
shift
;;
esac
done
if find "$plugins_path" -mindepth 1 -type d &>/dev/null; then
(
for plugin_path in "$plugins_path"/*; do
plugin_name=$(basename "$plugin_path")
printf "%s" "$plugin_name"
if [ -n "$show_repo" ]; then
printf "\\t%s" "$(git --git-dir "$plugin_path/.git" remote get-url origin 2>/dev/null)"
fi
if [ -n "$show_ref" ]; then
local branch
local gitref
branch=$(git --git-dir "$plugin_path/.git" rev-parse --abbrev-ref HEAD 2>/dev/null)
gitref=$(git --git-dir "$plugin_path/.git" rev-parse --short HEAD 2>/dev/null)
printf "\\t%s\\t%s" "$branch" "$gitref"
fi
printf "\\n"
done
) | awk '{ if (NF > 1) { printf("%-28s", $1) ; $1="" }; print $0}'
else
display_error 'No plugins installed'
exit 1
fi
}
plugin_add_command() {
if [[ $# -lt 1 || $# -gt 2 ]]; then
display_error "usage: asdf plugin add <name> [<git-url>]"
exit 1
fi
local plugin_name=$1
if ! printf "%s" "$plugin_name" | grep -q -E "^[a-zA-Z0-9_-]+$"; then
display_error "$plugin_name is invalid. Name must match regex ^[a-zA-Z0-9_-]+$"
exit 1
fi
if [ -n "$2" ]; then
local source_url=$2
else
initialize_or_update_repository
local source_url
source_url=$(get_plugin_source_url "$plugin_name")
fi
if [ -z "$source_url" ]; then
display_error "plugin $plugin_name not found in repository"
exit 1
fi
local plugin_path
plugin_path=$(get_plugin_path "$plugin_name")
mkdir -p "$(asdf_data_dir)/plugins"
if [ -d "$plugin_path" ]; then
display_error "Plugin named $plugin_name already added"
exit 2
else
asdf_run_hook "pre_asdf_plugin_add" "$plugin_name"
asdf_run_hook "pre_asdf_plugin_add_${plugin_name}"
if ! git clone -q "$source_url" "$plugin_path"; then
exit 1
fi
if [ -f "${plugin_path}/bin/post-plugin-add" ]; then
(
export ASDF_PLUGIN_SOURCE_URL=$source_url
export ASDF_PLUGIN_PATH=$plugin_path
"${plugin_path}/bin/post-plugin-add"
)
fi
asdf_run_hook "post_asdf_plugin_add" "$plugin_name"
asdf_run_hook "post_asdf_plugin_add_${plugin_name}"
fi
}
plugin_update_command() {
if [ "$#" -lt 1 ]; then
display_error "usage: asdf plugin-update {<name> [git-ref] | --all}"
exit 1
fi
local plugin_name="$1"
local gitref="${2}"
local plugins=
if [ "$plugin_name" = "--all" ]; then
if [ -d "$(asdf_data_dir)"/plugins ]; then
plugins=$(find "$(asdf_data_dir)"/plugins -mindepth 1 -maxdepth 1 -type d)
while IFS= read -r dir; do
update_plugin "$(basename "$dir")" "$dir" "$gitref" &
done <<<"$plugins"
wait
fi
else
local plugin_path
plugin_path="$(get_plugin_path "$plugin_name")"
check_if_plugin_exists "$plugin_name"
update_plugin "$plugin_name" "$plugin_path" "$gitref"
fi
}
update_plugin() {
local plugin_name=$1
local plugin_path=$2
plugin_remote_default_branch=$(git --git-dir "$plugin_path/.git" --work-tree "$plugin_path" ls-remote --symref origin HEAD | awk '{ sub(/refs\/heads\//, ""); print $2; exit }')
local gitref=${3:-${plugin_remote_default_branch}}
logfile=$(mktemp)
local common_git_options=(--git-dir "$plugin_path/.git" --work-tree "$plugin_path")
local prev_ref=
local post_ref=
{
asdf_run_hook "pre_asdf_plugin_update" "$plugin_name"
asdf_run_hook "pre_asdf_plugin_update_${plugin_name}"
printf "Updating %s to %s\\n" "$plugin_name" "$gitref"
git "${common_git_options[@]}" fetch --prune --update-head-ok origin "$gitref:$gitref"
prev_ref=$(git "${common_git_options[@]}" rev-parse --short HEAD)
post_ref=$(git "${common_git_options[@]}" rev-parse --short "${gitref}")
git "${common_git_options[@]}" -c advice.detachedHead=false checkout --force "$gitref"
if [ -f "${plugin_path}/bin/post-plugin-update" ]; then
(
export ASDF_PLUGIN_PATH=$plugin_path
export ASDF_PLUGIN_PREV_REF=$prev_ref
export ASDF_PLUGIN_POST_REF=$post_ref
"${plugin_path}/bin/post-plugin-update"
)
fi
asdf_run_hook "post_asdf_plugin_update" "$plugin_name"
asdf_run_hook "post_asdf_plugin_update_${plugin_name}"
} >"$logfile" 2>&1
cat "$logfile"
rm "$logfile"
}

222
lib/functions/versions.bash Normal file
View File

@ -0,0 +1,222 @@
version_command() {
local cmd=$1
local plugin_name=$2
if [ "$#" -lt "3" ]; then
if [ "$cmd" = "global" ]; then
printf "Usage: asdf global <name> <version>\\n"
else
printf "Usage: asdf local <name> <version>\\n"
fi
exit 1
fi
shift 2
local versions=("$@")
local file
if [ "$cmd" = "global" ]; then
file=${ASDF_DEFAULT_TOOL_VERSIONS_FILENAME:-$HOME/.tool-versions}
elif [ "$cmd" = "local-tree" ]; then
file=$(find_tool_versions)
else # cmd = local
file="$(pwd)/.tool-versions"
fi
if [ -L "$file" ]; then
# Resolve file path if symlink
file="$(resolve_symlink "$file")"
fi
check_if_plugin_exists "$plugin_name"
declare -a resolved_versions
local item
for item in "${!versions[@]}"; do
IFS=':' read -r -a version_info <<<"${versions[$item]}"
if [ "${version_info[0]}" = "latest" ] && [ -n "${version_info[1]}" ]; then
version=$(latest_command "$plugin_name" "${version_info[1]}")
elif [ "${version_info[0]}" = "latest" ] && [ -z "${version_info[1]}" ]; then
version=$(latest_command "$plugin_name")
else
# if branch handles ref: || path: || normal versions
version="${versions[$item]}"
fi
# check_if_version_exists should probably handle if either param is empty string
if [ -z "$version" ]; then
exit 1
fi
if ! (check_if_version_exists "$plugin_name" "$version"); then
version_not_installed_text "$plugin_name" "$version" 1>&2
exit 1
fi
resolved_versions+=("$version")
done
if [ -f "$file" ] && grep "^$plugin_name " "$file" >/dev/null; then
sed -i.bak -e "s|^$plugin_name .*$|$plugin_name ${resolved_versions[*]}|" "$file"
rm -f "$file".bak
else
printf "%s %s\\n" "$plugin_name" "${resolved_versions[*]}" >>"$file"
fi
}
list_all_command() {
local plugin_name=$1
local query=$2
local plugin_path
local std_out_file
local std_err_file
local output
plugin_path=$(get_plugin_path "$plugin_name")
check_if_plugin_exists "$plugin_name"
# Capture return code to allow error handling
std_out_file="$(mktemp "/tmp/asdf-command-list-all-${plugin_name}.stdout.XXXXXX")"
std_err_file="$(mktemp "/tmp/asdf-command-list-all-${plugin_name}.stderr.XXXXXX")"
return_code=0 && "${plugin_path}/bin/list-all" >"$std_out_file" 2>"$std_err_file" || return_code=$?
if [[ $return_code -ne 0 ]]; then
# Printing all output to allow plugin to handle error formatting
printf "Plugin %s's list-all callback script failed with output:\\n" "${plugin_name}" >&2
printf "%s\\n" "$(cat "$std_err_file")" >&2
printf "%s\\n" "$(cat "$std_out_file")" >&2
rm "$std_out_file" "$std_err_file"
exit 1
fi
if [[ $query ]]; then
output=$(tr ' ' '\n' <"$std_out_file" |
grep -E "^\\s*$query" |
tr '\n' ' ')
else
output=$(cat "$std_out_file")
fi
if [ -z "$output" ]; then
display_error "No compatible versions available ($plugin_name $query)"
exit 1
fi
IFS=' ' read -r -a versions_list <<<"$output"
for version in "${versions_list[@]}"; do
printf "%s\\n" "${version}"
done
# Remove temp files if they still exist
rm "$std_out_file" "$std_err_file" || true
}
latest_command() {
DEFAULT_QUERY="[0-9]"
local plugin_name=$1
local query=$2
local plugin_path
if [ "$plugin_name" == "--all" ]; then
latest_all
fi
[[ -z $query ]] && query="$DEFAULT_QUERY"
plugin_path=$(get_plugin_path "$plugin_name")
check_if_plugin_exists "$plugin_name"
local versions
if [ -f "${plugin_path}/bin/latest-stable" ]; then
versions=$("${plugin_path}"/bin/latest-stable "$query")
if [ -z "${versions}" ]; then
# this branch requires this print to mimic the error from the list-all branch
printf "No compatible versions available (%s %s)\\n" "$plugin_name" "$query" >&2
exit 1
fi
else
# pattern from xxenv-latest (https://github.com/momo-lab/xxenv-latest)
versions=$(list_all_command "$plugin_name" "$query" |
grep -ivE "(^Available versions:|-src|-dev|-latest|-stm|[-\\.]rc|-alpha|-beta|[-\\.]pre|-next|(a|b|c)[0-9]+|snapshot|master)" |
sed 's/^[[:space:]]\+//' |
tail -1)
if [ -z "${versions}" ]; then
exit 1
fi
fi
printf "%s\\n" "$versions"
}
latest_all() {
local plugins_path
plugins_path=$(get_plugin_path)
if find "$plugins_path" -mindepth 1 -type d &>/dev/null; then
for plugin_path in "$plugins_path"/*; do
plugin_name=$(basename "$plugin_path")
# Retrieve the version of the plugin
local version
if [ -f "${plugin_path}/bin/latest-stable" ]; then
# We can't filter by a concrete query because different plugins might
# have different queries.
version=$("${plugin_path}"/bin/latest-stable "")
if [ -z "${version}" ]; then
version="unknown"
fi
else
# pattern from xxenv-latest (https://github.com/momo-lab/xxenv-latest)
version=$(list_all_command "$plugin_name" |
grep -ivE "(^Available version:|-src|-dev|-latest|-stm|[-\\.]rc|-alpha|-beta|[-\\.]pre|-next|(a|b|c)[0-9]+|snapshot|master)" |
sed 's/^[[:space:]]\+//' |
tail -1)
if [ -z "${version}" ]; then
version="unknown"
fi
fi
local installed_status
installed_status="missing"
local installed_versions
installed_versions=$(list_installed_versions "$plugin_name")
if [ -n "$installed_versions" ] && printf '%s\n' "$installed_versions" | grep -q "^$version\$"; then
installed_status="installed"
fi
printf "%s\\t%s\\t%s\\n" "$plugin_name" "$version" "$installed_status"
done
else
printf "%s\\n" 'No plugins installed'
fi
exit 0
}
local_command() {
local parent=false
local positional=()
while [[ $# -gt 0 ]]; do
case $1 in
-p | --parent)
parent="true"
shift # past value
;;
*)
positional+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${positional[@]}" # restore positional parameters
if [ $parent = true ]; then
version_command local-tree "$@"
else
version_command local "$@"
fi
}