Skip to content

Commit

Permalink
feat: Enable use of latest: in .tool-versions files
Browse files Browse the repository at this point in the history
This change enables `asdf`'s existing latest-version-resolution
functionality within the `.tool-versions` file itself, ie rather
than having to have a `.tool-versions` file that contains a full
version number:

```
java corretto-21.0.5.11.1
```

...you can now use the same `latest:` syntax that is already available
in the `local` & `global` commands, ie:

```
java latest:corretto-21
```

Currently, using `latew` `asdf local python latest:3.7`

### Implementation

A new `resolve_version_spec()` function has been extracted from the
existing `version_command()` function. This takes a version-spec string,
like `latest:corretto-11` or `corretto-21.0.5.11.1`, and resolves it to
a definite installed version number (if the resolved version is not
installed, the appropriate error message is shown).

This new `resolve_version_spec()` function is now called in
`select_version()`, used by the `with_shim_executable()` function,
meaning that any execution of the `asdf` shim (eg, executing `java`)
will now resolve any version specifications found in the `.tool-versions`
file - if `.tool-versions` contains `java latest:corretto-21`, this
will be resolved and the latest version of Java 21 used.

## Other Information

Previous PRs relating to `latest`:

* asdf-vm#575 in November 2019: added the `latest`
  command, eg `asdf latest python 3.6` reports the latest version of Python 3.6.
* asdf-vm#633 in July 2021: made it possible
  to specify `latest` when using the `local` & `global` commands, eg:
  `asdf local python latest:3.7` - this would save a precise version number
  to `.tools-versions`, which is undesired behaviour for us at the Guardian.
  • Loading branch information
rtyley committed Oct 17, 2024
1 parent c5116dc commit 1e618bb
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 22 deletions.
2 changes: 2 additions & 0 deletions bin/asdf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ fi

# shellcheck source=lib/utils.bash
. "$(dirname "$(dirname "$0")")/lib/utils.bash"
# shellcheck source=lib/functions/versions.bash
. "$(dirname "$(dirname "$0")")/lib/functions/versions.bash"

find_cmd() {
local cmd_dir="$1"
Expand Down
48 changes: 27 additions & 21 deletions lib/functions/versions.bash
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,7 @@ version_command() {
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")
resolved_versions+=("$(resolve_version_spec "${versions[$item]}")")
done

if [ -f "$file" ] && grep -q "^$plugin_name " "$file"; then
Expand All @@ -79,6 +59,32 @@ version_command() {
fi
}

resolve_version_spec() {
local version_spec=$1

IFS=':' read -r -a version_info <<<"$version_spec"
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

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

list_all_command() {
local plugin_name=$1
local query=$2
Expand Down
3 changes: 2 additions & 1 deletion lib/utils.bash
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,8 @@ select_version() {
version_and_path=$(find_versions "$plugin_name" "$search_path")
IFS='|' read -r version_string _path <<<"$version_and_path"
IFS=' ' read -r -a usable_plugin_versions <<<"$version_string"
for plugin_version in "${usable_plugin_versions[@]}"; do
for version_spec in "${usable_plugin_versions[@]}"; do
plugin_version="$(resolve_version_spec "$version_spec")"
for plugin_and_version in "${shim_versions[@]}"; do
local plugin_shim_name
local plugin_shim_version
Expand Down

0 comments on commit 1e618bb

Please sign in to comment.