Description
Describe the problem as clearly as you can
When passing a string to Gem::Platform.match
, the behavior of the method is the same as before 1b9f7f5 introduced a fix for musl platforms.
Although Gem::Platform#=~
properly coerces the other
argument, the #match
method, when passed a String
, will instead invoke String#=~
.
The interesting bit can be seen in the docstring for String#=~
(from https://ruby-doc.org/core-3.1.2/String.html#method-i-3D~)
If the given object is not a Regexp, returns the value returned by object =~ self.
thereby avoiding the intended behavior change of 1b9f7f5
Did you try upgrading RubyGems?
Present in 3.3.22
Post steps to reproduce the problem
On a x86_64-linux-musl
system (e.g., ruby:3.1-alpine
image):
#! /usr/bin/env ruby
Gem::VERSION # => "3.3.22"
Gem::Platform.local # => #<Gem::Platform:0x00007fda5ca0e0b8 @cpu="x86_64", @os="linux", @version="musl">
gem_platform_string = "x86_64-linux"
gem_platform = Gem::Platform.new(gem_platform_string)
Gem::Platform.match(gem_platform_string) # => false
Gem::Platform.match(gem_platform) # => true
Run gem env
and paste the output below
RubyGems Environment:
- RUBYGEMS VERSION: 3.3.22
- RUBY VERSION: 3.1.2 (2022-04-12 patchlevel 20) [x86_64-linux-musl]
- INSTALLATION DIRECTORY: /usr/local/bundle
- USER INSTALLATION DIRECTORY: /root/.local/share/gem/ruby/3.1.0
- RUBY EXECUTABLE: /usr/local/bin/ruby
- GIT EXECUTABLE:
- EXECUTABLE DIRECTORY: /usr/local/bundle/bin
- SPEC CACHE DIRECTORY: /root/.local/share/gem/specs
- SYSTEM CONFIGURATION DIRECTORY: /usr/local/etc
- RUBYGEMS PLATFORMS:
- ruby
- x86_64-linux-musl
- GEM PATHS:
- /usr/local/bundle
- /root/.local/share/gem/ruby/3.1.0
- /usr/local/lib/ruby/gems/3.1.0
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :backtrace => true
- :bulk_threshold => 1000
- "install" => "--no-document"
- "update" => "--no-document"
- REMOTE SOURCES:
- https://rubygems.org/
- SHELL PATH:
- /usr/local/bundle/bin
- /usr/local/sbin
- /usr/local/bin
- /usr/sbin
- /usr/bin
- /sbin
- /bin
Proposed fix
I think the right thing to do here is to coerce the argument to a Gem::Platform
object, so something like:
diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb
index 06de5de..1dacc59 100644
--- a/lib/rubygems/platform.rb
+++ b/lib/rubygems/platform.rb
@@ -22,6 +22,7 @@ def self.match(platform)
end
def self.match_platforms?(platform, platforms)
+ platform = Gem::Platform.new(platform) unless platform.is_a?(Gem::Platform)
platforms.any? do |local_platform|
platform.nil? ||
local_platform == platform ||
I couldn't figure out how to write a nice test for this, but hopefully I've provided enough detail?