Skip to content

Commit

Permalink
Optimize rehash times by not running the rehash.rb script if discover…
Browse files Browse the repository at this point in the history
…ed Gemfiles haven't changed

This is achieved by comparing the modification times of Gemfile manifests against their Gemfiles.
  • Loading branch information
carsomyr committed May 30, 2013
1 parent e529cf7 commit 9003c5c
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 37 deletions.
75 changes: 75 additions & 0 deletions etc/rbenv.d/bundler/includes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,81 @@ function find_bundled_executable {
return -- 1
}

# Gets whether the heavyweight, script-based rehash operation is needed by comparing the modification times of Gemfile
# manifests against their Gemfiles.
function needs_rehash_script {

local -- manifest_dir=$1

if [[ ! -f "${manifest_dir}/manifest.txt" ]]; then
return -- 0
fi

local -- acc=$PWD

while [[ "$acc" != "$(dirname -- "$acc")" ]]; do

if [[ -f "${acc}/Gemfile" ]]; then
return -- 0
fi

acc=$(dirname -- "$acc")
done

local -- manifest_entries=$(cat -- "${manifest_dir}/manifest.txt")
local -- ifs_save=$IFS

IFS=$'\n'
manifest_entries=($manifest_entries)
IFS=$ifs_save

for (( i = 0; i < ${#manifest_entries[@]}; i += 2 )); do

if [[ "${manifest_dir}/${manifest_entries[$(($i + 1))]}" -ot "${manifest_entries[$i]}" ]]; then
return -- 0
fi
done

return -- 1
}

# Generates shims for the executables listed in Gemfile manifests.
function make_gemfile_shims {

local -- manifest_dir=$1
local -- manifest_entries=$(cat -- "${manifest_dir}/manifest.txt")

ifs_save=$IFS

IFS=$'\n'
manifest_entries=($manifest_entries)
IFS=$ifs_save

for (( i = 0; i < ${#manifest_entries[@]}; i += 2 )); do

gemspec_entries=$(cat -- "${manifest_dir}/${manifest_entries[$(($i + 1))]}")

ifs_save=$IFS

IFS=$'\n'
gemspec_entries=($gemspec_entries)
IFS=$ifs_save

for (( j = 0; j < ${#gemspec_entries[@]}; j += 2 )); do

gem_executable="${gemspec_entries[$(($j + 1))]}/${gemspec_entries[$j]}"

if [[ ! -f "$gem_executable" ]]; then
continue
fi

cd -- "$SHIM_PATH" && make_shims "$gem_executable"; cd -- "$PWD"
done
done

return -- 0
}

# The plugins root directory.
plugin_root_dir=$(dirname -- "$(dirname -- "$(dirname -- "$(dirname -- "${BASH_SOURCE[0]}")")")")

Expand Down
7 changes: 4 additions & 3 deletions etc/rbenv.d/bundler/rehash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,6 @@ def self.rbenv_version(dir = Pathname.new("."))
# @param [Hash] manifest_map the `Hash` from Bundler-controlled directories to gemspec manifests.
# @param [Pathname] out_dir the output directory.
def self.rehash(ruby_profile_map, manifest_map, out_dir = Pathname.new("."))
raise "The output directory does not exist" if !out_dir.directory?

Pathname.new("manifest.txt").expand_path(out_dir).open("wb") do |f|
manifest_map.each do |gemfile, manifest_file|
next if !gemfile.file?
Expand Down Expand Up @@ -411,7 +409,10 @@ def self.ruby_scope
end

opt_spec.on("-o", "--out-dir OUT_DIR", "output metadata files to this directory") do |out_dir|
opts[:out_dir] = Pathname.new(out_dir)
p = Pathname.new(out_dir)
p.mkpath

opts[:out_dir] = p
end
end.parse(ARGV)

Expand Down
39 changes: 5 additions & 34 deletions etc/rbenv.d/rehash/bundler.bash
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,10 @@ if [[ -n "$plugin_disabled" ]]; then
fi

manifest_dir="${plugin_root_dir}/share/rbenv/bundler"
rehash_rb_script="${plugin_root_dir}/etc/rbenv.d/bundler/rehash.rb"
rehash_script="${plugin_root_dir}/etc/rbenv.d/bundler/rehash.rb"

mkdir -p -- "$manifest_dir"
touch -- "${manifest_dir}/manifest.txt"

"$rehash_rb_script" --refresh --verbose --out-dir "$manifest_dir" -- "$PWD" || true

manifest_entries=$(cat -- "${manifest_dir}/manifest.txt")

ifs_save=$IFS

IFS=$'\n'
manifest_entries=($manifest_entries)
IFS=$ifs_save

for (( i = 0; i < ${#manifest_entries[@]}; i += 2 )); do

gemspec_entries=$(cat -- "${manifest_dir}/${manifest_entries[$(($i + 1))]}")

ifs_save=$IFS

IFS=$'\n'
gemspec_entries=($gemspec_entries)
IFS=$ifs_save

for (( j = 0; j < ${#gemspec_entries[@]}; j += 2 )); do

gem_executable="${gemspec_entries[$(($j + 1))]}/${gemspec_entries[$j]}"

if [[ ! -f "$gem_executable" ]]; then
continue
fi
if { needs_rehash_script "$manifest_dir"; } then
"$rehash_script" --refresh --verbose --out-dir "$manifest_dir" -- "$PWD" || true
fi

cd -- "$SHIM_PATH" && make_shims "$gem_executable"; cd -- "$PWD"
done
done
make_gemfile_shims "$manifest_dir"

0 comments on commit 9003c5c

Please sign in to comment.