diff --git a/lib/functions/versions.bash b/lib/functions/versions.bash index 4e27ce834..df50cbb1b 100644 --- a/lib/functions/versions.bash +++ b/lib/functions/versions.bash @@ -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 @@ -154,7 +154,7 @@ latest_command() { fi fi - printf "%s\\n" "$versions" + printf "%s\n" "$versions" } latest_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 + # 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' diff --git a/test/fixtures/dummy_distro_plugin/bin/download b/test/fixtures/dummy_distro_plugin/bin/download new file mode 100755 index 000000000..0fdcf0910 --- /dev/null +++ b/test/fixtures/dummy_distro_plugin/bin/download @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +exit 0 diff --git a/test/fixtures/dummy_distro_plugin/bin/install b/test/fixtures/dummy_distro_plugin/bin/install new file mode 100755 index 000000000..645f6ec6b --- /dev/null +++ b/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 <"$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 <"$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" diff --git a/test/fixtures/dummy_distro_plugin/bin/list-all b/test/fixtures/dummy_distro_plugin/bin/list-all new file mode 100755 index 000000000..c64c0efe8 --- /dev/null +++ b/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 diff --git a/test/latest_command.bats b/test/latest_command.bats index 8e01ce809..4c3fb18c9 100644 --- a/test/latest_command.bats +++ b/test/latest_command.bats @@ -6,6 +6,7 @@ setup() { setup_asdf_dir install_dummy_plugin install_dummy_legacy_plugin + install_dummy_distro_plugin } teardown() { @@ -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 ] } @@ -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 ] } @@ -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 ] } diff --git a/test/test_helpers.bash b/test/test_helpers.bash index 1704fce78..e565d4cb8 100644 --- a/test/test_helpers.bash +++ b/test/test_helpers.bash @@ -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}" @@ -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" }