2011-09-13 03:28:24 +02:00
|
|
|
#!/usr/bin/env bash
|
2012-12-30 22:10:23 +01:00
|
|
|
#
|
2013-12-12 00:35:31 +01:00
|
|
|
# Summary: Install a Ruby version using ruby-build
|
2012-12-30 22:25:52 +01:00
|
|
|
#
|
2023-11-07 18:10:34 +01:00
|
|
|
# Usage: rbenv install [-f|-s] [-kpv] <version> [-- <configure-args...>]
|
2016-01-15 15:10:05 +01:00
|
|
|
# rbenv install [-f|-s] [-kpv] <definition-file>
|
2023-11-07 18:10:34 +01:00
|
|
|
# rbenv install --list
|
2016-01-15 15:24:33 +01:00
|
|
|
# rbenv install --version
|
2012-12-30 22:10:23 +01:00
|
|
|
#
|
2023-11-07 18:10:34 +01:00
|
|
|
# -l, --list List latest stable versions for each Ruby
|
|
|
|
# -L, --list-all List all local versions, including outdated ones
|
|
|
|
# -f, --force Allow overwriting an existing installed version
|
|
|
|
# -s, --skip-existing Avoid overwriting an existing installed version
|
2013-12-12 00:35:31 +01:00
|
|
|
#
|
|
|
|
# ruby-build options:
|
|
|
|
#
|
2023-11-07 18:10:34 +01:00
|
|
|
# -v, --verbose Verbose mode: forward all build output to stdout/stderr
|
|
|
|
# -p, --patch Apply a patch from stdin before building
|
|
|
|
# -k, --keep Keep source tree in RBENV_BUILD_ROOT after installation
|
|
|
|
# (defaults to "RBENV_ROOT/sources")
|
|
|
|
# --version Show version of ruby-build
|
2012-12-30 22:10:23 +01:00
|
|
|
#
|
2023-11-07 18:10:34 +01:00
|
|
|
# For detailed information on installing Ruby versions with ruby-build,
|
|
|
|
# including a list of environment variables for adjusting compilation,
|
|
|
|
# see: https://github.com/rbenv/ruby-build#usage
|
2012-12-30 22:29:52 +01:00
|
|
|
#
|
2011-09-13 03:28:24 +02:00
|
|
|
set -e
|
|
|
|
[ -n "$RBENV_DEBUG" ] && set -x
|
|
|
|
|
2014-09-09 05:14:33 +02:00
|
|
|
# Add `share/ruby-build/` directory from each rbenv plugin to the list of
|
|
|
|
# paths where build definitions are looked up.
|
|
|
|
shopt -s nullglob
|
|
|
|
for plugin_path in "$RBENV_ROOT"/plugins/*/share/ruby-build; do
|
|
|
|
RUBY_BUILD_DEFINITIONS="${RUBY_BUILD_DEFINITIONS}:${plugin_path}"
|
|
|
|
done
|
|
|
|
export RUBY_BUILD_DEFINITIONS
|
|
|
|
shopt -u nullglob
|
|
|
|
|
2011-09-13 20:16:03 +02:00
|
|
|
# Provide rbenv completions
|
|
|
|
if [ "$1" = "--complete" ]; then
|
2015-12-03 21:11:14 +01:00
|
|
|
echo --list
|
2020-02-19 03:01:43 +01:00
|
|
|
echo --list-all
|
2015-12-03 21:11:14 +01:00
|
|
|
echo --force
|
|
|
|
echo --skip-existing
|
|
|
|
echo --keep
|
|
|
|
echo --patch
|
2016-01-15 21:12:53 +01:00
|
|
|
echo --verbose
|
|
|
|
echo --version
|
2011-09-13 20:16:03 +02:00
|
|
|
exec ruby-build --definitions
|
|
|
|
fi
|
|
|
|
|
2012-08-15 21:02:23 +02:00
|
|
|
# Load shared library functions
|
2012-08-15 21:43:44 +02:00
|
|
|
eval "$(ruby-build --lib)"
|
2012-08-15 21:02:23 +02:00
|
|
|
|
|
|
|
usage() {
|
2015-06-02 03:41:42 +02:00
|
|
|
rbenv-help install 2>/dev/null
|
2012-08-15 21:02:23 +02:00
|
|
|
[ -z "$1" ] || exit "$1"
|
|
|
|
}
|
|
|
|
|
2013-03-21 18:40:53 +01:00
|
|
|
definitions() {
|
|
|
|
local query="$1"
|
2014-04-18 02:51:26 +02:00
|
|
|
ruby-build --definitions | $(type -p ggrep grep | head -1) -F "$query" || true
|
2013-03-21 18:40:53 +01:00
|
|
|
}
|
|
|
|
|
2022-09-25 11:20:43 +02:00
|
|
|
suggest_selecting_global() {
|
|
|
|
# shellcheck disable=SC2155
|
|
|
|
local version_file="$(rbenv-version-file)"
|
|
|
|
[[ "$version_file" != "$RBENV_ROOT"/version || -e "$version_file" ]] && return 0
|
|
|
|
echo
|
|
|
|
colorize 1 "NOTE:"
|
|
|
|
echo -n " to activate this Ruby version as the new default, run: "
|
|
|
|
colorize 33 "rbenv global $VERSION_NAME"
|
|
|
|
echo
|
|
|
|
}
|
|
|
|
|
|
|
|
colorize() {
|
|
|
|
if [ -t 1 ]; then printf "\e[%sm%s\e[m" "$1" "$2"
|
|
|
|
else printf "%s" "$2"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2013-03-21 18:40:53 +01:00
|
|
|
indent() {
|
|
|
|
sed 's/^/ /'
|
|
|
|
}
|
|
|
|
|
2013-01-30 00:22:56 +01:00
|
|
|
unset FORCE
|
2014-04-04 17:28:27 +02:00
|
|
|
unset SKIP_EXISTING
|
2012-08-15 21:02:23 +02:00
|
|
|
unset KEEP
|
|
|
|
unset VERBOSE
|
2013-12-11 21:16:47 +01:00
|
|
|
unset HAS_PATCH
|
2012-08-15 21:02:23 +02:00
|
|
|
|
|
|
|
parse_options "$@"
|
|
|
|
for option in "${OPTIONS[@]}"; do
|
|
|
|
case "$option" in
|
|
|
|
"h" | "help" )
|
|
|
|
usage 0
|
|
|
|
;;
|
|
|
|
"l" | "list" )
|
2020-02-19 03:01:43 +01:00
|
|
|
ruby-build --list
|
2022-10-03 13:28:58 +02:00
|
|
|
[ ! -t 1 ] || {
|
2020-03-06 14:14:45 +01:00
|
|
|
echo
|
|
|
|
echo "Only latest stable releases for each Ruby implementation are shown."
|
2023-11-07 18:10:34 +01:00
|
|
|
echo "Use \`rbenv install --list-all' to show all local versions."
|
2020-03-06 14:14:45 +01:00
|
|
|
} 1>&2
|
2012-08-15 21:02:23 +02:00
|
|
|
exit
|
|
|
|
;;
|
2020-02-19 03:01:43 +01:00
|
|
|
"L" | "list-all" )
|
|
|
|
ruby-build --definitions
|
|
|
|
exit
|
2020-01-30 06:48:43 +01:00
|
|
|
;;
|
2013-01-30 00:22:56 +01:00
|
|
|
"f" | "force" )
|
|
|
|
FORCE=true
|
|
|
|
;;
|
2014-04-04 17:28:27 +02:00
|
|
|
"s" | "skip-existing" )
|
|
|
|
SKIP_EXISTING=true
|
|
|
|
;;
|
2012-08-15 21:02:23 +02:00
|
|
|
"k" | "keep" )
|
|
|
|
[ -n "${RBENV_BUILD_ROOT}" ] || RBENV_BUILD_ROOT="${RBENV_ROOT}/sources"
|
|
|
|
;;
|
|
|
|
"v" | "verbose" )
|
|
|
|
VERBOSE="-v"
|
|
|
|
;;
|
2013-12-11 21:16:47 +01:00
|
|
|
"p" | "patch" )
|
|
|
|
HAS_PATCH="-p"
|
|
|
|
;;
|
2012-08-15 21:02:23 +02:00
|
|
|
"version" )
|
|
|
|
exec ruby-build --version
|
|
|
|
;;
|
|
|
|
* )
|
2014-11-27 04:51:11 +01:00
|
|
|
usage 1 >&2
|
2012-08-15 21:02:23 +02:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
2014-11-27 04:51:11 +01:00
|
|
|
[ "${#ARGUMENTS[@]}" -le 1 ] || usage 1 >&2
|
2014-11-27 04:45:52 +01:00
|
|
|
|
2013-01-29 22:07:06 +01:00
|
|
|
unset VERSION_NAME
|
2013-01-30 00:01:13 +01:00
|
|
|
|
|
|
|
# The first argument contains the definition to install. If the
|
|
|
|
# argument is missing, try to install whatever local app-specific
|
|
|
|
# version is specified by rbenv. Show usage instructions if a local
|
|
|
|
# version is not specified.
|
2012-08-15 21:02:23 +02:00
|
|
|
DEFINITION="${ARGUMENTS[0]}"
|
2014-01-04 14:43:42 +01:00
|
|
|
[ -n "$DEFINITION" ] || DEFINITION="$(rbenv-local 2>/dev/null || true)"
|
2014-11-27 04:51:11 +01:00
|
|
|
[ -n "$DEFINITION" ] || usage 1 >&2
|
2011-09-13 03:38:48 +02:00
|
|
|
|
2013-01-29 22:07:06 +01:00
|
|
|
# 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.
|
|
|
|
declare -a before_hooks after_hooks
|
|
|
|
|
2023-10-12 11:10:43 +02:00
|
|
|
# shellcheck disable=SC2317
|
2013-01-29 22:07:06 +01:00
|
|
|
before_install() {
|
|
|
|
local hook="$1"
|
|
|
|
before_hooks["${#before_hooks[@]}"]="$hook"
|
|
|
|
}
|
|
|
|
|
2023-10-12 11:10:43 +02:00
|
|
|
# shellcheck disable=SC2317
|
2013-01-29 22:07:06 +01:00
|
|
|
after_install() {
|
|
|
|
local hook="$1"
|
|
|
|
after_hooks["${#after_hooks[@]}"]="$hook"
|
|
|
|
}
|
|
|
|
|
2023-10-12 11:10:43 +02:00
|
|
|
IFS=$'\n' read -d '' -r -a scripts <<<"$(rbenv-hooks install)" || true
|
|
|
|
# shellcheck disable=SC1090
|
2013-12-30 14:45:16 +01:00
|
|
|
for script in "${scripts[@]}"; do source "$script"; done
|
2012-08-16 04:49:13 +02:00
|
|
|
|
2013-01-29 22:07:06 +01:00
|
|
|
|
|
|
|
# Set VERSION_NAME from $DEFINITION, if it is not already set. Then
|
|
|
|
# compute the installation prefix.
|
|
|
|
[ -n "$VERSION_NAME" ] || VERSION_NAME="${DEFINITION##*/}"
|
2011-09-13 03:38:48 +02:00
|
|
|
PREFIX="${RBENV_ROOT}/versions/${VERSION_NAME}"
|
|
|
|
|
2013-02-22 20:22:15 +01:00
|
|
|
[ -d "${PREFIX}" ] && PREFIX_EXISTS=1
|
|
|
|
|
2013-01-30 00:22:56 +01:00
|
|
|
# If the installation prefix exists, prompt for confirmation unless
|
|
|
|
# the --force option was specified.
|
2014-04-04 17:28:27 +02:00
|
|
|
if [ -d "${PREFIX}/bin" ]; then
|
|
|
|
if [ -z "$FORCE" ] && [ -z "$SKIP_EXISTING" ]; then
|
|
|
|
echo "rbenv: $PREFIX already exists" >&2
|
2024-05-01 15:45:23 +02:00
|
|
|
if [ ! -t 0 ]; then
|
|
|
|
echo "rbenv: must use \`--force' or \`--skip-existing' in non-interactive mode" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
2023-10-12 11:10:43 +02:00
|
|
|
read -rp "continue with installation? (y/N) "
|
2014-04-04 17:28:27 +02:00
|
|
|
|
|
|
|
case "$REPLY" in
|
|
|
|
y* | Y* ) ;;
|
|
|
|
* ) exit 1 ;;
|
|
|
|
esac
|
|
|
|
elif [ -n "$SKIP_EXISTING" ]; then
|
|
|
|
# Since we know the ruby version is already installed, and are opting to
|
|
|
|
# not force installation of existing versions, we just `exit 0` here to
|
|
|
|
# leave things happy
|
|
|
|
exit 0
|
|
|
|
fi
|
2013-01-30 00:22:56 +01:00
|
|
|
fi
|
|
|
|
|
2013-01-29 22:07:06 +01:00
|
|
|
# If RBENV_BUILD_ROOT is set, always pass keep options to ruby-build.
|
2012-04-28 23:26:52 +02:00
|
|
|
if [ -n "${RBENV_BUILD_ROOT}" ]; then
|
|
|
|
export RUBY_BUILD_BUILD_PATH="${RBENV_BUILD_ROOT}/${VERSION_NAME}"
|
2012-08-15 21:02:23 +02:00
|
|
|
KEEP="-k"
|
2012-04-28 23:26:52 +02:00
|
|
|
fi
|
|
|
|
|
2013-01-29 22:07:06 +01:00
|
|
|
# Set RUBY_BUILD_CACHE_PATH to $RBENV_ROOT/cache, if the directory
|
|
|
|
# exists and the variable is not already set.
|
2012-11-14 00:34:08 +01:00
|
|
|
if [ -z "${RUBY_BUILD_CACHE_PATH}" ] && [ -d "${RBENV_ROOT}/cache" ]; then
|
|
|
|
export RUBY_BUILD_CACHE_PATH="${RBENV_ROOT}/cache"
|
Simple, optional tarball cache support
Rationale:
Both in development and in production, some usage patterns of ruby-build
are slowed down by the download phase. In scenarios such as
troubleshooting failing builds or with provisioning situations (chef,
vagrant...) the repeated download is unnerving, bandwidth wasting and
simply against etiquette towards tarball hosters.
It also happens that some source sites happen to be down and in such
cases it is helpful to be able to sideload sources to rbenv.
Behavior:
By default nothing changes.
If the variable CACHE_PATH is set, then ruby-build will use that
directory to store a successful download, and will check before
downloading if the tarball is already there, in which case downloading
is skipped.
The file is first downloaded as before in the tmp subdirectory and only
moved afterwards, thus ensuring consistency.
There is no default cache path and the optional variable is to be set by
hand, ensuring people know what they're doing when using ruby-build.
Additionnally, rbenv-install will helpfully set CACHE_PATH if and only
if a RBENV_ROOT/cache directory exists. Again, the directory has to be
created manually.
The CACHE_PATH variable internally ends with a slash to mutualize
non-cached cases. Still, consistency is ensured whether or not a slash
is provided externally.
Notes:
I'm not quite sure CACHE_PATH is a good name, maybe
RUBY_BUILD_CACHE_PATH is better and less conflicting.
2012-11-07 16:43:15 +01:00
|
|
|
fi
|
|
|
|
|
2013-04-19 18:35:43 +02:00
|
|
|
# Default RBENV_VERSION to the globally-specified Ruby version. (The
|
|
|
|
# REE installer requires an existing Ruby installation to run. An
|
|
|
|
# unsatisfied local .ruby-version file can cause the installer to
|
|
|
|
# fail.)
|
2022-09-25 11:20:43 +02:00
|
|
|
# shellcheck disable=SC2155
|
2014-01-04 14:43:42 +01:00
|
|
|
export RBENV_VERSION="$(rbenv-global 2>/dev/null || true)"
|
2013-04-19 18:35:43 +02:00
|
|
|
|
2013-01-29 22:07:06 +01:00
|
|
|
|
|
|
|
# Execute `before_install` hooks.
|
|
|
|
for hook in "${before_hooks[@]}"; do eval "$hook"; done
|
|
|
|
|
2013-02-04 23:43:38 +01:00
|
|
|
# Plan cleanup on unsuccessful installation.
|
|
|
|
cleanup() {
|
2013-02-22 20:22:15 +01:00
|
|
|
[ -z "${PREFIX_EXISTS}" ] && rm -rf "$PREFIX"
|
2013-02-04 23:43:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
trap cleanup SIGINT
|
|
|
|
|
2023-10-11 15:10:02 +02:00
|
|
|
build_args=(${KEEP:+--keep} ${VERBOSE:+--verbose} ${HAS_PATCH:+--patch} "$DEFINITION" "$PREFIX")
|
|
|
|
[ ${#EXTRA_ARGUMENTS[@]} -eq 0 ] || build_args+=(-- "${EXTRA_ARGUMENTS[@]}")
|
|
|
|
|
2013-03-21 18:40:53 +01:00
|
|
|
# Invoke `ruby-build` and record the exit status in $STATUS.
|
2013-01-29 22:07:06 +01:00
|
|
|
STATUS=0
|
2023-10-11 15:10:02 +02:00
|
|
|
ruby-build "${build_args[@]}" || STATUS="$?"
|
2013-01-29 22:07:06 +01:00
|
|
|
|
2013-03-21 18:40:53 +01:00
|
|
|
# Display a more helpful message if the definition wasn't found.
|
|
|
|
if [ "$STATUS" == "2" ]; then
|
|
|
|
{ candidates="$(definitions "$DEFINITION")"
|
2014-09-09 07:23:23 +02:00
|
|
|
here="$(dirname "${0%/*}")"
|
2013-03-21 18:40:53 +01:00
|
|
|
if [ -n "$candidates" ]; then
|
|
|
|
echo
|
|
|
|
echo "The following versions contain \`$DEFINITION' in the name:"
|
|
|
|
echo "$candidates" | indent
|
|
|
|
fi
|
|
|
|
echo
|
2023-11-07 18:10:34 +01:00
|
|
|
echo "See all available versions with \`rbenv install --list-all'."
|
2013-03-21 18:40:53 +01:00
|
|
|
echo
|
2014-09-09 07:23:23 +02:00
|
|
|
echo -n "If the version you need is missing, try upgrading ruby-build"
|
2023-10-12 11:10:43 +02:00
|
|
|
if [ "$here" != "${here#"$(brew --prefix 2>/dev/null)"}" ]; then
|
2014-09-09 07:23:23 +02:00
|
|
|
printf ":\n\n"
|
2023-02-20 16:00:59 +01:00
|
|
|
echo " brew upgrade ruby-build"
|
2014-09-09 07:23:23 +02:00
|
|
|
elif [ -d "${here}/.git" ]; then
|
|
|
|
printf ":\n\n"
|
2023-11-07 18:10:34 +01:00
|
|
|
echo " git -C ${here/${HOME}\//~/} pull"
|
2014-09-09 07:23:23 +02:00
|
|
|
else
|
|
|
|
printf ".\n"
|
|
|
|
fi
|
2013-03-21 18:40:53 +01:00
|
|
|
} >&2
|
|
|
|
fi
|
|
|
|
|
2013-01-29 22:07:06 +01:00
|
|
|
# Execute `after_install` hooks.
|
|
|
|
for hook in "${after_hooks[@]}"; do eval "$hook"; done
|
|
|
|
|
|
|
|
# Run `rbenv-rehash` after a successful installation.
|
2013-02-04 23:43:38 +01:00
|
|
|
if [ "$STATUS" == "0" ]; then
|
2014-01-04 14:43:42 +01:00
|
|
|
rbenv-rehash
|
2022-09-25 11:20:43 +02:00
|
|
|
suggest_selecting_global
|
2013-02-04 23:43:38 +01:00
|
|
|
else
|
|
|
|
cleanup
|
|
|
|
fi
|
2013-01-29 22:07:06 +01:00
|
|
|
|
|
|
|
exit "$STATUS"
|