Skip to content

Commit b394438

Browse files
Fix require issue with file extension priority
If `require "a"` is run when two folders have been specified in the -I option including a "a.rb" file and a "a.so" file respectively, the ruby spec says that the ".rb" file should always be preferred. However, the logic we added in 6b81076d9 to make the -I option always beat default gems does not respect this spec, creating a difference from the original ruby-core's require. [the ruby spec says]: https://github.com/ruby/spec/blob/d80a6e2b221d4f17a8cadcac75ef950c59cba901/core/kernel/shared/require.rb#L234-L246
1 parent 912d141 commit b394438

File tree

2 files changed

+74
-16
lines changed

2 files changed

+74
-16
lines changed

lib/rubygems/core_ext/kernel_require.rb

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,18 @@ def require(path)
4343
# https://github.com/rubygems/rubygems/pull/1868
4444
resolved_path = begin
4545
rp = nil
46-
$LOAD_PATH[0...Gem.load_path_insert_index || -1].each do |lp|
47-
safe_lp = lp.dup.tap(&Gem::UNTAINT)
48-
begin
49-
if File.symlink? safe_lp # for backward compatibility
50-
next
46+
Gem.suffixes.each do |s|
47+
$LOAD_PATH[0...Gem.load_path_insert_index || -1].each do |lp|
48+
safe_lp = lp.dup.tap(&Gem::UNTAINT)
49+
begin
50+
if File.symlink? safe_lp # for backward compatibility
51+
next
52+
end
53+
rescue SecurityError
54+
RUBYGEMS_ACTIVATION_MONITOR.exit
55+
raise
5156
end
52-
rescue SecurityError
53-
RUBYGEMS_ACTIVATION_MONITOR.exit
54-
raise
55-
end
5657

57-
Gem.suffixes.each do |s|
5858
full_path = File.expand_path(File.join(safe_lp, "#{path}#{s}"))
5959
if File.file?(full_path)
6060
rp = full_path
@@ -67,12 +67,8 @@ def require(path)
6767
end
6868

6969
if resolved_path
70-
begin
71-
RUBYGEMS_ACTIVATION_MONITOR.exit
72-
return gem_original_require(resolved_path)
73-
rescue LoadError
74-
RUBYGEMS_ACTIVATION_MONITOR.enter
75-
end
70+
RUBYGEMS_ACTIVATION_MONITOR.exit
71+
return gem_original_require(resolved_path)
7672
end
7773

7874
if spec = Gem.find_unresolved_default_spec(path)

test/rubygems/test_require.rb

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,24 @@ def test_dash_i_beats_default_gems
120120
Object.send :remove_const, :HELLO if Object.const_defined? :HELLO
121121
end
122122

123+
def test_dash_i_respects_default_library_extension_priority
124+
skip "extensions don't quite work on jruby" if Gem.java_platform?
125+
126+
dash_i_ext_arg = util_install_extension_file('a')
127+
dash_i_lib_arg = util_install_ruby_file('a')
128+
129+
lp = $LOAD_PATH.dup
130+
131+
begin
132+
$LOAD_PATH.unshift dash_i_lib_arg
133+
$LOAD_PATH.unshift dash_i_ext_arg
134+
assert_require 'a'
135+
assert_match(/a\.rb$/, $LOADED_FEATURES.last)
136+
ensure
137+
$LOAD_PATH.replace lp
138+
end
139+
end
140+
123141
def test_concurrent_require
124142
Object.const_set :FILE_ENTERED_LATCH, Latch.new(2)
125143
Object.const_set :FILE_EXIT_LATCH, Latch.new(1)
@@ -541,4 +559,48 @@ def silence_warnings
541559
$VERBOSE = old_verbose
542560
end
543561

562+
def util_install_extension_file(name)
563+
spec = quick_gem name
564+
util_build_gem spec
565+
566+
spec.extensions << "extconf.rb"
567+
write_file File.join(@tempdir, "extconf.rb") do |io|
568+
io.write <<-RUBY
569+
require "mkmf"
570+
create_makefile("#{name}")
571+
RUBY
572+
end
573+
574+
write_file File.join(@tempdir, "#{name}.c") do |io|
575+
io.write <<-C
576+
#include <ruby.h>
577+
void Init_#{name}() { }
578+
C
579+
end
580+
581+
spec.files += ["extconf.rb", "#{name}.c"]
582+
583+
so = File.join(spec.gem_dir, "#{name}.#{RbConfig::CONFIG["DLEXT"]}")
584+
refute_path_exists so
585+
586+
path = Gem::Package.build spec
587+
installer = Gem::Installer.at path
588+
installer.install
589+
assert_path_exists so
590+
591+
spec.gem_dir
592+
end
593+
594+
def util_install_ruby_file(name)
595+
dir_lib = Dir.mktmpdir("test_require_lib", @tempdir)
596+
dash_i_lib_arg = File.join dir_lib
597+
598+
a_rb = File.join dash_i_lib_arg, "#{name}.rb"
599+
600+
FileUtils.mkdir_p File.dirname a_rb
601+
File.open(a_rb, 'w') { |f| f.write "# #{name}.rb" }
602+
603+
dash_i_lib_arg
604+
end
605+
544606
end

0 commit comments

Comments
 (0)