-
-
Save drbrain/3ea0befdadc187cf88dc to your computer and use it in GitHub Desktop.
requirable_files implementation for rubygems/rubygems#971
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'benchmark/ips' | |
Gem::Specification.each do |spec| | |
begin | |
spec.activate | |
rescue Gem::LoadError | |
end | |
end | |
def old_find_files_from_load_path glob # :nodoc: | |
$LOAD_PATH.map { |load_path| | |
Dir["#{File.expand_path glob, load_path}#{Gem.suffix_pattern}"] | |
}.flatten.select { |file| File.file? file.untaint } | |
end | |
def find_files_from_requirable_files glob | |
files = [] | |
pattern = "#{glob}#{Gem.suffix_pattern}" | |
Gem.loaded_specs.each_value do |spec| | |
files.concat spec.requirable_files.select { |file| | |
File.fnmatch(pattern, file, File::FNM_EXTGLOB) | |
} | |
end | |
files | |
end | |
search = "minitest/*_plugin" | |
p old_find_files_from_load_path search | |
p find_files_from_requirable_files search | |
Benchmark.ips do |x| | |
x.report('old') { old_find_files_from_load_path search } | |
x.report('requirable_files') { find_files_from_requirable_files search } | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ ruby -Ilib bin/gem pristine --all | |
[…] | |
$ ruby -Ilib bm.rb | |
["/usr/local/lib/ruby/gems/2.1.0/gems/minitest-5.3.5/lib/minitest/pride_plugin.rb"] | |
["minitest/pride_plugin.rb"] | |
Calculating ------------------------------------- | |
old 29 i/100ms | |
requirable_files 12 i/100ms | |
------------------------------------------------- | |
old 293.3 (±2.4%) i/s - 1479 in 5.046004s | |
requirable_files 124.7 (±1.6%) i/s - 624 in 5.004588s |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb | |
index 18fb3b3..29d9af1 100644 | |
--- a/lib/rubygems/installer.rb | |
+++ b/lib/rubygems/installer.rb | |
@@ -10,6 +10,7 @@ require 'rubygems/package' | |
require 'rubygems/ext' | |
require 'rubygems/user_interaction' | |
require 'fileutils' | |
+require 'pathname' | |
## | |
# The installer installs the files contained in the .gem into the Gem.home. | |
@@ -246,6 +247,7 @@ class Gem::Installer | |
generate_bin | |
write_spec | |
write_cache_file | |
+ write_requirable_files | |
end | |
say spec.post_install_message unless spec.post_install_message.nil? | |
@@ -806,5 +808,23 @@ TEXT | |
FileUtils.cp @gem, cache_file unless File.exist? cache_file | |
end | |
+ def write_requirable_files | |
+ files = [] | |
+ | |
+ spec.full_require_paths.each do |dir| | |
+ dir = Pathname dir | |
+ next unless dir.directory? | |
+ | |
+ dir.find do |entry| | |
+ files << entry.relative_path_from(dir).to_s unless entry.directory? | |
+ end | |
+ | |
+ end | |
+ | |
+ File.open spec.requirable_files_file, 'w' do |io| | |
+ io.write files.join "\n" | |
+ end | |
+ end | |
+ | |
end | |
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb | |
index 8f4213c..dd27cdf 100644 | |
--- a/lib/rubygems/specification.rb | |
+++ b/lib/rubygems/specification.rb | |
@@ -2123,6 +2123,15 @@ class Gem::Specification < Gem::BasicSpecification | |
self.require_paths = Array(path) | |
end | |
+ def requirable_files_file # :nodoc: | |
+ File.join spec_dir, "#{full_name}.requirable_files" | |
+ end | |
+ | |
+ def requirable_files # :nodoc: | |
+ return [] unless File.exist? requirable_files_file | |
+ File.read(requirable_files_file).split "\n" | |
+ end | |
+ | |
## | |
# Set requirements to +req+, ensuring it is an array. Don't | |
# use this, push onto the array instead. | |
diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb | |
index f03285a..e457cf2 100644 | |
--- a/test/rubygems/test_gem_commands_install_command.rb | |
+++ b/test/rubygems/test_gem_commands_install_command.rb | |
@@ -461,6 +461,8 @@ ERROR: Possible alternatives: non_existent_with_hint | |
a2_gemspec = File.join(gemdir, "a-2.gemspec") | |
a1_gemspec = File.join(gemdir, "a-1.gemspec") | |
+ a1_requirable_files = File.join gemdir, "a-1.requirable_files" | |
+ | |
FileUtils.rm_rf a1_gemspec | |
FileUtils.rm_rf a2_gemspec | |
@@ -480,7 +482,7 @@ ERROR: Possible alternatives: non_existent_with_hint | |
fin = Dir["#{gemdir}/*"] | |
- assert_equal [a1_gemspec], fin - start | |
+ assert_equal [a1_gemspec, a1_requirable_files], fin - start | |
end | |
def test_execute_two | |
diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb | |
index 33b6080..7c98060 100644 | |
--- a/test/rubygems/test_gem_installer.rb | |
+++ b/test/rubygems/test_gem_installer.rb | |
@@ -1474,6 +1474,28 @@ gem 'other', version | |
assert_equal ['bin/executable'], default_spec.files | |
end | |
+ def test_write_requirable_files | |
+ spec = quick_gem 'a' do |s| | |
+ util_make_exec s | |
+ s.files = %w[lib/a.rb lib/a/b.rb lib/a.txt] | |
+ end | |
+ | |
+ util_build_gem spec | |
+ installer = util_installer spec, @gemhome | |
+ | |
+ installer.extract_files | |
+ | |
+ refute_path_exists spec.requirable_files_file | |
+ | |
+ installer.write_requirable_files | |
+ | |
+ assert_path_exists spec.requirable_files_file | |
+ | |
+ expected = %w[a/b.rb a.rb a.txt].join "\n" | |
+ | |
+ assert_equal expected, File.read(spec.requirable_files_file) | |
+ end | |
+ | |
def old_ruby_required | |
spec = util_spec 'old_ruby_required', '1' do |s| | |
s.required_ruby_version = '= 1.4.6' | |
diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb | |
index 723a4be..718f3cf 100644 | |
--- a/test/rubygems/test_gem_specification.rb | |
+++ b/test/rubygems/test_gem_specification.rb | |
@@ -2974,6 +2974,25 @@ end | |
assert_equal ["default-2.0.0.0"], Gem::Specification.map(&:full_name) | |
end | |
+ def test_requirables_files | |
+ a = quick_gem 'a' | |
+ | |
+ expected = %w[a.rb a/b.rb] | |
+ | |
+ open a.requirable_files_file, 'w' do |io| | |
+ io.write expected.join "\n" | |
+ end | |
+ | |
+ assert_equal expected, a.requirable_files | |
+ end | |
+ | |
+ def test_requirables_files_file | |
+ a = quick_gem 'a' | |
+ | |
+ assert_equal File.join(a.spec_dir, 'a-2.requirable_files'), | |
+ a.requirable_files_file | |
+ end | |
+ | |
def util_setup_deps | |
@gem = util_spec "awesome", "1.0" do |awesome| | |
awesome.add_runtime_dependency "bonobo", [] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment