pyenv/libexec/rbenv
Mislav Marohnić 76e64ff2ea Have shims survive symlinked rbenv updates a la Homebrew
Homebrew places the rbenv executable in a location such as
`/usr/local/bin/rbenv`, which is in PATH. However, that is a symlink to
`/usr/local/Cellar/rbenv/<VERSION>/bin/rbenv`, which is itself a symlink to
`/usr/local/Cellar/rbenv/<VERSION>/libexec/rbenv`. Upon executing, rbenv
will add its own directory to PATH so that it can easily invoke its
subcommands.

When generating shims during `rbenv rehash`, rbenv will try to put the
absolute path to itself inside each shim so that shims would work even
if rbenv itself isn't in PATH. Under Homebrew, rbenv's directory will be
the versioned directory in Homebrew's Cellar. However, due to Homebrew's
auto-cleanup functionality, shims generated this way will be broken
after upgrading rbenv because of the versioned Cellar path.

This changes how rbenv discovers itself in PATH: it will look at the
original PATH, not in the one modified by rbenv, with the intention of
excluding results under rbenv's own `libexec/`. If rbenv wasn't found in
PATH, return the absolute path to rbenv's own `bin/rbenv`.
2021-09-29 19:54:36 +02:00

130 lines
2.8 KiB
Bash
Executable file

#!/usr/bin/env bash
set -e
if [ "$1" = "--debug" ]; then
export RBENV_DEBUG=1
shift
fi
if [ -n "$RBENV_DEBUG" ]; then
# https://wiki-dev.bash-hackers.org/scripting/debuggingtips#making_xtrace_more_useful
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
set -x
fi
abort() {
{ if [ "$#" -eq 0 ]; then cat -
else echo "rbenv: $*"
fi
} >&2
exit 1
}
if enable -f "${BASH_SOURCE%/*}"/../libexec/rbenv-realpath.dylib realpath 2>/dev/null; then
abs_dirname() {
local path
path="$(realpath "$1")"
echo "${path%/*}"
}
else
[ -z "$RBENV_NATIVE_EXT" ] || abort "failed to load \`realpath' builtin"
READLINK=$(type -p greadlink readlink 2>/dev/null | head -n1)
[ -n "$READLINK" ] || abort "cannot find readlink - are you missing GNU coreutils?"
resolve_link() {
$READLINK "$1"
}
abs_dirname() {
local cwd="$PWD"
local path="$1"
while [ -n "$path" ]; do
cd "${path%/*}"
local name="${path##*/}"
path="$(resolve_link "$name" || true)"
done
pwd
cd "$cwd"
}
fi
if [ -z "${RBENV_ROOT}" ]; then
RBENV_ROOT="${HOME}/.rbenv"
else
RBENV_ROOT="${RBENV_ROOT%/}"
fi
export RBENV_ROOT
if [ -z "${RBENV_DIR}" ]; then
RBENV_DIR="$PWD"
else
[[ $RBENV_DIR == /* ]] || RBENV_DIR="$PWD/$RBENV_DIR"
cd "$RBENV_DIR" 2>/dev/null || abort "cannot change working directory to \`$RBENV_DIR'"
RBENV_DIR="$PWD"
cd "$OLDPWD"
fi
export RBENV_DIR
[ -n "$RBENV_ORIG_PATH" ] || export RBENV_ORIG_PATH="$PATH"
shopt -s nullglob
bin_path="$(abs_dirname "$0")"
for plugin_bin in "${RBENV_ROOT}/plugins/"*/bin; do
PATH="${plugin_bin}:${PATH}"
done
export PATH="${bin_path}:${PATH}"
RBENV_HOOK_PATH="${RBENV_HOOK_PATH}:${RBENV_ROOT}/rbenv.d"
if [ "${bin_path%/*}" != "$RBENV_ROOT" ]; then
# Add rbenv's own `rbenv.d` unless rbenv was cloned to RBENV_ROOT
RBENV_HOOK_PATH="${RBENV_HOOK_PATH}:${bin_path%/*}/rbenv.d"
fi
RBENV_HOOK_PATH="${RBENV_HOOK_PATH}:/usr/local/etc/rbenv.d:/etc/rbenv.d:/usr/lib/rbenv/hooks"
for plugin_hook in "${RBENV_ROOT}/plugins/"*/etc/rbenv.d; do
RBENV_HOOK_PATH="${RBENV_HOOK_PATH}:${plugin_hook}"
done
RBENV_HOOK_PATH="${RBENV_HOOK_PATH#:}"
export RBENV_HOOK_PATH
shopt -u nullglob
command="$1"
case "$command" in
"" )
{ rbenv---version
rbenv-help
} | abort
;;
-v | --version )
exec rbenv---version
;;
-h | --help )
exec rbenv-help
;;
* )
command_path="$(command -v "rbenv-$command" || true)"
if [ -z "$command_path" ]; then
if [ "$command" == "shell" ]; then
abort "shell integration not enabled. Run \`rbenv init' for instructions."
else
abort "no such command \`$command'"
fi
fi
shift 1
if [ "$1" = --help ]; then
if [[ "$command" == "sh-"* ]]; then
echo "rbenv help \"$command\""
else
exec rbenv-help "$command"
fi
else
exec "$command_path" "$@"
fi
;;
esac