Skip to content

Commit 6648263

Browse files
committed
Support building with version prefix
Commonly in CI pipelines and other scripts, users may want to install the latest from a specific series, e.g. `3.4` or `jruby-10.0`. ```bash $ bin/ruby-build 3.4 /tmp/3.4 ... Downloading ruby-3.4.9.tar.gz... $ bin/ruby-build 4.0 /tmp/4.0 ... Downloading ruby-4.0.2.tar.gz... ``` Also support `--resolve`: ```bash $ bin/ruby-build --resolve 3.4 3.4.9 ```
1 parent d8e1570 commit 6648263

4 files changed

Lines changed: 52 additions & 61 deletions

File tree

bin/rbenv-install

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,12 @@ DEFINITION="${ARGUMENTS[0]}"
144144
[ -n "$DEFINITION" ] || DEFINITION="$(rbenv-local 2>/dev/null || true)"
145145
[ -n "$DEFINITION" ] || usage 1 >&2
146146

147+
[ -n "$DEFINITION" ] && RESOLVED_DEFINITION="$(ruby-build --resolve "${DEFINITION}" 2>/dev/null || true)"
148+
149+
if [ -n "$RESOLVED_DEFINITION" ]; then
150+
DEFINITION="$RESOLVED_DEFINITION"
151+
fi
152+
147153
# Define `before_install` and `after_install` functions that allow
148154
# plugin hooks to register a string of code for execution before or
149155
# after the installation process.

bin/ruby-build

Lines changed: 32 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# ruby-build --version
77
#
88
# -l, --list List latest stable releases for each Ruby
9-
# -r, --resolve Find the most recent version matching a prefix.
9+
# --resolve Find the most recent version matching a prefix.
1010
# --definitions List all local definitions, including outdated ones
1111
# --version Show version of ruby-build
1212
#
@@ -1405,47 +1405,24 @@ list_maintained_versions() {
14051405

14061406
filter_version_prefix()
14071407
{
1408-
match=1
1409-
prefix="$1"
1410-
if [[ "${prefix}" = "ruby" ]]; then
1411-
# Filter MRI versions
1412-
grep -e '^[0-9]'
1413-
elif echo "${prefix}" | grep -e '^\([0-9]\|[a-z\+]\+-[0-9]\)' > /dev/null; then
1414-
# Filter by version prefix
1415-
while IFS= read -r version; do
1416-
if [[ "${version}" = "${prefix}" ]] || [[ "${version}" = "${prefix}."* ]]; then
1417-
match=0
1418-
echo "${version}"
1419-
fi
1420-
done
1421-
else
1422-
# Filter by implementation
1423-
while IFS= read -r version; do
1424-
if [[ "${version}" = "${prefix}-"* ]]; then
1425-
match=0
1426-
echo "${version}"
1427-
fi
1428-
done
1429-
fi
1430-
return $match
1408+
pattern="${1//./\.}"
1409+
pattern="${pattern//+/\+}"
1410+
grep -e "^${pattern}[-.$]"
14311411
}
14321412

14331413
resolve() {
14341414
prefix="${1%.}"
14351415
prefix="${prefix#ruby-}"
14361416

1437-
list_definitions | \
1417+
version=$(list_definitions | \
14381418
grep -v -e '-rc[0-9]*$' -e '-preview[0-9]*$' -e '-dev$' | \
14391419
filter_version_prefix "${prefix}" | \
14401420
LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n -k 5,5n | \
1441-
tail -n 1
1442-
}
1421+
tail -n 1)
1422+
1423+
[[ -z "${version}" ]] && return 1
1424+
[[ "${1}" = "ruby-"* ]] && version="ruby-${version}"
14431425

1444-
resolve_version() {
1445-
version=$(resolve "$@")
1446-
if [[ -z "${version}" ]]; then
1447-
exit 1
1448-
fi
14491426
echo "${version}"
14501427
}
14511428

@@ -1492,7 +1469,7 @@ for option in "${OPTIONS[@]}"; do
14921469
EARLY_EXIT=list_maintained_versions
14931470
;;
14941471
"resolve")
1495-
EARLY_EXIT=resolve_version
1472+
EARLY_EXIT=resolve
14961473
;;
14971474
"d" | "dir")
14981475
APPEND_DEFINITION_TO_PREFIX=true
@@ -1544,22 +1521,13 @@ if [ "${#EXTRA_ARGUMENTS[@]}" -gt 0 ]; then
15441521
RUBY_CONFIGURE_OPTS_ARRAY=("${EXTRA_ARGUMENTS[@]}")
15451522
fi
15461523

1547-
ORIGINAL_PREFIX_PATH="${PREFIX_PATH}"
1548-
if [ "$APPEND_DEFINITION_TO_PREFIX" = "true" ]; then
1549-
if [ -p "$DEFINITION_PATH" ]; then
1550-
echo "ruby-build: using named pipes in combination with \`--dir' is not possible" >&2
1551-
EARLY_EXIT=usage_error
1552-
fi
1553-
PREFIX_PATH="$PREFIX_PATH/$(basename "$DEFINITION_PATH")"
1554-
fi
1555-
15561524
case "$EARLY_EXIT" in
15571525
help )
15581526
version
15591527
echo
15601528
usage 0
15611529
;;
1562-
version | list_definitions | list_maintained_versions | resolve_version )
1530+
version | list_definitions | list_maintained_versions | resolve )
15631531
shift
15641532
"$EARLY_EXIT" "$@"
15651533
exit 0
@@ -1576,6 +1544,8 @@ usage_error )
15761544
;;
15771545
esac
15781546

1547+
DEFINITION_PREFIX=""
1548+
15791549
# expand the <definition> argument to full path of the definition file
15801550
if [[ ! -f "$DEFINITION_PATH" && ! -p "$DEFINITION_PATH" ]]; then
15811551
for DEFINITION_DIR in "${RUBY_BUILD_DEFINITIONS[@]}"; do
@@ -1587,23 +1557,26 @@ if [[ ! -f "$DEFINITION_PATH" && ! -p "$DEFINITION_PATH" ]]; then
15871557

15881558
# If the given definition is like ruby-X.Y.Z, search again with X.Y.Z
15891559
if [[ "$DEFINITION_PATH" =~ ^ruby-[0-9] ]]; then
1590-
DEFINITION_PATH="${DEFINITION_PATH#ruby-}"
1560+
UNPREFIXED_DEFINITION_PATH="${DEFINITION_PATH#ruby-}"
15911561
for DEFINITION_DIR in "${RUBY_BUILD_DEFINITIONS[@]}"; do
1592-
if [ -f "${DEFINITION_DIR}/${DEFINITION_PATH}" ]; then
1593-
DEFINITION_PATH="${DEFINITION_DIR}/${DEFINITION_PATH}"
1562+
if [ -f "${DEFINITION_DIR}/${UNPREFIXED_DEFINITION_PATH}" ]; then
1563+
DEFINITION_PREFIX="ruby-"
1564+
DEFINITION_PATH="${DEFINITION_DIR}/${UNPREFIXED_DEFINITION_PATH}"
15941565
break
15951566
fi
15961567
done
15971568
fi
15981569

1570+
# If the given definition isn't a perfect match, we do a prefix search.
15991571
if [ ! -f "$DEFINITION_PATH" ]; then
1600-
fully_qualified_version=$(resolve "$DEFINITION_PATH")
1572+
FULLY_QUALIFIED_VERSION=$(resolve "$DEFINITION_PATH")
16011573
for DEFINITION_DIR in "${RUBY_BUILD_DEFINITIONS[@]}"; do
1602-
if [ -f "${DEFINITION_DIR}/${fully_qualified_version}" ]; then
1603-
DEFINITION_PATH="${DEFINITION_DIR}/${fully_qualified_version}"
1604-
if [ "$APPEND_DEFINITION_TO_PREFIX" = "true" ]; then
1605-
PREFIX_PATH="$ORIGINAL_PREFIX_PATH/$(basename "$DEFINITION_PATH")"
1574+
if [ -f "${DEFINITION_DIR}/${FULLY_QUALIFIED_VERSION}" ]; then
1575+
if [[ "$DEFINITION_PATH" =~ ^ruby-[0-9] ]]; then
1576+
DEFINITION_PREFIX="ruby-"
16061577
fi
1578+
1579+
DEFINITION_PATH="${DEFINITION_DIR}/${FULLY_QUALIFIED_VERSION}"
16071580
break
16081581
fi
16091582
done
@@ -1615,6 +1588,14 @@ if [[ ! -f "$DEFINITION_PATH" && ! -p "$DEFINITION_PATH" ]]; then
16151588
fi
16161589
fi
16171590

1591+
if [ "$APPEND_DEFINITION_TO_PREFIX" = "true" ]; then
1592+
if [ -p "$DEFINITION_PATH" ]; then
1593+
echo "ruby-build: using named pipes in combination with \`--dir' is not possible" >&2
1594+
EARLY_EXIT=usage_error
1595+
fi
1596+
PREFIX_PATH="$PREFIX_PATH/${DEFINITION_PREFIX}$(basename "$DEFINITION_PATH")"
1597+
fi
1598+
16181599
# normalize the <prefix> argument
16191600
if [ "${PREFIX_PATH#/}" = "$PREFIX_PATH" ]; then
16201601
PREFIX_PATH="${PWD}/${PREFIX_PATH}"

test/definitions.bats

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ NUM_DEFINITIONS="$(ls "$BATS_TEST_DIRNAME"/../share/ruby-build | wc -l)"
9999
touch "${TMP}/definitions/2.0.0"
100100

101101
run bin/ruby-build --resolve "ruby-1.9" "${TMP}/install"
102-
assert_success "1.9.10"
102+
assert_success "ruby-1.9.10"
103103
}
104104

105105
@test "resolve definition by implementation name" {

test/rbenv.bats

100644100755
Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ stub_ruby_build() {
1616
}
1717

1818
@test "install proper" {
19-
stub_ruby_build 'echo ruby-build "$@"'
19+
stub_ruby_build 'echo 2.1.2' 'echo ruby-build "$@"'
2020

2121
run rbenv-install 2.1.2
2222
assert_success "ruby-build 2.1.2 ${RBENV_ROOT}/versions/2.1.2"
@@ -27,7 +27,7 @@ stub_ruby_build() {
2727
}
2828

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

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

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

4444
run rbenv-install 2.1.2
4545
assert_success <<OUT
@@ -52,7 +52,7 @@ OUT
5252
}
5353

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

5858
run rbenv-install
@@ -100,7 +100,8 @@ OUT
100100
fi
101101

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

106107
run rbenv-install 1.9.3
@@ -127,10 +128,11 @@ OUT
127128

128129
@test "Homebrew upgrade instructions" {
129130
stub brew "--prefix : echo '${BATS_TEST_DIRNAME%/*}'"
130-
stub_ruby_build 'echo ERROR >&2 && exit 2' \
131+
stub_ruby_build 'exit 1' \
132+
'echo ERROR >&2 && exit 2' \
131133
"--definitions : true"
132134

133-
run rbenv-install 1.9.3
135+
run rbenv-install 1.9.10
134136
assert_failure
135137
assert_output <<OUT
136138
ERROR
@@ -148,7 +150,8 @@ OUT
148150

149151
@test "no build definitions from plugins" {
150152
refute [ -e "${RBENV_ROOT}/plugins" ]
151-
stub_ruby_build 'echo $RUBY_BUILD_DEFINITIONS'
153+
stub_ruby_build 'echo 2.1.2' \
154+
'echo $RUBY_BUILD_DEFINITIONS'
152155

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

162166
run rbenv-install 2.1.2
163167
assert_success

0 commit comments

Comments
 (0)