[前][次][番号順一覧][スレッド一覧]

ruby-changes:65085

From: nagachika <ko1@a...>
Date: Sat, 30 Jan 2021 20:44:52 +0900 (JST)
Subject: [ruby-changes:65085] 99b4f20fd6 (ruby_2_7): Merge RubyGems-3.1.6 [Bug #16926]

https://git.ruby-lang.org/ruby.git/commit/?id=99b4f20fd6

From 99b4f20fd65075d2d9ee02f8c7a6b5d6a914ce31 Mon Sep 17 00:00:00 2001
From: nagachika <nagachika@r...>
Date: Sat, 30 Jan 2021 20:43:44 +0900
Subject: Merge RubyGems-3.1.6 [Bug #16926]
 https://github.com/ruby/ruby/pull/4122

---
 lib/rubygems.rb                         |  23 ++++---
 lib/rubygems/core_ext/kernel_require.rb |  60 ++++++++----------
 lib/rubygems/test_case.rb               |   1 +
 test/rubygems/test_bundled_ca.rb        |   1 +
 test/rubygems/test_kernel.rb            |  19 ++++++
 test/rubygems/test_require.rb           | 104 ++++++++++++++++++++++++++++++++
 version.h                               |   8 +--
 7 files changed, 167 insertions(+), 49 deletions(-)

diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index d8b4dc7..f8ca703 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -9,7 +9,7 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems.rb#L9
 require 'rbconfig'
 
 module Gem
-  VERSION = "3.1.5".freeze
+  VERSION = "3.1.6".freeze
 end
 
 # Must be first since it unloads the prelude from 1.9.2
@@ -659,22 +659,25 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} https://github.com/ruby/ruby/blob/trunk/lib/rubygems.rb#L659
 
     index = $LOAD_PATH.index RbConfig::CONFIG['sitelibdir']
 
-    index
+    index || 0
+  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)
-    insert_index = load_path_insert_index
+    @activated_gem_paths = activated_gem_paths + paths.size
 
-    if insert_index
-      # gem directories must come after -I and ENV['RUBYLIB']
-      $LOAD_PATH.insert(insert_index, *paths)
-    else
-      # we are probably testing in core, -I and RUBYLIB don't apply
-      $LOAD_PATH.unshift(*paths)
-    end
+    # gem directories must come after -I and ENV['RUBYLIB']
+    $LOAD_PATH.insert(Gem.load_path_insert_index, *paths)
   end
 
   @yaml_loaded = false
diff --git a/lib/rubygems/core_ext/kernel_require.rb b/lib/rubygems/core_ext/kernel_require.rb
index 60f4d18..115ae0c 100644
--- a/lib/rubygems/core_ext/kernel_require.rb
+++ b/lib/rubygems/core_ext/kernel_require.rb
@@ -39,49 +39,40 @@ module Kernel https://github.com/ruby/ruby/blob/trunk/lib/rubygems/core_ext/kernel_require.rb#L39
 
     path = path.to_path if path.respond_to? :to_path
 
-    # Ensure -I beats a default gem
-    # https://github.com/rubygems/rubygems/pull/1868
-    resolved_path = begin
-      rp = nil
-      $LOAD_PATH[0...Gem.load_path_insert_index || -1].each do |lp|
-        safe_lp = lp.dup.tap(&Gem::UNTAINT)
-        begin
-          if File.symlink? safe_lp # for backward compatibility
-            next
-          end
-        rescue SecurityError
-          RUBYGEMS_ACTIVATION_MONITOR.exit
-          raise
-        end
-
+    if spec = Gem.find_unresolved_default_spec(path)
+      # Ensure -I beats a default gem
+      resolved_path = begin
+        rp = nil
+        load_path_check_index = Gem.load_path_insert_index - Gem.activated_gem_paths
         Gem.suffixes.each do |s|
-          full_path = File.expand_path(File.join(safe_lp, "#{path}#{s}"))
-          if File.file?(full_path)
-            rp = full_path
-            break
+          $LOAD_PATH[0...load_path_check_index].each do |lp|
+            safe_lp = lp.dup.tap(&Gem::UNTAINT)
+            begin
+              if File.symlink? safe_lp # for backward compatibility
+                next
+              end
+            rescue SecurityError
+              RUBYGEMS_ACTIVATION_MONITOR.exit
+              raise
+            end
+
+            full_path = File.expand_path(File.join(safe_lp, "#{path}#{s}"))
+            if File.file?(full_path)
+              rp = full_path
+              break
+            end
           end
+          break if rp
         end
-        break if rp
-      end
-      rp
-    end
-
-    if resolved_path
-      begin
-        RUBYGEMS_ACTIVATION_MONITOR.exit
-        return gem_original_require(resolved_path)
-      rescue LoadError
-        RUBYGEMS_ACTIVATION_MONITOR.enter
+        rp
       end
-    end
 
-    if spec = Gem.find_unresolved_default_spec(path)
       begin
         Kernel.send(:gem, spec.name, Gem::Requirement.default_prerelease)
       rescue Exception
         RUBYGEMS_ACTIVATION_MONITOR.exit
         raise
-      end
+      end unless resolved_path
     end
 
     # If there are no unresolved deps, then we can use just try
@@ -157,8 +148,7 @@ module Kernel https://github.com/ruby/ruby/blob/trunk/lib/rubygems/core_ext/kernel_require.rb#L148
     RUBYGEMS_ACTIVATION_MONITOR.enter
 
     begin
-      if load_error.message.start_with?("Could not find") or
-          (load_error.message.end_with?(path) and Gem.try_activate(path))
+      if load_error.message.end_with?(path) and Gem.try_activate(path)
         require_again = true
       end
     ensure
diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb
index 8940320..c6f5f29 100644
--- a/lib/rubygems/test_case.rb
+++ b/lib/rubygems/test_case.rb
@@ -385,6 +385,7 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni https://github.com/ruby/ruby/blob/trunk/lib/rubygems/test_case.rb#L385
     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_bundled_ca.rb b/test/rubygems/test_bundled_ca.rb
index 9538d6b..4224755 100644
--- a/test/rubygems/test_bundled_ca.rb
+++ b/test/rubygems/test_bundled_ca.rb
@@ -62,5 +62,6 @@ if ENV["CI"] || ENV["TEST_SSL"] https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_bundled_ca.rb#L62
     def test_accessing_new_index
       assert_https('index.rubygems.org')
     end
+
   end
 end
diff --git a/test/rubygems/test_kernel.rb b/test/rubygems/test_kernel.rb
index b9f9b5e..daf9b57 100644
--- a/test/rubygems/test_kernel.rb
+++ b/test/rubygems/test_kernel.rb
@@ -91,6 +91,25 @@ class TestKernel < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_kernel.rb#L91
     refute $:.any? { |p| %r{a-1/bin} =~ p }
   end
 
+  def test_gem_failing_inside_require_doesnt_cause_double_exceptions
+    File.write("activate.rb", "gem('a', '= 999')\n")
+
+    require "open3"
+
+    output, _ = Open3.capture2e(
+      { "GEM_HOME" => Gem.paths.home },
+      Gem.ruby,
+      "-I",
+      File.expand_path("../../lib", __dir__),
+      "-r",
+      "./activate.rb"
+    )
+
+    load_errors = output.split("\n").select { |line| line.include?("Could not find")}
+
+    assert_equal 1, load_errors.size
+  end
+
   def test_gem_bundler
     quick_gem 'bundler', '1'
     quick_gem 'bundler', '2.a'
diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb
index aa2675a..392ede7 100644
--- a/test/rubygems/test_require.rb
+++ b/test/rubygems/test_require.rb
@@ -45,6 +45,35 @@ class TestGemRequire < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_require.rb#L45
     refute require(path), "'#{path}' was not yet required"
   end
 
+  def test_respect_loaded_features_caching_like_standard_require
+    dir = Dir.mktmpdir("test_require", @tempdir)
+
+    lp1 = File.join dir, 'foo1'
+    foo1 = File.join lp1, 'foo.rb'
+
+    FileUtils.mkdir_p lp1
+    File.open(foo1, 'w') { |f| f.write "class Object; HELLO = 'foo1' end" }
+
+    lp = $LOAD_PATH.dup
+
+    $LOAD_PATH.unshift lp1
+    assert_require 'foo'
+    assert_equal "foo1", ::Object::HELLO
+
+    lp2 = File.join dir, 'foo2'
+    foo2 = File.join lp2, 'foo.rb'
+
+    FileUtils.mkdir_p lp2
+    File.open(foo2, 'w') { |f| f.write "class Object; HELLO = 'foo2' end" }
+
+    $LOAD_PATH.unshift lp2
+    refute_require 'foo'
+    assert_equal "foo1", ::Object::HELLO
+  ensure
+    $LOAD_PATH.replace lp
+    Object.send :remove_const, :HELLO if Object.const_defined? :HELLO
+  end
+
   # Providing -I on the commandline should always beat gems
   def test_dash_i_beats_gems
     a1 = util_spec "a", "1", {"b" => "= 1"}, "lib/test_gem_require_a.rb"
@@ -120,6 +149,24 @@ class TestGemRequire < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_require.rb#L149
     Object.send :remove_const, :HELLO if Object.const_defined? :HELLO
   end
 
+  def test_dash_i_respects_default_library_extension_priority
+    skip "extensions don't quite work on jruby" if Gem.java_platform?
+
+    dash_i_ext_arg = util_install_extension_file('a')
+    dash_i_lib_arg = util_install_ruby_file('a')
+
+    lp = $LOAD_PATH.dup
+
+    begin
+      $LOAD_PATH.unshift dash_i_lib_arg
+      $LOAD_PATH.unshift dash_i_ext_arg
+      assert_require 'a'
+      assert_match(/a\.rb$/, $LOADED_FEATURES.last)
+    ensure
+      $LOAD_PATH.replace lp
+    end
+  end
+
   def test_concurrent_require
     Object.const_set :FILE_ENTERED_LATCH, Latch.new(2)
     Object.const_set :FILE_EXIT_LATCH, Latch.new(1)
@@ -364,6 +411,17 @@ class TestGemRequire < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_require.rb#L411
     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?
@@ -539,4 +597,50 @@ class TestGemRequire < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_require.rb#L597
     $VERBOSE = old_verbose
   end
 
+   (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]