Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: asdf latest --all report wrong runtimes (#1180) #1191

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
67 changes: 52 additions & 15 deletions lib/functions/versions.bash
Expand Up @@ -140,7 +140,7 @@ latest_command() {
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
printf "No compatible versions available (%s %s)\n" "$plugin_name" "$query" >&2
exit 1
fi
else
Expand All @@ -154,7 +154,7 @@ latest_command() {
fi
fi

printf "%s\\n" "$versions"
printf "%s\n" "$versions"
}

latest_all() {
Expand All @@ -165,36 +165,73 @@ latest_all() {
for plugin_path in "$plugins_path"/*/; do
plugin_name=$(basename "$plugin_path")

local all_versions
all_versions=$(list_all_command "$plugin_name")

local installed_versions
installed_versions=$(list_installed_versions "$plugin_name")

# Get a distinct list of distributions/variants
local installed_variants
installed_variants=$(printf "$installed_versions" |
sed -e "s/\(^.*\)\-[0-9].*/\1/" | # extract variant prefix
sort -u | # unique
sed -e "s/^[[:space:]]*[0-9].*//" | # remove versions without variant prefix
sed '/^[[:space:]]*$/d') # remove empty lines
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm uncomfortable with this being part of asdf. I know we have similar logic that already exists in a few places, but this doesn't feel like a future-proof solution. We're effectively using versions to store more than the version number. Versions are a combination of tool type (e.g. openjdk) and version (e.g. 1.2.3). I know this is a pretty fundamental change, but I think we might be better off either introducing a type field in addition to version, or specifying that plugins only support one type of thing (e.g. instead of a java plugin we have an openjdk plugin). Thoughts?

Copy link
Contributor

@jthegedus jthegedus Jul 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

specifying that plugins only support one type of thing

interesting proposal. I know this would also upset the Hashicorp plugin which manages the binaries for the Hashi ecosystem and not just different sources of the same runtime. I feel like Java and Hashicorp plugins are different enough and both valid in the spec we have defined 🤔


# Retrieve the version of the plugin
local version
local versions=()
if [ -f "${plugin_path}/bin/latest-stable" ]; then
# We can't filter by a concrete query because different plugins might
# have different queries.
local version
version=$("${plugin_path}"/bin/latest-stable "")

if [ -z "${version}" ]; then
version="unknown"
versions+=("unknown")
else
versions+=("$version")
fi
else
# pattern from xxenv-latest (https://github.com/momo-lab/xxenv-latest)
version=$(list_all_command "$plugin_name" |
local version
version=$(printf "$all_versions" |
grep -ivE "(^Available version:|-src|-dev|-latest|-stm|[-\\.]rc|-alpha|-beta|[-\\.]pre|-next|(a|b|c)[0-9]+|snapshot|master)" |
grep -iE "^\d+.*\$" | # filter out variants
sed 's/^[[:space:]]\+//' |
tail -1)
if [ -z "${version}" ]; then
version="unknown"

if [ -n "${version}" ]; then
versions+=("$version")
fi

# get latest version for each variant
for variant in $installed_variants; do
query=$(printf "$variant" | tr -d '[:space:]')
version=$(printf "$all_versions" | grep -E "^\\s*$query" |
grep -iE "^($variant|$variant(-\d+.*)?)\$" | # filter for exact match or with version suffix to deal with overlaps (e.g. zulu-18.28.13, zulu-jre-18.28.13)
sed 's/^[[:space:]]\+//' |
tail -1)

if [ -z "$version" ]; then
versions+=("$variant") # fallback to the variant name
else
versions+=("$version")
fi
done

fi

local installed_status
installed_status="missing"
for version in "${versions[@]}"; do
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

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'
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/dummy_distro_plugin/bin/download
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

exit 0
27 changes: 27 additions & 0 deletions test/fixtures/dummy_distro_plugin/bin/install
@@ -0,0 +1,27 @@
#!/usr/bin/env bash

# We want certain versions to fail installation for various reasons in the tests
check_dummy_versions() {
local bad_versions=" other-dummy "
if [[ "$bad_versions" == *" $ASDF_INSTALL_VERSION "* ]]; then
echo "Dummy couldn't install version: $ASDF_INSTALL_VERSION (on purpose)"
exit 1
fi
}

check_dummy_versions
mkdir -p "$ASDF_INSTALL_PATH"
env >"$ASDF_INSTALL_PATH/env"
echo "$ASDF_INSTALL_VERSION" >"$ASDF_INSTALL_PATH/version"

# create the dummy executable
mkdir -p "$ASDF_INSTALL_PATH/bin"
cat <<EOF >"$ASDF_INSTALL_PATH/bin/dummy"
echo This is Dummy ${ASDF_INSTALL_VERSION}! \$2 \$1
EOF
chmod +x "$ASDF_INSTALL_PATH/bin/dummy"
mkdir -p "$ASDF_INSTALL_PATH/bin/subdir"
cat <<EOF >"$ASDF_INSTALL_PATH/bin/subdir/other_bin"
echo This is Other Bin ${ASDF_INSTALL_VERSION}! \$2 \$1
EOF
chmod +x "$ASDF_INSTALL_PATH/bin/subdir/other_bin"
6 changes: 6 additions & 0 deletions test/fixtures/dummy_distro_plugin/bin/list-all
@@ -0,0 +1,6 @@
#!/usr/bin/env bash

versions_list=(1.0 2.0 dist-1.0.0 dist-1.1.0 other-dist-1.0 other-dist-2.0-src rc1 rc1-beta)
echo "${versions_list[@]}"
# Sending message to STD error to ensure that it is ignored
echo "ignore this error" >&2
49 changes: 46 additions & 3 deletions test/latest_command.bats
Expand Up @@ -6,6 +6,7 @@ setup() {
setup_asdf_dir
install_dummy_plugin
install_dummy_legacy_plugin
install_dummy_distro_plugin
}

teardown() {
Expand All @@ -17,18 +18,30 @@ teardown() {
####################################################
@test "[latest_command - dummy_plugin] shows latest stable version" {
run asdf latest dummy

echo "status: $status"
echo "output: $output"

[ "$(echo "2.0.0")" == "$output" ]
[ "$status" -eq 0 ]
}

@test "[latest_command - dummy_plugin] shows latest stable version that matches the given string" {
run asdf latest dummy 1

echo "status: $status"
echo "output: $output"

[ "$(echo "1.1.0")" == "$output" ]
[ "$status" -eq 0 ]
}

@test "[latest_command - dummy_plugin] an invalid version should return an error" {
run asdf latest dummy 3

echo "status: $status"
echo "output: $output"

[ "$(echo "No compatible versions available (dummy 3)")" == "$output" ]
[ "$status" -eq 1 ]
}
Expand All @@ -38,48 +51,60 @@ teardown() {
####################################################
@test "[latest_command - dummy_legacy_plugin] shows latest stable version" {
run asdf latest legacy-dummy

echo "status: $status"
echo "output: $output"

[ "$(echo "5.1.0")" == "$output" ]
[ "$status" -eq 0 ]
}

@test "[latest_command - dummy_legacy_plugin] shows latest stable version that matches the given string" {
run asdf latest legacy-dummy 1

echo "status: $status"
echo "output: $output"

[ "$(echo "1.1.0")" == "$output" ]
[ "$status" -eq 0 ]
}

@test "[latest_command - dummy_legacy_plugin] No stable version should return an error" {
run asdf latest legacy-dummy 3

echo "status: $status"
echo "output: $output"

[ -z "$output" ]
[ "$status" -eq 1 ]
}

@test "[latest_command - dummy_legacy_plugin] do not show latest unstable version that matches the given string" {
run asdf latest legacy-dummy 4

echo "status: $status"
echo "output: $output"

[ "$(echo "4.0.0")" == "$output" ]
[ "$status" -eq 0 ]
}

@test "[latest_command - dummy_legacy_plugin] do not show latest unstable version with capital characters that matches the given string" {
run asdf latest legacy-dummy 5

echo "status: $status"
echo "output: $output"

[ "$(echo "5.1.0")" == "$output" ]
[ "$status" -eq 0 ]
}

@test "[latest_command - dummy_legacy_plugin] an invalid version should return an error" {
run asdf latest legacy-dummy 6

echo "status: $status"
echo "output: $output"

[ "$(echo "No compatible versions available (legacy-dummy 6)")" == "$output" ]
[ "$status" -eq 1 ]
}
Expand All @@ -90,14 +115,32 @@ teardown() {
@test "[latest_command - all plugins] shows the latest stable version of all plugins" {
run asdf install dummy 2.0.0
run asdf install legacy-dummy 4.0.0
run asdf install distro-dummy 1.0
run asdf install distro-dummy dist-1.0.0
run asdf install distro-dummy other-dist-1.0
run asdf install distro-dummy rc1
run asdf latest --all
echo "output $output"
[ "$(echo -e "dummy\t2.0.0\tinstalled\nlegacy-dummy\t5.1.0\tmissing\n")" == "$output" ]

echo "status: $status"
echo "output: $output"

[ "$(printf "%s\\t%s\\t%s\\n" "distro-dummy" "2.0" "missing"
printf "%s\\t%s\\t%s\\n" "distro-dummy" "dist-1.1.0" "missing"
printf "%s\\t%s\\t%s\\n" "distro-dummy" "other-dist-2.0-src" "missing"
printf "%s\\t%s\\t%s\\n" "distro-dummy" "rc1" "installed"
printf "%s\\t%s\\t%s\\n" "dummy" "2.0.0" "installed"
printf "%s\\t%s\\t%s\\n" "legacy-dummy" "5.1.0" "missing")" == "$output" ]
[ "$status" -eq 0 ]
}

@test "[latest_command - all plugins] not installed plugin should return missing" {
run asdf latest --all
[ "$(echo -e "dummy\t2.0.0\tmissing\nlegacy-dummy\t5.1.0\tmissing\n")" == "$output" ]

echo "status: $status"
echo "output: $output"

[ "$(printf "%s\\t%s\\t%s\\n" "distro-dummy" "2.0" "missing"
printf "%s\\t%s\\t%s\\n" "dummy" "2.0.0" "missing"
printf "%s\\t%s\\t%s\\n" "legacy-dummy" "5.1.0" "missing")" == "$output" ]
[ "$status" -eq 0 ]
}
9 changes: 9 additions & 0 deletions test/test_helpers.bash
Expand Up @@ -37,6 +37,12 @@ install_mock_legacy_plugin() {
cp -r "$BATS_TEST_DIRNAME/fixtures/dummy_legacy_plugin" "$location/plugins/$plugin_name"
}

install_mock_distro_plugin() {
local plugin_name=$1
local location="${2:-$ASDF_DIR}"
cp -r "$BATS_TEST_DIRNAME/fixtures/dummy_distro_plugin" "$location/plugins/$plugin_name"
}

install_mock_broken_plugin() {
local plugin_name=$1
local location="${2:-$ASDF_DIR}"
Expand Down Expand Up @@ -69,6 +75,9 @@ install_dummy_legacy_plugin() {
install_mock_legacy_plugin "legacy-dummy"
}

install_dummy_distro_plugin() {
install_mock_distro_plugin "distro-dummy"
}
install_dummy_broken_plugin() {
install_mock_broken_plugin "dummy-broken"
}
Expand Down