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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ $ ruby-build --list # lists latest stable releases for ea
$ ruby-build --definitions # lists all definitions, including outdated ones
$ ruby-build 3.2.2 ~/.rubies/ruby-3.2.2 # installs Ruby 3.2.2
$ ruby-build -d ruby-3.2.2 ~/.rubies # alternate form for the previous example
$ ruby-build -d 3.2 ~/.rubies/ # installs latest "ruby-3.2" (3.2.10)

# As an rbenv plugin
$ rbenv install 3.2.2 # installs Ruby 3.2.2 to ~/.rbenv/versions/3.2.2
Expand Down
6 changes: 6 additions & 0 deletions bin/rbenv-install
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ DEFINITION="${ARGUMENTS[0]}"
[ -n "$DEFINITION" ] || DEFINITION="$(rbenv-local 2>/dev/null || true)"
[ -n "$DEFINITION" ] || usage 1 >&2

[ -n "$DEFINITION" ] && RESOLVED_DEFINITION="$(ruby-build --resolve "${DEFINITION}" 2>/dev/null || true)"

if [ -n "$RESOLVED_DEFINITION" ]; then
DEFINITION="$RESOLVED_DEFINITION"
fi

# Define `before_install` and `after_install` functions that allow
# plugin hooks to register a string of code for execution before or
# after the installation process.
Expand Down
73 changes: 60 additions & 13 deletions bin/ruby-build
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
#
# Usage: ruby-build [-dvpk] <definition> <prefix> [-- <configure-args...>]
# ruby-build {--list|--definitions}
# ruby-build {--resolve} <version>
# ruby-build --version
#
# -l, --list List latest stable releases for each Ruby
# --resolve Find the most recent version matching a prefix.
# --definitions List all local definitions, including outdated ones
# --version Show version of ruby-build
#
Expand Down Expand Up @@ -1401,6 +1403,29 @@ list_maintained_versions() {
} | extract_latest_versions | sort_versions | uniq
}

filter_version_prefix()
{
pattern="${1//./\.}"
pattern="${pattern//+/\+}"
grep -e "^${pattern}[-.$]"
}

resolve() {
prefix="${1%.}"
prefix="${prefix#ruby-}"

version=$(list_definitions | \
grep -v -e '-rc[0-9]*$' -e '-preview[0-9]*$' -e '-dev$' | \
filter_version_prefix "${prefix}" | \
LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n -k 5,5n | \
tail -n 1)

[[ -z "${version}" ]] && return 1
[[ "${1}" = "ruby-"* ]] && version="ruby-${version}"

echo "${version}"
}

extract_latest_versions() {
# sort in this function looks redundunt but it is necessary
# rbx-3.99 appears latest unless the sort
Expand Down Expand Up @@ -1443,6 +1468,9 @@ for option in "${OPTIONS[@]}"; do
"l" | "list")
EARLY_EXIT=list_maintained_versions
;;
"resolve")
EARLY_EXIT=resolve
;;
"d" | "dir")
APPEND_DEFINITION_TO_PREFIX=true
;;
Expand Down Expand Up @@ -1493,22 +1521,15 @@ if [ "${#EXTRA_ARGUMENTS[@]}" -gt 0 ]; then
RUBY_CONFIGURE_OPTS_ARRAY=("${EXTRA_ARGUMENTS[@]}")
fi

if [ "$APPEND_DEFINITION_TO_PREFIX" = "true" ]; then
if [ -p "$DEFINITION_PATH" ]; then
echo "ruby-build: using named pipes in combination with \`--dir' is not possible" >&2
EARLY_EXIT=usage_error
fi
PREFIX_PATH="$PREFIX_PATH/$(basename "$DEFINITION_PATH")"
fi

case "$EARLY_EXIT" in
help )
version
echo
usage 0
;;
version | list_definitions | list_maintained_versions )
"$EARLY_EXIT"
version | list_definitions | list_maintained_versions | resolve )
shift
"$EARLY_EXIT" "$@"
exit 0
;;
usage_error )
Expand All @@ -1523,6 +1544,8 @@ usage_error )
;;
esac

DEFINITION_PREFIX=""

# expand the <definition> argument to full path of the definition file
if [[ ! -f "$DEFINITION_PATH" && ! -p "$DEFINITION_PATH" ]]; then
for DEFINITION_DIR in "${RUBY_BUILD_DEFINITIONS[@]}"; do
Expand All @@ -1534,10 +1557,26 @@ if [[ ! -f "$DEFINITION_PATH" && ! -p "$DEFINITION_PATH" ]]; then

# If the given definition is like ruby-X.Y.Z, search again with X.Y.Z
if [[ "$DEFINITION_PATH" =~ ^ruby-[0-9] ]]; then
DEFINITION_PATH="${DEFINITION_PATH#ruby-}"
UNPREFIXED_DEFINITION_PATH="${DEFINITION_PATH#ruby-}"
for DEFINITION_DIR in "${RUBY_BUILD_DEFINITIONS[@]}"; do
if [ -f "${DEFINITION_DIR}/${DEFINITION_PATH}" ]; then
DEFINITION_PATH="${DEFINITION_DIR}/${DEFINITION_PATH}"
if [ -f "${DEFINITION_DIR}/${UNPREFIXED_DEFINITION_PATH}" ]; then
DEFINITION_PREFIX="ruby-"
DEFINITION_PATH="${DEFINITION_DIR}/${UNPREFIXED_DEFINITION_PATH}"
break
fi
done
fi

# If the given definition isn't a perfect match, we do a prefix search.
if [ ! -f "$DEFINITION_PATH" ]; then
Comment thread
eregon marked this conversation as resolved.
FULLY_QUALIFIED_VERSION=$(resolve "$DEFINITION_PATH")
for DEFINITION_DIR in "${RUBY_BUILD_DEFINITIONS[@]}"; do
if [ -f "${DEFINITION_DIR}/${FULLY_QUALIFIED_VERSION}" ]; then
if [[ "$DEFINITION_PATH" =~ ^ruby-[0-9] ]]; then
DEFINITION_PREFIX="ruby-"
fi

DEFINITION_PATH="${DEFINITION_DIR}/${FULLY_QUALIFIED_VERSION}"
break
fi
done
Expand All @@ -1549,6 +1588,14 @@ if [[ ! -f "$DEFINITION_PATH" && ! -p "$DEFINITION_PATH" ]]; then
fi
fi

if [ "$APPEND_DEFINITION_TO_PREFIX" = "true" ]; then
if [ -p "$DEFINITION_PATH" ]; then
echo "ruby-build: using named pipes in combination with \`--dir' is not possible" >&2
EARLY_EXIT=usage_error
fi
PREFIX_PATH="$PREFIX_PATH/${DEFINITION_PREFIX}$(basename "$DEFINITION_PATH")"
fi

# normalize the <prefix> argument
if [ "${PREFIX_PATH#/}" = "$PREFIX_PATH" ]; then
PREFIX_PATH="${PWD}/${PREFIX_PATH}"
Expand Down
70 changes: 70 additions & 0 deletions test/definitions.bats
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,76 @@ NUM_DEFINITIONS="$(ls "$BATS_TEST_DIRNAME"/../share/ruby-build | wc -l)"
assert_success ""
}

@test "installing definition by prefix" {
export RUBY_BUILD_DEFINITIONS="${TMP}/definitions"
mkdir -p "${TMP}/definitions"

echo false > "${TMP}/definitions/1.8.6"
echo false > "${TMP}/definitions/1.9.3"
echo true > "${TMP}/definitions/1.9.10"
echo false > "${TMP}/definitions/1.90.0"
echo false > "${TMP}/definitions/2.0.0"

run bin/ruby-build "1.9" "${TMP}/install"
assert_success ""
}

@test "resolve definition by version prefix" {
export RUBY_BUILD_DEFINITIONS="${TMP}/definitions"
mkdir -p "${TMP}/definitions"

touch "${TMP}/definitions/1.8.6"
touch "${TMP}/definitions/1.9.3"
touch "${TMP}/definitions/1.9.10"
touch "${TMP}/definitions/1.90.0"
touch "${TMP}/definitions/2.0.0"

run bin/ruby-build --resolve "1.9" "${TMP}/install"
assert_success "1.9.10"
}

@test "resolve definition with ruby prefix" {
export RUBY_BUILD_DEFINITIONS="${TMP}/definitions"
mkdir -p "${TMP}/definitions"

touch "${TMP}/definitions/1.8.6"
touch "${TMP}/definitions/1.9.3"
touch "${TMP}/definitions/1.9.10"
touch "${TMP}/definitions/1.90.0"
touch "${TMP}/definitions/2.0.0"

run bin/ruby-build --resolve "ruby-1.9" "${TMP}/install"
assert_success "ruby-1.9.10"
}

@test "resolve definition by implementation name" {
export RUBY_BUILD_DEFINITIONS="${TMP}/definitions"
mkdir -p "${TMP}/definitions"

touch "${TMP}/definitions/foo-1.8.6"
touch "${TMP}/definitions/foo-1.9.3"
touch "${TMP}/definitions/1.9.10"
touch "${TMP}/definitions/1.90.0"
touch "${TMP}/definitions/2.0.0"

run bin/ruby-build --resolve "foo" "${TMP}/install"
assert_success "foo-1.9.3"
}

@test "resolve definition by implementation name and version" {
export RUBY_BUILD_DEFINITIONS="${TMP}/definitions"
mkdir -p "${TMP}/definitions"

touch "${TMP}/definitions/foo-1.8.6"
touch "${TMP}/definitions/foo-1.9.3"
touch "${TMP}/definitions/1.9.10"
touch "${TMP}/definitions/1.90.0"
touch "${TMP}/definitions/2.0.0"

run bin/ruby-build --resolve "foo-1.8" "${TMP}/install"
assert_success "foo-1.8.6"
}

@test "installing nonexistent definition" {
run ruby-build "nonexistent" "${TMP}/install"
assert [ "$status" -eq 2 ]
Expand Down
Empty file modified test/installer.bats
100644 → 100755
Empty file.
22 changes: 13 additions & 9 deletions test/rbenv.bats
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ stub_ruby_build() {
}

@test "install proper" {
stub_ruby_build 'echo ruby-build "$@"'
stub_ruby_build 'echo 2.1.2' 'echo ruby-build "$@"'

run rbenv-install 2.1.2
assert_success "ruby-build 2.1.2 ${RBENV_ROOT}/versions/2.1.2"
Expand All @@ -27,7 +27,7 @@ stub_ruby_build() {
}

@test "install with flags" {
stub_ruby_build 'echo "ruby-build $(inspect_args "$@")"'
stub_ruby_build 'echo 2.1.2' 'echo "ruby-build $(inspect_args "$@")"'

run rbenv-install -kpv 2.1.2 -- --with-configure-opt="hello world"
assert_success "ruby-build --keep --verbose --patch 2.1.2 ${RBENV_ROOT}/versions/2.1.2 -- \"--with-configure-opt=hello world\""
Expand All @@ -39,7 +39,7 @@ stub_ruby_build() {

@test "suggest running rbenv global after install" {
rm -rf "$RBENV_ROOT/version"
stub_ruby_build 'echo ruby-build "$@"'
stub_ruby_build 'echo 2.1.2' 'echo ruby-build "$@"'

run rbenv-install 2.1.2
assert_success <<OUT
Expand All @@ -52,7 +52,7 @@ OUT
}

@test "install rbenv local version by default" {
stub_ruby_build 'echo ruby-build "$1"'
stub_ruby_build 'echo 2.1.2' 'echo ruby-build "$1"'
stub rbenv-local 'echo 2.1.2'

run rbenv-install
Expand Down Expand Up @@ -100,7 +100,8 @@ OUT
fi

stub_repeated brew false
stub_ruby_build 'echo ERROR >&2 && exit 2' \
stub_ruby_build 'exit 1' \
'echo ERROR >&2 && exit 2' \
"--definitions : echo 1.8.7 1.9.3-p0 1.9.3-p194 2.1.2 | tr ' ' $'\\n'"

run rbenv-install 1.9.3
Expand All @@ -127,10 +128,11 @@ OUT

@test "Homebrew upgrade instructions" {
stub brew "--prefix : echo '${BATS_TEST_DIRNAME%/*}'"
stub_ruby_build 'echo ERROR >&2 && exit 2' \
stub_ruby_build 'exit 1' \
'echo ERROR >&2 && exit 2' \
"--definitions : true"

run rbenv-install 1.9.3
run rbenv-install 1.9.10
assert_failure
assert_output <<OUT
ERROR
Expand All @@ -148,7 +150,8 @@ OUT

@test "no build definitions from plugins" {
refute [ -e "${RBENV_ROOT}/plugins" ]
stub_ruby_build 'echo $RUBY_BUILD_DEFINITIONS'
stub_ruby_build 'echo 2.1.2' \
'echo $RUBY_BUILD_DEFINITIONS'

run rbenv-install 2.1.2
assert_success ""
Expand All @@ -157,7 +160,8 @@ OUT
@test "some build definitions from plugins" {
mkdir -p "${RBENV_ROOT}/plugins/foo/share/ruby-build"
mkdir -p "${RBENV_ROOT}/plugins/bar/share/ruby-build"
stub_ruby_build "echo \$RUBY_BUILD_DEFINITIONS | tr ':' $'\\n'"
stub_ruby_build 'echo 2.1.2' \
"echo \$RUBY_BUILD_DEFINITIONS | tr ':' $'\\n'"

run rbenv-install 2.1.2
assert_success
Expand Down