Skip to content

Commit 6b81076

Browse files
bundlerbotdeivid-rodriguezsegiddins
committed
Merge #1868
1868: [Require] Ensure -I beats a default gem r=hsbt a=segiddins # Description: Fixes #1866. Definitely a WIP, just wanted to let everyone have a look at this. # Tasks: - [ ] Describe the problem / feature - [ ] Write tests - [ ] Write code to solve the problem - [ ] Get code review from coworkers / friends I will abide by the [code of conduct](https://github.com/rubygems/rubygems/blob/master/CODE_OF_CONDUCT.md). Co-authored-by: David Rodríguez <deivid.rodriguez@riseup.net> Co-authored-by: Samuel Giddins <segiddins@segiddins.me>
2 parents ca12905 + fc3f722 commit 6b81076

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

lib/rubygems/core_ext/kernel_require.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,26 @@ def require(path)
3636

3737
path = path.to_path if path.respond_to? :to_path
3838

39+
resolved_path = begin
40+
rp = nil
41+
$LOAD_PATH[0...Gem.load_path_insert_index || -1].each do |lp|
42+
Gem.suffixes.each do |s|
43+
full_path = File.expand_path(File.join(lp, "#{path}#{s}"))
44+
if File.file?(full_path)
45+
rp = full_path
46+
break
47+
end
48+
end
49+
break if rp
50+
end
51+
rp
52+
end
53+
54+
if resolved_path
55+
RUBYGEMS_ACTIVATION_MONITOR.exit
56+
return gem_original_require(resolved_path)
57+
end
58+
3959
if spec = Gem.find_unresolved_default_spec(path)
4060
begin
4161
Kernel.send(:gem, spec.name, "#{Gem::Requirement.default}.a")

lib/rubygems/test_case.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,7 @@ def new_default_spec(name, version, deps = nil, *files)
739739
spec.files = files
740740

741741
lib_dir = File.join(@tempdir, "default_gems", "lib")
742+
lib_dir.instance_variable_set(:@gem_prelude_index, lib_dir)
742743
$LOAD_PATH.unshift(lib_dir)
743744
files.each do |file|
744745
rb_path = File.join(lib_dir, file)

test/rubygems/test_require.rb

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def test_dash_i_beats_gems
7070
assert_require 'test_gem_require_a'
7171
assert_require 'b/c' # this should be required from -I
7272
assert_equal "world", ::Object::HELLO
73+
assert_equal %w(a-1 b-1), loaded_spec_names
7374
ensure
7475
$LOAD_PATH.replace lp
7576
Object.send :remove_const, :HELLO if Object.const_defined? :HELLO
@@ -86,6 +87,39 @@ def create_sync_thread
8687
end
8788
end
8889

90+
# Providing -I on the commandline should always beat gems
91+
def test_dash_i_beats_default_gems
92+
a1 = new_default_spec "a", "1", {"b" => "= 1"}, "test_gem_require_a.rb"
93+
b1 = new_default_spec "b", "1", {"c" => "> 0"}, "b/c.rb"
94+
c1 = new_default_spec "c", "1", nil, "c/c.rb"
95+
c2 = new_default_spec "c", "2", nil, "c/c.rb"
96+
97+
install_default_specs c1, c2, b1, a1
98+
99+
dir = Dir.mktmpdir("test_require", @tempdir)
100+
dash_i_arg = File.join dir, 'lib'
101+
102+
c_rb = File.join dash_i_arg, 'c', 'c.rb'
103+
104+
FileUtils.mkdir_p File.dirname c_rb
105+
File.open(c_rb, 'w') { |f| f.write "class Object; HELLO = 'world' end" }
106+
107+
assert_require 'test_gem_require_a'
108+
109+
lp = $LOAD_PATH.dup
110+
111+
# Pretend to provide a commandline argument that overrides a file in gem b
112+
$LOAD_PATH.unshift dash_i_arg
113+
114+
assert_require 'b/c'
115+
assert_require 'c/c' # this should be required from -I
116+
assert_equal "world", ::Object::HELLO
117+
assert_equal %w(a-1 b-1), loaded_spec_names
118+
ensure
119+
$LOAD_PATH.replace lp
120+
Object.send :remove_const, :HELLO if Object.const_defined? :HELLO
121+
end
122+
89123
def test_concurrent_require
90124
Object.const_set :FILE_ENTERED_LATCH, Latch.new(2)
91125
Object.const_set :FILE_EXIT_LATCH, Latch.new(1)
@@ -176,7 +210,7 @@ def test_activate_via_require_respects_loaded_files
176210

177211
install_specs b1, b2, a1
178212

179-
require 'test_gem_require_a'
213+
assert_require 'test_gem_require_a'
180214
assert_equal unresolved_names, ["b (>= 1)"]
181215

182216
refute require('benchmark'), "benchmark should have already been loaded"

0 commit comments

Comments
 (0)