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`.
This commit is contained in:
Mislav Marohnić 2021-09-29 17:50:03 +02:00
parent b0fb351419
commit 76e64ff2ea
2 changed files with 18 additions and 1 deletions

View file

@ -68,6 +68,7 @@ else
fi
export RBENV_DIR
[ -n "$RBENV_ORIG_PATH" ] || export RBENV_ORIG_PATH="$PATH"
shopt -s nullglob

View file

@ -34,6 +34,22 @@ remove_prototype_shim() {
rm -f "$PROTOTYPE_SHIM_PATH"
}
# Locates rbenv as found in the user's PATH. Otherwise, returns an
# absolute path to the rbenv executable itself.
rbenv_path() {
local found
found="$(PATH="$RBENV_ORIG_PATH" command -v rbenv)"
if [[ $found == /* ]]; then
echo "$found"
elif [[ -n "$found" ]]; then
echo "$PWD/${found#./}"
else
# Assume rbenv isn't in PATH.
local here="${BASH_SOURCE%/*}"
echo "${here%/*}/bin/rbenv"
fi
}
# The prototype shim file is a script that re-execs itself, passing
# its filename and any arguments to `rbenv exec`. This file is
# hard-linked for every executable and then removed. The linking
@ -61,7 +77,7 @@ if [ "\$program" = "ruby" ]; then
fi
export RBENV_ROOT="$RBENV_ROOT"
exec "$(command -v rbenv)" exec "\$program" "\$@"
exec "$(rbenv_path)" exec "\$program" "\$@"
SH
chmod +x "$PROTOTYPE_SHIM_PATH"
}