Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
ruby-build
ruby-build-source
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@ 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 pin to a specific ruby-build version/branch/tag with the `ASDF_RUBY_BUILD_VERSION` environment variable:

```
ASDF_RUBY_BUILD_VERSION=master asdf install ruby 2.6.4
ASDF_RUBY_BUILD_VERSION=v20240101 asdf install ruby 3.3.0
ASDF_RUBY_BUILD_VERSION=master asdf install ruby 3.3.0
```

Set `ASDF_RUBY_SKIP_RUBY_BUILD_UPDATE=1` to skip the network check and reuse whatever ruby-build refs are already cached locally.

## Default gems

asdf-ruby can automatically install a set of default gems right after
Expand Down Expand Up @@ -68,7 +70,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, 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.

Expand Down
115 changes: 79 additions & 36 deletions lib/utils.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#!/usr/bin/env bash

RUBY_BUILD_VERSION="${ASDF_RUBY_BUILD_VERSION:-v20260503}"
RUBY_BUILD_TAG="$RUBY_BUILD_VERSION"
RUBY_BUILD_REPOSITORY="https://github.com/rbenv/ruby-build.git"

echoerr() {
echo >&2 -e "\033[0;31m$1\033[0m"
Expand All @@ -17,54 +16,98 @@ ensure_ruby_build_setup() {
}

ensure_ruby_build_installed() {
local current_ruby_build_version

if [ ! -f "$(ruby_build_path)" ]; then
download_ruby_build
else
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
# shellcheck disable=SC2086
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 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
local source_dir target_ref
source_dir="$(ruby_build_source_dir)"

if ! ensure_ruby_build_source "$source_dir"; then
if [ -f "$(ruby_build_path)" ]; then
echoerr "Warning: Could not access ruby-build source; using existing installation."
return 0
fi
errorexit "Failed to clone ruby-build. Check your network connection."
fi

target_ref="$(resolve_ruby_build_ref "$source_dir")" ||
errorexit "Could not determine ruby-build version."

if needs_install "$target_ref"; then
install_ruby_build "$source_dir" "$target_ref"
fi
}

# Maintain a persistent clone of ruby-build. Cheap `git fetch` on each install
# keeps tag list current; set ASDF_RUBY_SKIP_RUBY_BUILD_UPDATE=1 to bypass.
ensure_ruby_build_source() {
local source_dir="$1"

if [ ! -d "$source_dir/.git" ]; then
echoerr "Cloning ruby-build..."
rm -rf "$source_dir"
git clone "$RUBY_BUILD_REPOSITORY" "$source_dir" >/dev/null 2>&1 || return 1
return 0
fi

if [ -n "${ASDF_RUBY_SKIP_RUBY_BUILD_UPDATE:-}" ]; then
return 0
fi

git -C "$source_dir" fetch --tags --prune origin >/dev/null 2>&1 ||
echoerr "Warning: Could not update ruby-build, using cached refs."
return 0
}

download_ruby_build() {
# Print to stderr so asdf doesn't assume this string is a list of versions
echoerr "Downloading ruby-build..."
# shellcheck disable=SC2155
local build_dir="$(ruby_build_source_dir)"
# Pick the ref to check out: explicit env var > latest release tag.
resolve_ruby_build_ref() {
local source_dir="$1"

# Remove directory in case it still exists from last download
rm -rf "$build_dir"
if [ -n "${ASDF_RUBY_BUILD_VERSION:-}" ]; then
echo "$ASDF_RUBY_BUILD_VERSION"
return 0
fi

# Clone down and checkout the correct ruby-build version
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
)
local latest
latest="$(git -C "$source_dir" tag --list 'v*' --sort=-v:refname | head -1)"
if [ -n "$latest" ]; then
echo "$latest"
return 0
fi
return 1
}

# Install in the ruby-build dir
PREFIX="$(ruby_build_dir)" "$build_dir/install.sh"
needs_install() {
local target_ref="$1" installed_version
[ ! -f "$(ruby_build_path)" ] && return 0

# Remove ruby-build source dir
rm -rf "$build_dir"
installed_version="$("$(ruby_build_path)" --version | cut -d ' ' -f2)"
if [ "${installed_version:0:1}" != "v" ]; then
installed_version="v$installed_version"
fi
[ "$installed_version" != "$target_ref" ]
}

install_ruby_build() {
local source_dir="$1" ref="$2"
echoerr "Installing ruby-build ${ref}..."

local checkout_ref="$ref"
if git -C "$source_dir" show-ref --verify --quiet "refs/remotes/origin/$ref"; then
checkout_ref="origin/$ref"
fi
git -C "$source_dir" checkout --detach "$checkout_ref" >/dev/null 2>&1 ||
errorexit "Failed to checkout ruby-build ref ${ref}."

rm -rf "$(ruby_build_dir)"
local install_dir
install_dir="$(cd "$(asdf_ruby_plugin_path)" && pwd)/ruby-build"
PREFIX="$install_dir" "$source_dir/install.sh" ||
errorexit "Failed to install ruby-build."
}

asdf_ruby_plugin_path() {
# shellcheck disable=SC2005
echo "$(dirname "$(dirname "$0")")"
}

ruby_build_dir() {
echo "$(asdf_ruby_plugin_path)/ruby-build"
}
Expand Down
Loading