mirror of
https://github.com/rbenv/rbenv.git
synced 2025-11-10 05:51:56 +01:00
Enable fallback to PATH from rbenv shims
Previously, when someone activated rbenv shim `foo`, rbenv would error out if `RBENV_ROOT/versions/RBENV_VERSION/bin/foo` did not exist. This change allows `foo` to be additionally looked up in PATH as fallback. This prevents a case where one of the Ruby versions is shadowing a system-wide command of the same name, preventing the use of the global command across all other Ruby versions. rbenv used to be strict around this, allowing the fallback to avoid ever falling back to system Ruby for invocations like `bundle` if the current Ruby version did not yet install Bundler. The current approach prevents this scenario by explicitly disallowing fallback for the following executables: ruby, rake, gem, bundle, bundler, irb, rdoc, ri.
This commit is contained in:
parent
6b1cc34610
commit
5ce2fd8a2f
3 changed files with 64 additions and 16 deletions
|
|
@ -1,17 +1,21 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Summary: Run an executable with the selected Ruby version
|
||||
# Summary: Run an executable with the current Ruby version
|
||||
#
|
||||
# Usage: rbenv exec <command> [arg1 arg2...]
|
||||
# Usage: rbenv exec <command> [<args>...]
|
||||
#
|
||||
# Runs an executable by first preparing PATH so that the selected Ruby
|
||||
# version's `bin' directory is at the front.
|
||||
# Runs an executable by first prepending the current Ruby version's
|
||||
# `bin' directory to PATH.
|
||||
#
|
||||
# For example, if the currently selected Ruby version is 1.9.3-p327:
|
||||
# rbenv exec bundle install
|
||||
# For example, this invocation:
|
||||
#
|
||||
# is equivalent to:
|
||||
# PATH="$RBENV_ROOT/versions/1.9.3-p327/bin:$PATH" bundle install
|
||||
# RBENV_VERSION=3.1.2 rbenv exec bundle install
|
||||
#
|
||||
# roughly translates to:
|
||||
#
|
||||
# PATH="$RBENV_ROOT/versions/3.1.2/bin:$PATH" bundle install
|
||||
#
|
||||
# See `rbenv help which' for information about the fallback mechanism.
|
||||
|
||||
set -e
|
||||
[ -n "$RBENV_DEBUG" ] && set -x
|
||||
|
|
@ -41,7 +45,7 @@ for script in "${scripts[@]}"; do
|
|||
done
|
||||
|
||||
shift 1
|
||||
if [ "$RBENV_VERSION" != "system" ]; then
|
||||
if [ "$RBENV_BIN_PATH" = "${RBENV_ROOT}/versions/${RBENV_VERSION}/bin" ]; then
|
||||
export PATH="${RBENV_BIN_PATH}:${PATH}"
|
||||
fi
|
||||
exec -a "$RBENV_COMMAND" "$RBENV_COMMAND_PATH" "$@"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,17 @@
|
|||
#
|
||||
# Displays the full path to the executable that rbenv will invoke when
|
||||
# you run the given command.
|
||||
#
|
||||
# If GEM_HOME is set, the result will be `$GEM_HOME/bin/<command>' if
|
||||
# it exists.
|
||||
#
|
||||
# If the current Ruby version is "system", the command will be looked up
|
||||
# in PATH.
|
||||
#
|
||||
# For other Ruby versions, the command is first looked up in
|
||||
# `$RBENV_ROOT/versions/$RBENV_VERSION/bin'. If it does not exist and if
|
||||
# the command is not one of the core Ruby executables (e.g. "ruby",
|
||||
# "gem", "bundle"), it will be looked up in PATH.
|
||||
|
||||
set -e
|
||||
[ -n "$RBENV_DEBUG" ] && set -x
|
||||
|
|
@ -36,15 +47,28 @@ fi
|
|||
|
||||
RBENV_VERSION="${RBENV_VERSION:-$(rbenv-version-name)}"
|
||||
|
||||
if [ "$RBENV_VERSION" = "system" ]; then
|
||||
PATH="$(remove_from_path "${RBENV_ROOT}/shims")" \
|
||||
RBENV_COMMAND_PATH="$(command -v "$RBENV_COMMAND" || true)"
|
||||
if [[ -n "$GEM_HOME" && -x "${GEM_HOME}/bin/${RBENV_COMMAND}" ]]; then
|
||||
RBENV_COMMAND_PATH="${GEM_HOME}/bin/${RBENV_COMMAND}"
|
||||
elif [ "$RBENV_VERSION" = "system" ]; then
|
||||
PATH="$(remove_from_path "${RBENV_ROOT}/shims")" RBENV_COMMAND_PATH="$(type -P "$RBENV_COMMAND" || true)"
|
||||
else
|
||||
RBENV_COMMAND_PATH="${RBENV_ROOT}/versions/${RBENV_VERSION}/bin/${RBENV_COMMAND}"
|
||||
fi
|
||||
|
||||
if [[ ! -x "$RBENV_COMMAND_PATH" && -n "$GEM_HOME" && -x "${GEM_HOME}/bin/${RBENV_COMMAND}" ]]; then
|
||||
RBENV_COMMAND_PATH="${GEM_HOME}/bin/${RBENV_COMMAND}"
|
||||
if [ ! -x "$RBENV_COMMAND_PATH" ]; then
|
||||
# Look up the command in PATH as fallback.
|
||||
case "$RBENV_COMMAND" in
|
||||
ruby | rake | gem | bundle | bundler | irb | rdoc | ri )
|
||||
# Do not allow fallback to PATH for core Ruby commands. If any of these are missing
|
||||
# in the current Ruby version, error out instead of allowing a potentially unrelated
|
||||
# Ruby version to activate and potentially muck up the current project.
|
||||
;;
|
||||
* )
|
||||
if PATH="$(remove_from_path "${RBENV_ROOT}/shims")" RBENV_COMMAND_FALLBACK="$(type -P "$RBENV_COMMAND")"; then
|
||||
RBENV_COMMAND_PATH="$RBENV_COMMAND_FALLBACK"
|
||||
fi
|
||||
unset RBENV_COMMAND_FALLBACK
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
OLDIFS="$IFS"
|
||||
|
|
|
|||
|
|
@ -78,6 +78,26 @@ ${RBENV_ROOT}/versions/2.0/bin/ruby
|
|||
OUT
|
||||
}
|
||||
|
||||
@test "prepends Ruby to PATH" {
|
||||
export RBENV_VERSION="2.0"
|
||||
create_executable "ruby" <<SH
|
||||
#!$BASH
|
||||
echo \$PATH
|
||||
SH
|
||||
|
||||
run rbenv-exec ruby
|
||||
assert_success
|
||||
[[ $output == "${RBENV_ROOT}/versions/${RBENV_VERSION}/bin:"* ]]
|
||||
}
|
||||
|
||||
@test "does not modify PATH for fallback" {
|
||||
export RBENV_VERSION="2.0"
|
||||
create_executable "ruby" "#!/bin/sh"
|
||||
|
||||
run rbenv-exec bash -c 'echo $PATH'
|
||||
assert_success "$PATH"
|
||||
}
|
||||
|
||||
@test "supports ruby -S <cmd>" {
|
||||
export RBENV_VERSION="2.0"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue