diff --git a/lib/rubygems.rb b/lib/rubygems.rb index f773b44f87026c..d1381cbb839838 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -1337,6 +1337,17 @@ def default_gem_load_paths rescue LoadError end +# TruffleRuby >= 24 defines REUSE_AS_BINARY_ON_TRUFFLERUBY in defaults/truffleruby. +# However, TruffleRuby < 24 defines REUSE_AS_BINARY_ON_TRUFFLERUBY directly in its copy +# of lib/rubygems/platform.rb, so it is not defined if RubyGems is updated (gem update --system). +# Instead, we define it here in that case, similar to bundler/lib/bundler/rubygems_ext.rb. +# We must define it here and not in platform.rb because platform.rb is loaded before defaults/truffleruby. +class Gem::Platform + if RUBY_ENGINE == "truffleruby" && !defined?(REUSE_AS_BINARY_ON_TRUFFLERUBY) + REUSE_AS_BINARY_ON_TRUFFLERUBY = %w[libv8 libv8-node sorbet-static].freeze + end +end + ## # Loads the default specs. Gem::Specification.load_defaults diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb index 5c5abdc2e2bda6..3513db13f418e7 100644 --- a/lib/rubygems/platform.rb +++ b/lib/rubygems/platform.rb @@ -43,10 +43,20 @@ def self.match_spec?(spec) match_gem?(spec.platform, spec.name) end - def self.match_gem?(platform, gem_name) - # NOTE: this method might be redefined by Ruby implementations to - # customize behavior per RUBY_ENGINE, gem_name or other criteria. - match_platforms?(platform, Gem.platforms) + if RUBY_ENGINE == "truffleruby" + def self.match_gem?(platform, gem_name) + raise "Not a string: #{gem_name.inspect}" unless String === gem_name + + if REUSE_AS_BINARY_ON_TRUFFLERUBY.include?(gem_name) + match_platforms?(platform, [Gem::Platform::RUBY, Gem::Platform.local]) + else + match_platforms?(platform, Gem.platforms) + end + end + else + def self.match_gem?(platform, gem_name) + match_platforms?(platform, Gem.platforms) + end end def self.sort_priority(platform)