|
|
|
@ -1,31 +1,67 @@ |
|
|
|
#!/usr/bin/env bash |
|
|
|
set -e |
|
|
|
|
|
|
|
SHIM_PATH="${HOME}/.rbenv/shims" |
|
|
|
PROTOTYPE_SHIM_PATH="${SHIM_PATH}/.rbenv-shim" |
|
|
|
|
|
|
|
# Create the shims directory if it doesn't already exist. |
|
|
|
mkdir -p "$SHIM_PATH" |
|
|
|
|
|
|
|
# Ensure only one instance of rbenv-rehash is running at a time by |
|
|
|
# setting the shell's `noclobber` option and attempting to write to |
|
|
|
# the prototype shim file. If the file already exists, print a warning |
|
|
|
# to stderr and exit with a non-zero status. |
|
|
|
set -o noclobber |
|
|
|
{ echo > "$PROTOTYPE_SHIM_PATH" |
|
|
|
} 2>/dev/null || |
|
|
|
{ echo "rbenv: cannot rehash: $PROTOTYPE_SHIM_PATH exists" |
|
|
|
exit 1 |
|
|
|
} >&2 |
|
|
|
set +o noclobber |
|
|
|
|
|
|
|
# If we were able to obtain a lock, register a trap to clean up the |
|
|
|
# prototype shim when the process exits. |
|
|
|
trap remove_prototype_shim SIGINT SIGTERM EXIT |
|
|
|
|
|
|
|
remove_prototype_shim() { |
|
|
|
rm -f "$PROTOTYPE_SHIM_PATH" |
|
|
|
} |
|
|
|
|
|
|
|
# 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 binary and then removed. The linking technique |
|
|
|
# is fast, uses less disk space than unique files, and also serves as |
|
|
|
# a locking mechanism. |
|
|
|
create_prototype_shim() { |
|
|
|
cat > .rbenv-shim <<SH |
|
|
|
cat > "$PROTOTYPE_SHIM_PATH" <<SH |
|
|
|
#!/usr/bin/env bash |
|
|
|
set -e |
|
|
|
exec rbenv exec "\${0##*/}" "\$@" |
|
|
|
SH |
|
|
|
chmod +x .rbenv-shim |
|
|
|
chmod +x "$PROTOTYPE_SHIM_PATH" |
|
|
|
} |
|
|
|
|
|
|
|
# Make shims by iterating over every filename argument and creating a |
|
|
|
# hard link from the prototype shim to a file of the same name in the |
|
|
|
# shims directory, if one does not already exist. |
|
|
|
make_shims() { |
|
|
|
local glob="$@" |
|
|
|
|
|
|
|
for file in $glob; do |
|
|
|
local shim="${file##*/}" |
|
|
|
[ -e "$shim" ] || ln -f .rbenv-shim "$shim" |
|
|
|
[ -e "$shim" ] || ln -f "$PROTOTYPE_SHIM_PATH" "$shim" |
|
|
|
done |
|
|
|
} |
|
|
|
|
|
|
|
mkdir -p "${HOME}/.rbenv/shims" |
|
|
|
cd "${HOME}/.rbenv/shims" |
|
|
|
rm -f * |
|
|
|
# Empty out the shims directory and make it the working directory. |
|
|
|
rm -f "$SHIM_PATH"/* |
|
|
|
cd "$SHIM_PATH" |
|
|
|
|
|
|
|
# Create the prototype shim, then make shims for all known binaries. |
|
|
|
create_prototype_shim |
|
|
|
make_shims ../versions/*/bin/* |
|
|
|
|
|
|
|
# Find and run any plugins that might want to make shims too. |
|
|
|
shopt -s nullglob |
|
|
|
RBENV_REHASH_PLUGINS=(/etc/rbenv.d/rehash/*.bash ${HOME}/.rbenv/rbenv.d/rehash/*.bash) |
|
|
|
shopt -u nullglob |
|
|
|
@ -33,5 +69,3 @@ shopt -u nullglob |
|
|
|
for script in ${RBENV_REHASH_PLUGINS[@]}; do |
|
|
|
source $script |
|
|
|
done |
|
|
|
|
|
|
|
rm -f .rbenv-shim |