Skip to content

Commit 6af219c

Browse files
authored
Merge pull request #9390 from ruby/keep-lib-ext-and-warn
Revert `DEFAULT_INSTALL_EXTENSION_IN_LIB` and warn `require_relative` with C ext
2 parents 6fd37f4 + 1198c24 commit 6af219c

File tree

4 files changed

+87
-4
lines changed

4 files changed

+87
-4
lines changed

lib/rubygems/config_file.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class Gem::ConfigFile
4747
DEFAULT_CONCURRENT_DOWNLOADS = 8
4848
DEFAULT_CERT_EXPIRATION_LENGTH_DAYS = 365
4949
DEFAULT_IPV4_FALLBACK_ENABLED = false
50-
DEFAULT_INSTALL_EXTENSION_IN_LIB = false
50+
DEFAULT_INSTALL_EXTENSION_IN_LIB = true
5151
DEFAULT_GLOBAL_GEM_CACHE = false
5252
DEFAULT_USE_PSYCH = false
5353

lib/rubygems/specification_policy.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ def validate_extensions # :nodoc:
476476

477477
validate_rake_extensions(builder)
478478
validate_rust_extensions(builder)
479+
validate_extension_require_relative
479480
end
480481

481482
def validate_rust_extensions(builder) # :nodoc:
@@ -496,6 +497,33 @@ def validate_rake_extensions(builder) # :nodoc:
496497
WARNING
497498
end
498499

500+
def validate_extension_require_relative # :nodoc:
501+
return unless @specification.extensions.any?
502+
503+
require_paths = @specification.require_paths
504+
505+
@specification.files.each do |rb_file|
506+
next unless rb_file.end_with?(".rb")
507+
next unless require_paths.any? {|rp| rb_file.start_with?("#{rp}/") }
508+
next unless File.file?(rb_file)
509+
510+
File.foreach(rb_file).with_index(1) do |line, lineno|
511+
next unless line =~ /^\s*require_relative\s+["']([^"']+)["']/
512+
513+
required_path = Regexp.last_match(1)
514+
resolved = File.join(File.dirname(rb_file), required_path)
515+
516+
next if @specification.files.any? {|f| f == "#{resolved}.rb" || f == resolved }
517+
518+
warning <<~WARNING
519+
#{rb_file}:#{lineno} uses `require_relative "#{required_path}"` to load a compiled extension.
520+
This will break in RubyGems 4.2, which will stop copying compiled extensions into the gem's lib directory.
521+
Use `require` instead of `require_relative` to load compiled extensions.
522+
WARNING
523+
end
524+
end
525+
end
526+
499527
def validate_unique_links
500528
links = @specification.metadata.slice(*METADATA_LINK_KEYS)
501529
grouped = links.group_by {|_key, uri| uri }

test/rubygems/test_gem_config_file.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def test_initialize
4343
assert_equal [@gem_repo], Gem.sources
4444
assert_equal 365, @cfg.cert_expiration_length_days
4545
assert_equal false, @cfg.ipv4_fallback_enabled
46-
assert_equal false, @cfg.install_extension_in_lib
46+
assert_equal true, @cfg.install_extension_in_lib
4747

4848
File.open @temp_conf, "w" do |fp|
4949
fp.puts ":backtrace: true"
@@ -59,7 +59,7 @@ def test_initialize
5959
fp.puts ":ssl_verify_mode: 0"
6060
fp.puts ":ssl_ca_cert: /etc/ssl/certs"
6161
fp.puts ":cert_expiration_length_days: 28"
62-
fp.puts ":install_extension_in_lib: true"
62+
fp.puts ":install_extension_in_lib: false"
6363
fp.puts ":ipv4_fallback_enabled: true"
6464
end
6565

@@ -75,7 +75,7 @@ def test_initialize
7575
assert_equal 0, @cfg.ssl_verify_mode
7676
assert_equal "/etc/ssl/certs", @cfg.ssl_ca_cert
7777
assert_equal 28, @cfg.cert_expiration_length_days
78-
assert_equal true, @cfg.install_extension_in_lib
78+
assert_equal false, @cfg.install_extension_in_lib
7979
assert_equal true, @cfg.ipv4_fallback_enabled
8080
end
8181

test/rubygems/test_gem_specification.rb

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2887,6 +2887,61 @@ def test_validate_rust_extension_have_no_missing_cargo_toml_error
28872887
end
28882888
end
28892889

2890+
def test_validate_extension_require_relative_warning
2891+
util_setup_validate
2892+
2893+
Dir.chdir @tempdir do
2894+
@a1.extensions = ["ext/a/extconf.rb"]
2895+
@a1.files = %w[lib/code.rb lib/a.rb ext/a/extconf.rb]
2896+
2897+
File.write File.join("lib", "a.rb"), 'require_relative "a/a"'
2898+
2899+
use_ui @ui do
2900+
@a1.validate
2901+
end
2902+
2903+
assert_match(%r{require_relative "a/a"}, @ui.error)
2904+
assert_match(/will break in RubyGems 4\.2/, @ui.error)
2905+
assert_match(/Use `require` instead of `require_relative`/, @ui.error)
2906+
end
2907+
end
2908+
2909+
def test_validate_extension_require_relative_no_warning_when_rb_exists
2910+
util_setup_validate
2911+
2912+
Dir.chdir @tempdir do
2913+
@a1.extensions = ["ext/a/extconf.rb"]
2914+
@a1.files = %w[lib/code.rb lib/a.rb lib/a/a.rb ext/a/extconf.rb]
2915+
2916+
FileUtils.mkdir_p File.join("lib", "a")
2917+
File.write File.join("lib", "a.rb"), 'require_relative "a/a"'
2918+
File.write File.join("lib", "a", "a.rb"), ""
2919+
2920+
use_ui @ui do
2921+
@a1.validate
2922+
end
2923+
2924+
refute_match(/require_relative/, @ui.error)
2925+
end
2926+
end
2927+
2928+
def test_validate_extension_require_relative_no_warning_without_extensions
2929+
util_setup_validate
2930+
2931+
Dir.chdir @tempdir do
2932+
@a1.extensions = []
2933+
@a1.files = %w[lib/code.rb lib/a.rb]
2934+
2935+
File.write File.join("lib", "a.rb"), 'require_relative "a/a"'
2936+
2937+
use_ui @ui do
2938+
@a1.validate
2939+
end
2940+
2941+
refute_match(/require_relative/, @ui.error)
2942+
end
2943+
end
2944+
28902945
def test_validate_description
28912946
util_setup_validate
28922947

0 commit comments

Comments
 (0)