Merge pull request #636 from sstephenson/speedup-rehash

Speed up `rbenv rehash`
This commit is contained in:
Mislav Marohnić 2014-10-16 12:29:51 +02:00
commit 07d675350f
2 changed files with 45 additions and 36 deletions

View file

@ -70,49 +70,47 @@ SH
# of the first shim in the shims directory, assume rbenv has been # of the first shim in the shims directory, assume rbenv has been
# upgraded and the existing shims need to be removed. # upgraded and the existing shims need to be removed.
remove_outdated_shims() { remove_outdated_shims() {
for shim in *; do local shim
for shim in "$SHIM_PATH"/*; do
if ! diff "$PROTOTYPE_SHIM_PATH" "$shim" >/dev/null 2>&1; then if ! diff "$PROTOTYPE_SHIM_PATH" "$shim" >/dev/null 2>&1; then
for shim in *; do rm -f "$shim"; done rm -f "$SHIM_PATH"/*
fi fi
break break
done done
} }
# List basenames of executables for every Ruby version
list_executable_names() {
local file
for file in "$RBENV_ROOT"/versions/*/bin/*; do
echo "${file##*/}"
done
}
# The basename of each argument passed to `make_shims` will be # The basename of each argument passed to `make_shims` will be
# registered for installation as a shim. In this way, plugins may call # registered for installation as a shim. In this way, plugins may call
# `make_shims` with a glob to register many shims at once. # `make_shims` with a glob to register many shims at once.
make_shims() { make_shims() {
local shims=("$@") local file shim
for file; do
for file in "${shims[@]}"; do shim="${file##*/}"
local shim="${file##*/}"
register_shim "$shim" register_shim "$shim"
done done
} }
# Create an empty array for the list of registered shims and an empty registered_shims=" "
# string to use as a search index.
registered_shims=()
registered_shims_index=""
# We will keep track of shims registered for installation with the # Registers the name of a shim to be generated.
# global `registered_shims` array and with a global search index
# string. The array will let us iterate over all registered shims. The
# index string will let us quickly check whether a shim with the given
# name has been registered or not.
register_shim() { register_shim() {
local shim="$@" registered_shims="${registered_shims}${1} "
registered_shims["${#registered_shims[@]}"]="$shim"
registered_shims_index="$registered_shims_index/$shim/"
} }
# To install all the registered shims, we iterate over the # Install all the shims registered via `make_shims` or `register_shim` directly.
# `registered_shims` array and create a link if one does not already
# exist.
install_registered_shims() { install_registered_shims() {
local shim local shim file
for shim in "${registered_shims[@]}"; do for shim in $registered_shims; do
[ -e "$shim" ] || ln -f "$PROTOTYPE_SHIM_PATH" "$shim" file="${SHIM_PATH}/${shim}"
[ -e "$file" ] || ln -f "$PROTOTYPE_SHIM_PATH" "$file"
done done
} }
@ -122,26 +120,21 @@ install_registered_shims() {
# removed. # removed.
remove_stale_shims() { remove_stale_shims() {
local shim local shim
for shim in *; do for shim in "$SHIM_PATH"/*; do
if [[ "$registered_shims_index" != *"/$shim/"* ]]; then if [[ "$registered_shims" != *" ${shim##*/} "* ]]; then
rm -f "$shim" rm -f "$shim"
fi fi
done done
} }
# Change to the shims directory.
cd "$SHIM_PATH"
shopt -s nullglob shopt -s nullglob
# Create the prototype shim, then register shims for all known # Create the prototype shim, then register shims for all known
# executables. # executables.
create_prototype_shim create_prototype_shim
remove_outdated_shims remove_outdated_shims
make_shims ../versions/*/bin/* make_shims $(list_executable_names | sort -u)
# Restore the previous working directory.
cd "$OLDPWD"
# Allow plugins to register shims. # Allow plugins to register shims.
OLDIFS="$IFS" OLDIFS="$IFS"
@ -152,8 +145,5 @@ for script in "${scripts[@]}"; do
source "$script" source "$script"
done done
# Change back to the shims directory to install the registered shims
# and remove stale shims.
cd "$SHIM_PATH"
install_registered_shims install_registered_shims
remove_stale_shims remove_stale_shims

View file

@ -53,7 +53,7 @@ ruby
OUT OUT
} }
@test "removes stale shims" { @test "removes outdated shims" {
mkdir -p "${RBENV_ROOT}/shims" mkdir -p "${RBENV_ROOT}/shims"
touch "${RBENV_ROOT}/shims/oldshim1" touch "${RBENV_ROOT}/shims/oldshim1"
chmod +x "${RBENV_ROOT}/shims/oldshim1" chmod +x "${RBENV_ROOT}/shims/oldshim1"
@ -67,6 +67,25 @@ OUT
assert [ ! -e "${RBENV_ROOT}/shims/oldshim1" ] assert [ ! -e "${RBENV_ROOT}/shims/oldshim1" ]
} }
@test "do exact matches when removing stale shims" {
create_executable "2.0" "unicorn_rails"
create_executable "2.0" "rspec-core"
rbenv-rehash
cp "$RBENV_ROOT"/shims/{rspec-core,rspec}
cp "$RBENV_ROOT"/shims/{rspec-core,rails}
cp "$RBENV_ROOT"/shims/{rspec-core,uni}
chmod +x "$RBENV_ROOT"/shims/{rspec,rails,uni}
run rbenv-rehash
assert_success ""
assert [ ! -e "${RBENV_ROOT}/shims/rails" ]
assert [ ! -e "${RBENV_ROOT}/shims/rake" ]
assert [ ! -e "${RBENV_ROOT}/shims/uni" ]
}
@test "binary install locations containing spaces" { @test "binary install locations containing spaces" {
create_executable "dirname1 p247" "ruby" create_executable "dirname1 p247" "ruby"
create_executable "dirname2 preview1" "rspec" create_executable "dirname2 preview1" "rspec"