summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rodríguez <deivid.rodriguez@riseup.net>2020-05-19 14:00:00 +0200
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2020-06-05 07:32:42 +0900
commita18e81d797135de6e143a600e4f4d2b00ab23bf9 (patch)
treeaaf319c30c0b65fa0f2718b445cc7efe33736210
parent8c8364c84e53303baf3828fd5266cb5aec54c582 (diff)
[rubygems/rubygems] Fix performance regression in `require`
Our check for `-I` paths should not go through all activated gems. https://github.com/rubygems/rubygems/commit/00d98eb8a3
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3184
-rw-r--r--lib/rubygems.rb10
-rw-r--r--lib/rubygems/core_ext/kernel_require.rb2
-rw-r--r--lib/rubygems/test_case.rb1
-rw-r--r--test/rubygems/test_require.rb11
4 files changed, 23 insertions, 1 deletions
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index ef744c40ba..9bf1c63a3e 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -594,9 +594,19 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
end
##
+ # The number of paths in the `$LOAD_PATH` from activated gems. Used to
+ # prioritize `-I` and `ENV['RUBYLIB`]` entries during `require`.
+
+ def self.activated_gem_paths
+ @activated_gem_paths ||= 0
+ end
+
+ ##
# Add a list of paths to the $LOAD_PATH at the proper place.
def self.add_to_load_path(*paths)
+ @activated_gem_paths = activated_gem_paths + paths.size
+
insert_index = load_path_insert_index
if insert_index
diff --git a/lib/rubygems/core_ext/kernel_require.rb b/lib/rubygems/core_ext/kernel_require.rb
index ed24111bd5..7625ce1bee 100644
--- a/lib/rubygems/core_ext/kernel_require.rb
+++ b/lib/rubygems/core_ext/kernel_require.rb
@@ -47,7 +47,7 @@ module Kernel
load_path_insert_index = Gem.load_path_insert_index
break unless load_path_insert_index
- $LOAD_PATH[0...load_path_insert_index].each do |lp|
+ $LOAD_PATH[0...load_path_insert_index - Gem.activated_gem_paths].each do |lp|
safe_lp = lp.dup.tap(&Gem::UNTAINT)
begin
if File.symlink? safe_lp # for backward compatibility
diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb
index a63c99fd8e..9b83f03d31 100644
--- a/lib/rubygems/test_case.rb
+++ b/lib/rubygems/test_case.rb
@@ -388,6 +388,7 @@ class Gem::TestCase < Minitest::Test
Gem::Security.reset
Gem.loaded_specs.clear
+ Gem.instance_variable_set(:@activated_gem_paths, 0)
Gem.clear_default_specs
Bundler.reset!
diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb
index 1c86a4ed66..c6be26a658 100644
--- a/test/rubygems/test_require.rb
+++ b/test/rubygems/test_require.rb
@@ -382,6 +382,17 @@ class TestGemRequire < Gem::TestCase
assert_equal 0, times_called
end
+ def test_second_gem_require_does_not_resolve_path_manually_before_going_through_standard_require
+ a1 = util_spec "a", "1", nil, "lib/test_gem_require_a.rb"
+ install_gem a1
+
+ assert_require "test_gem_require_a"
+
+ stub(:gem_original_require, ->(path) { assert_equal "test_gem_require_a", path }) do
+ require "test_gem_require_a"
+ end
+ end
+
def test_realworld_default_gem
testing_ruby_repo = !ENV["GEM_COMMAND"].nil?
skip "this test can't work under ruby-core setup" if testing_ruby_repo || java_platform?