#!/usr/bin/env bash set -e [ -n "$RBENV_DEBUG" ] && set -x SHIM_PATH="${RBENV_ROOT}/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 > "$PROTOTYPE_SHIM_PATH" <<SH #!/usr/bin/env bash set -e export RBENV_ROOT="$RBENV_ROOT" exec rbenv exec "\${0##*/}" "\$@" SH 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 "$PROTOTYPE_SHIM_PATH" "$shim" done } # 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 shopt -s nullglob make_shims ../versions/*/bin/* # Find and run any plugins that might want to make shims too. RBENV_REHASH_PLUGINS=(/etc/rbenv.d/rehash/*.bash ${RBENV_ROOT}/rbenv.d/rehash/*.bash) shopt -u nullglob for script in ${RBENV_REHASH_PLUGINS[@]}; do source $script done