summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Noria <fxn@hashref.com>2024-03-13 22:52:41 +0100
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2024-03-25 14:33:03 +0900
commitd6e9367edb940ea26a51e56b2be1032a97eea4c2 (patch)
tree6246738df535cc30d4051400f22c5c116100cbd9
parent02a4bdd6076b84da35d4a5d1aa749f1e9683ad1b (diff)
Skip Bootsnap and Zeitwerk in bundled gems warning
-rw-r--r--lib/bundled_gems.rb29
1 files changed, 21 insertions, 8 deletions
diff --git a/lib/bundled_gems.rb b/lib/bundled_gems.rb
index 55286725c0..1578b48040 100644
--- a/lib/bundled_gems.rb
+++ b/lib/bundled_gems.rb
@@ -109,12 +109,7 @@ module Gem::BUNDLED_GEMS
else
return
end
- # Warning feature is not working correctly with Bootsnap.
- # caller_locations returns:
- # lib/ruby/3.3.0+0/bundled_gems.rb:65:in `block (2 levels) in replace_require'
- # $GEM_HOME/gems/bootsnap-1.17.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'"
- # ...
- return if caller_locations(2).find {|c| c&.path.match?(/bootsnap/) }
+
return if WARNED[name]
WARNED[name] = true
if gem == true
@@ -134,11 +129,29 @@ module Gem::BUNDLED_GEMS
if defined?(Bundler)
msg += " Add #{gem} to your Gemfile or gemspec."
+
# We detect the gem name from caller_locations. We need to skip 2 frames like:
# lib/ruby/3.3.0+0/bundled_gems.rb:90:in `warning?'",
# lib/ruby/3.3.0+0/bundler/rubygems_integration.rb:247:in `block (2 levels) in replace_require'",
- location = caller_locations(3,1)[0]&.path
- if File.file?(location) && !location.start_with?(Gem::BUNDLED_GEMS::LIBDIR)
+ #
+ # Additionally, we need to skip Bootsnap and Zeitwerk if present, these
+ # gems decorate Kernel#require, so they are not really the ones issuing
+ # the require call users should be warned about. Those are upwards.
+ frames_to_skip = 2
+ location = nil
+ Thread.each_caller_location do |cl|
+ if frames_to_skip >= 1
+ frames_to_skip -= 1
+ next
+ end
+
+ unless cl.path.match?(/bootsnap|zeitwerk/)
+ location = cl.path
+ break
+ end
+ end
+
+ if location && File.file?(location) && !location.start_with?(Gem::BUNDLED_GEMS::LIBDIR)
caller_gem = nil
Gem.path.each do |path|
if location =~ %r{#{path}/gems/([\w\-\.]+)}