diff --git a/lib/rubygems/core_ext/kernel_require.rb b/lib/rubygems/core_ext/kernel_require.rb index 8c85ef79fc..5986e356bc 100755 --- a/lib/rubygems/core_ext/kernel_require.rb +++ b/lib/rubygems/core_ext/kernel_require.rb @@ -36,6 +36,26 @@ module Kernel path = path.to_path if path.respond_to? :to_path + resolved_path = begin + rp = nil + $LOAD_PATH[0...Gem.load_path_insert_index || -1].each do |lp| + Gem.suffixes.each do |s| + full_path = File.expand_path(File.join(lp, "#{path}#{s}").untaint) + if File.file?(full_path) + rp = full_path + break + end + end + break if rp + end + rp + end + + if resolved_path + RUBYGEMS_ACTIVATION_MONITOR.exit + return gem_original_require(resolved_path) + end + if spec = Gem.find_unresolved_default_spec(path) begin Kernel.send(:gem, spec.name, "#{Gem::Requirement.default}.a") diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb index b6bb7ca93e..4b43df539d 100644 --- a/lib/rubygems/test_case.rb +++ b/lib/rubygems/test_case.rb @@ -739,6 +739,7 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni spec.files = files lib_dir = File.join(@tempdir, "default_gems", "lib") + lib_dir.instance_variable_set(:@gem_prelude_index, lib_dir) $LOAD_PATH.unshift(lib_dir) files.each do |file| rb_path = File.join(lib_dir, file) diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb index 330b56b43d..a0c272ed66 100644 --- a/test/rubygems/test_require.rb +++ b/test/rubygems/test_require.rb @@ -87,6 +87,39 @@ class TestGemRequire < Gem::TestCase end end + # Providing -I on the commandline should always beat gems + def test_dash_i_beats_default_gems + a1 = new_default_spec "a", "1", {"b" => "= 1"}, "test_gem_require_a.rb" + b1 = new_default_spec "b", "1", {"c" => "> 0"}, "b/c.rb" + c1 = new_default_spec "c", "1", nil, "c/c.rb" + c2 = new_default_spec "c", "2", nil, "c/c.rb" + + install_default_specs c1, c2, b1, a1 + + dir = Dir.mktmpdir("test_require", @tempdir) + dash_i_arg = File.join dir, 'lib' + + c_rb = File.join dash_i_arg, 'c', 'c.rb' + + FileUtils.mkdir_p File.dirname c_rb + File.open(c_rb, 'w') { |f| f.write "class Object; HELLO = 'world' end" } + + assert_require 'test_gem_require_a' + + lp = $LOAD_PATH.dup + + # Pretend to provide a commandline argument that overrides a file in gem b + $LOAD_PATH.unshift dash_i_arg + + assert_require 'b/c' + assert_require 'c/c' # this should be required from -I + assert_equal "world", ::Object::HELLO + assert_equal %w(a-1 b-1), loaded_spec_names + ensure + $LOAD_PATH.replace lp + Object.send :remove_const, :HELLO if Object.const_defined? :HELLO + end + def test_concurrent_require Object.const_set :FILE_ENTERED_LATCH, Latch.new(2) Object.const_set :FILE_EXIT_LATCH, Latch.new(1)