From c27f94c6559c985fc4d333e63bf46420a05d3342 Mon Sep 17 00:00:00 2001 From: Philip Theus Date: Wed, 14 Jan 2026 20:06:15 +0100 Subject: [PATCH 1/2] Automatically fetch latest ruby-build version with 24h cache --- .gitignore | 2 + README.md | 20 ++++++---- lib/utils.sh | 104 +++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 107 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 8b254c4..38487e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ ruby-build +ruby-build-source +.ruby-build-version-cache diff --git a/README.md b/README.md index b730da7..d2bf636 100644 --- a/README.md +++ b/README.md @@ -27,14 +27,20 @@ RUBY_APPLY_PATCHES=$'dir/1.patch\n2.patch\nhttp://example.com/3.patch' asdf inst RUBY_APPLY_PATCHES=$(curl -s https://raw.githubusercontent.com/rvm/rvm/master/patchsets/ruby/2.1.1/railsexpress) asdf install ruby 2.1.1 ``` -> [!NOTE] -> This plugin does not automatically fetch new Ruby versions. Running `asdf plugin update ruby` will update asdf-ruby and ensure the latest versions of Ruby are available to install. If the desired ruby version is still not showing up see the below [Troubleshooting](https://github.com/asdf-vm/asdf-ruby?tab=readme-ov-file#troubleshooting) section. +By default asdf-ruby automatically fetches the latest release of ruby-build, so new Ruby versions are available as soon as ruby-build supports them. -By default asdf-ruby uses a recent release of ruby-build, however instead you can choose your own branch/tag through the `ASDF_RUBY_BUILD_VERSION` variable: +You can override this behavior with the following environment variables: -``` -ASDF_RUBY_BUILD_VERSION=master asdf install ruby 2.6.4 -``` +- `ASDF_RUBY_BUILD_VERSION` - Pin to a specific ruby-build version/branch/tag: + ``` + ASDF_RUBY_BUILD_VERSION=v20240101 asdf install ruby 3.3.0 + ASDF_RUBY_BUILD_VERSION=master asdf install ruby 3.3.0 + ``` + +- `ASDF_RUBY_BUILD_CACHE_CLEAR` - Bypass the 24-hour cache and fetch the latest version: + ``` + ASDF_RUBY_BUILD_CACHE_CLEAR=1 asdf list-all ruby + ``` ## Default gems @@ -68,7 +74,7 @@ note that you might have to change `.ruby-version` to include full version (e.g. ## Troubleshooting > [!NOTE] -> The most common issue reported for this plugin is a missing Ruby version. If you are not seeing a recent Ruby version in the list of available Ruby versions it's likely due to having an older version of this plugin. Run `asdf plugin update ruby` to get the most recent list of Ruby versions. If it is still not showing up then this plugin's `RUBY_BUILD_VERSION` in lib/utils.sh likely needs updated with the latest ruby-build release https://github.com/rbenv/ruby-build/releases. Please check for an existing PR before submitting a new one. If there is not one, please fork the repo and submit one. If this plugin's ruby-build needs updated, you can workaround it with `ASDF_RUBY_BUILD_VERSION`. A note in the above [Use](https://github.com/asdf-vm/asdf-ruby?tab=readme-ov-file#use) section describes how to do this. +> If you are not seeing a recent Ruby version, try bypassing the version cache with `ASDF_RUBY_BUILD_CACHE_CLEAR=1 asdf list-all ruby` to fetch the latest ruby-build version. If the version still doesn't appear, check ruby-build's releases at https://github.com/rbenv/ruby-build/releases to see if it's been added yet. If you are moving to asdf-ruby from another Ruby version manager, it is recommended to completely uninstall the old Ruby version manager before installing asdf-ruby. diff --git a/lib/utils.sh b/lib/utils.sh index ee143d1..e06300b 100644 --- a/lib/utils.sh +++ b/lib/utils.sh @@ -1,8 +1,5 @@ #!/usr/bin/env bash -RUBY_BUILD_VERSION="${ASDF_RUBY_BUILD_VERSION:-v20260114}" -RUBY_BUILD_TAG="$RUBY_BUILD_VERSION" - echoerr() { echo >&2 -e "\033[0;31m$1\033[0m" } @@ -17,11 +14,18 @@ ensure_ruby_build_setup() { } ensure_ruby_build_installed() { - local current_ruby_build_version + local current_ruby_build_version target_version + + target_version="$(get_ruby_build_version)" if [ ! -f "$(ruby_build_path)" ]; then - download_ruby_build - else + # No ruby-build installed - we must have a version to download + if [ -z "$target_version" ]; then + errorexit "Could not determine ruby-build version. Check your network connection." + fi + download_ruby_build "$target_version" + elif [ -n "$target_version" ]; then + # ruby-build exists and we have a target version - check if update needed current_ruby_build_version="$("$(ruby_build_path)" --version | cut -d ' ' -f2)" # If ruby-build version does not start with 'v', # add 'v' to beginning of version @@ -29,18 +33,20 @@ ensure_ruby_build_installed() { if [ ${current_ruby_build_version:0:1} != "v" ]; then current_ruby_build_version="v$current_ruby_build_version" fi - if [ "$current_ruby_build_version" != "$RUBY_BUILD_VERSION" ]; then + if [ "$current_ruby_build_version" != "$target_version" ]; then # If the ruby-build directory already exists and the version does not # match, remove it and download the correct version rm -rf "$(ruby_build_dir)" - download_ruby_build + download_ruby_build "$target_version" fi fi + # If ruby-build exists but we couldn't get a target version, just use what's installed } download_ruby_build() { + local version="$1" # Print to stderr so asdf doesn't assume this string is a list of versions - echoerr "Downloading ruby-build..." + echoerr "Downloading ruby-build ${version}..." # shellcheck disable=SC2155 local build_dir="$(ruby_build_source_dir)" @@ -51,11 +57,13 @@ download_ruby_build() { git clone https://github.com/rbenv/ruby-build.git "$build_dir" >/dev/null 2>&1 ( cd "$build_dir" || exit - git checkout "$RUBY_BUILD_TAG" >/dev/null 2>&1 + git checkout "$version" >/dev/null 2>&1 ) - # Install in the ruby-build dir - PREFIX="$(ruby_build_dir)" "$build_dir/install.sh" + # Install in the ruby-build dir (must use absolute path as install.sh changes directory) + local install_dir + install_dir="$(cd "$(asdf_ruby_plugin_path)" && pwd)/ruby-build" + PREFIX="$install_dir" "$build_dir/install.sh" # Remove ruby-build source dir rm -rf "$build_dir" @@ -76,3 +84,75 @@ ruby_build_source_dir() { ruby_build_path() { echo "$(ruby_build_dir)/bin/ruby-build" } + +ruby_build_version_cache_path() { + echo "$(asdf_ruby_plugin_path)/.ruby-build-version-cache" +} + +# Get file modification time in seconds since epoch (cross-platform) +get_file_mtime() { + local file="$1" + # Try GNU stat first (Linux), then BSD stat (macOS) + stat -c %Y "$file" 2>/dev/null || stat -f %m "$file" 2>/dev/null +} + +# Fetch the latest ruby-build version tag from GitHub +fetch_latest_ruby_build_version() { + git ls-remote --tags --sort=-version:refname https://github.com/rbenv/ruby-build.git 2>/dev/null | + grep -oE 'refs/tags/v[0-9]+$' | + head -1 | + sed 's|refs/tags/||' +} + +# Get the ruby-build version to use, with caching +# Priority: ASDF_RUBY_BUILD_VERSION env var > cached latest > fetched latest > installed version +get_ruby_build_version() { + # If user explicitly set a version, use that + if [ -n "${ASDF_RUBY_BUILD_VERSION:-}" ]; then + echo "$ASDF_RUBY_BUILD_VERSION" + return 0 + fi + + local cache_file + cache_file="$(ruby_build_version_cache_path)" + + # Check cache first (unless ASDF_RUBY_BUILD_CACHE_CLEAR is set) + if [ -z "${ASDF_RUBY_BUILD_CACHE_CLEAR:-}" ] && [ -f "$cache_file" ]; then + local cache_mtime current_time age + cache_mtime="$(get_file_mtime "$cache_file")" + current_time="$(date +%s)" + age=$((current_time - cache_mtime)) + + # Cache for 24 hours + if [ "$age" -lt 86400 ]; then + cat "$cache_file" + return 0 + fi + fi + + # Fetch latest version from GitHub + local latest_version + latest_version="$(fetch_latest_ruby_build_version)" + + if [ -n "$latest_version" ]; then + echo "$latest_version" >"$cache_file" + echo "$latest_version" + return 0 + fi + + # Fallback: if ruby-build is already installed, use its version + # (if we can't reach GitHub, we likely can't download a new version anyway) + if [ -f "$(ruby_build_path)" ]; then + local installed_version + installed_version="$("$(ruby_build_path)" --version | cut -d ' ' -f2)" + if [ "${installed_version:0:1}" != "v" ]; then + installed_version="v$installed_version" + fi + echoerr "Warning: Could not fetch latest ruby-build version, using installed version ${installed_version}" + echo "$installed_version" + return 0 + fi + + # No version available + return 1 +} From fb77da081d824786c85c3c70f2fa04b81ac6fbaa Mon Sep 17 00:00:00 2001 From: Philip Theus Date: Wed, 14 Jan 2026 20:50:33 +0100 Subject: [PATCH 2/2] Remove version cache --- .gitignore | 1 - README.md | 18 ++++++------------ lib/utils.sh | 33 ++------------------------------- 3 files changed, 8 insertions(+), 44 deletions(-) diff --git a/.gitignore b/.gitignore index 38487e9..a02b3bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ ruby-build ruby-build-source -.ruby-build-version-cache diff --git a/README.md b/README.md index d2bf636..61b7fed 100644 --- a/README.md +++ b/README.md @@ -29,18 +29,12 @@ RUBY_APPLY_PATCHES=$(curl -s https://raw.githubusercontent.com/rvm/rvm/master/pa By default asdf-ruby automatically fetches the latest release of ruby-build, so new Ruby versions are available as soon as ruby-build supports them. -You can override this behavior with the following environment variables: +You can pin to a specific ruby-build version/branch/tag with the `ASDF_RUBY_BUILD_VERSION` environment variable: -- `ASDF_RUBY_BUILD_VERSION` - Pin to a specific ruby-build version/branch/tag: - ``` - ASDF_RUBY_BUILD_VERSION=v20240101 asdf install ruby 3.3.0 - ASDF_RUBY_BUILD_VERSION=master asdf install ruby 3.3.0 - ``` - -- `ASDF_RUBY_BUILD_CACHE_CLEAR` - Bypass the 24-hour cache and fetch the latest version: - ``` - ASDF_RUBY_BUILD_CACHE_CLEAR=1 asdf list-all ruby - ``` +``` +ASDF_RUBY_BUILD_VERSION=v20240101 asdf install ruby 3.3.0 +ASDF_RUBY_BUILD_VERSION=master asdf install ruby 3.3.0 +``` ## Default gems @@ -74,7 +68,7 @@ note that you might have to change `.ruby-version` to include full version (e.g. ## Troubleshooting > [!NOTE] -> If you are not seeing a recent Ruby version, try bypassing the version cache with `ASDF_RUBY_BUILD_CACHE_CLEAR=1 asdf list-all ruby` to fetch the latest ruby-build version. If the version still doesn't appear, check ruby-build's releases at https://github.com/rbenv/ruby-build/releases to see if it's been added yet. +> If you are not seeing a recent Ruby version, check ruby-build's releases at https://github.com/rbenv/ruby-build/releases to see if it's been added yet. If you are moving to asdf-ruby from another Ruby version manager, it is recommended to completely uninstall the old Ruby version manager before installing asdf-ruby. diff --git a/lib/utils.sh b/lib/utils.sh index e06300b..08cb741 100644 --- a/lib/utils.sh +++ b/lib/utils.sh @@ -85,17 +85,6 @@ ruby_build_path() { echo "$(ruby_build_dir)/bin/ruby-build" } -ruby_build_version_cache_path() { - echo "$(asdf_ruby_plugin_path)/.ruby-build-version-cache" -} - -# Get file modification time in seconds since epoch (cross-platform) -get_file_mtime() { - local file="$1" - # Try GNU stat first (Linux), then BSD stat (macOS) - stat -c %Y "$file" 2>/dev/null || stat -f %m "$file" 2>/dev/null -} - # Fetch the latest ruby-build version tag from GitHub fetch_latest_ruby_build_version() { git ls-remote --tags --sort=-version:refname https://github.com/rbenv/ruby-build.git 2>/dev/null | @@ -104,8 +93,8 @@ fetch_latest_ruby_build_version() { sed 's|refs/tags/||' } -# Get the ruby-build version to use, with caching -# Priority: ASDF_RUBY_BUILD_VERSION env var > cached latest > fetched latest > installed version +# Get the ruby-build version to use +# Priority: ASDF_RUBY_BUILD_VERSION env var > fetched latest > installed version get_ruby_build_version() { # If user explicitly set a version, use that if [ -n "${ASDF_RUBY_BUILD_VERSION:-}" ]; then @@ -113,29 +102,11 @@ get_ruby_build_version() { return 0 fi - local cache_file - cache_file="$(ruby_build_version_cache_path)" - - # Check cache first (unless ASDF_RUBY_BUILD_CACHE_CLEAR is set) - if [ -z "${ASDF_RUBY_BUILD_CACHE_CLEAR:-}" ] && [ -f "$cache_file" ]; then - local cache_mtime current_time age - cache_mtime="$(get_file_mtime "$cache_file")" - current_time="$(date +%s)" - age=$((current_time - cache_mtime)) - - # Cache for 24 hours - if [ "$age" -lt 86400 ]; then - cat "$cache_file" - return 0 - fi - fi - # Fetch latest version from GitHub local latest_version latest_version="$(fetch_latest_ruby_build_version)" if [ -n "$latest_version" ]; then - echo "$latest_version" >"$cache_file" echo "$latest_version" return 0 fi