Skip to content

Instantly share code, notes, and snippets.

@lloeki
Last active January 17, 2022 08:53
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lloeki/12dcf61324f64a2fa1e8a8b2109c1f00 to your computer and use it in GitHub Desktop.
Save lloeki/12dcf61324f64a2fa1e8a8b2109c1f00 to your computer and use it in GitHub Desktop.
Bundler 1.17 / Rubygems 3.0 linux-musl resolution
# This fixes the platform value for rubygems 3.x, allowing bundler and gem install
# to properly resolve to: a) linux on linux, and b) to linux-musl on linux-musl
# with a fallback to linux if there's no linux-musl gem published.
#
# This works when there is no extension to build that would try to query the
# current Ruby platform through Rubygems (because building an extension spawns an
# independent Ruby interpreter)
#
# The second file in this gist is a patch to apply to Rubygems 3.0.3.1, e.g for
# official Docker Hub images:
#
# ```
# cat musl.patch | (cd /usr/local/lib/ruby/2.6.0/rubygems && patch -p1)
# ```
module Gem::Platform::Patch
def initialize(arch)
case arch
when Array then
@cpu, @os, @version = arch
when String then
arch = arch.split '-'
if arch.length > 2 and arch.last !~ /\d+(\.\d+)?$/ # reassemble x86-linux-{libc}
extra = arch.pop
arch.last << "-#{extra}"
end
cpu = arch.shift
@cpu = case cpu
when /i\d86/ then 'x86'
else cpu
end
if arch.length == 2 and arch.last =~ /^\d+(\.\d+)?$/ # for command-line
@os, @version = arch
return
end
os, = arch
@cpu, os = nil, cpu if os.nil? # legacy jruby
@os, @version = case os
when /aix(\d+)?/ then [ 'aix', $1 ]
when /cygwin/ then [ 'cygwin', nil ]
when /darwin(\d+)?/ then [ 'darwin', $1 ]
when /^macruby$/ then [ 'macruby', nil ]
when /freebsd(\d+)?/ then [ 'freebsd', $1 ]
when /hpux(\d+)?/ then [ 'hpux', $1 ]
when /^java$/, /^jruby$/ then [ 'java', nil ]
when /^java([\d.]*)/ then [ 'java', $1 ]
when /^dalvik(\d+)?$/ then [ 'dalvik', $1 ]
when /^dotnet$/ then [ 'dotnet', nil ]
when /^dotnet([\d.]*)/ then [ 'dotnet', $1 ]
when /linux-?((?!gnu)\w+)?/ then [ 'linux', $1 ]
when /mingw32/ then [ 'mingw32', nil ]
when /(mswin\d+)(\_(\d+))?/ then
os, version = $1, $3
@cpu = 'x86' if @cpu.nil? and os =~ /32$/
[os, version]
when /netbsdelf/ then [ 'netbsdelf', nil ]
when /openbsd(\d+\.\d+)?/ then [ 'openbsd', $1 ]
when /bitrig(\d+\.\d+)?/ then [ 'bitrig', $1 ]
when /solaris(\d+\.\d+)?/ then [ 'solaris', $1 ]
# test
when /^(\w+_platform)(\d+)?/ then [ $1, $2 ]
else [ 'unknown', nil ]
end
when Gem::Platform then
@cpu = arch.cpu
@os = arch.os
@version = arch.version
else
raise ArgumentError, "invalid argument #{arch.inspect}"
end
end
def ===(other)
return nil unless Gem::Platform === other
# cpu
([nil,'universal'].include?(@cpu) or [nil, 'universal'].include?(other.cpu) or @cpu == other.cpu or (@cpu == 'arm' and other.cpu.start_with?("arm"))) and
# os
@os == other.os and
# version
(
(@os != 'linux' and (@version.nil? or other.version.nil?)) or
(@os == 'linux' and (!@version.nil? and other.version.nil?)) or
@version == other.version
)
end
end
# apply monkeypatch
Gem::Platform.prepend Gem::Platform::Patch
# reset cached values
Gem::Platform.instance_eval { @local = nil }
Gem.instance_eval { @platforms = nil }
source 'https://rubygems.org'
gem 'libv8-node'
gem 'nokogiri'
diff --git a/platform.orig b/platform.rb
index f8fe4da..93e9dee 100644
--- a/platform.orig
+++ b/platform.rb
@@ -56,7 +56,7 @@ class Gem::Platform
when String then
arch = arch.split '-'
- if arch.length > 2 and arch.last !~ /\d/ # reassemble x86-linux-gnu
+ if arch.length > 2 and arch.last !~ /\d+(\.\d+)?$/ # reassemble x86-linux-{libc}
extra = arch.pop
arch.last << "-#{extra}"
end
@@ -64,11 +64,11 @@ class Gem::Platform
cpu = arch.shift
@cpu = case cpu
- when /i\d86/ then 'x86'
- else cpu
- end
+ when /i\d86/ then 'x86'
+ else cpu
+ end
- if arch.length == 2 and arch.last =~ /^\d+(\.\d+)?$/ # for command-line
+ if arch.length == 2 and arch.last =~ /^\d+(\.\d+)?$/ # for command-line
@os, @version = arch
return
end
@@ -88,7 +88,7 @@ class Gem::Platform
when /^dalvik(\d+)?$/ then [ 'dalvik', $1 ]
when /^dotnet$/ then [ 'dotnet', nil ]
when /^dotnet([\d.]*)/ then [ 'dotnet', $1 ]
- when /linux/ then [ 'linux', $1 ]
+ when /linux-?((?!gnu)\w+)?/ then [ 'linux', $1 ]
when /mingw32/ then [ 'mingw32', nil ]
when /(mswin\d+)(\_(\d+))?/ then
os, version = $1, $3
@@ -149,16 +149,20 @@ class Gem::Platform
return nil unless Gem::Platform === other
# cpu
- ([nil,'universal'].include?(@cpu) or [nil, 'universal'].include?(other.cpu) or @cpu == other.cpu or
- (@cpu == 'arm' and other.cpu =~ /\Aarm/)) and
+ ([nil,'universal'].include?(@cpu) or [nil, 'universal'].include?(other.cpu) or @cpu == other.cpu or (@cpu == 'arm' and other.cpu.start_with?("arm"))) and
# os
@os == other.os and
# version
- (@version.nil? or other.version.nil? or @version == other.version)
+ (
+ (@os != 'linux' and (@version.nil? or other.version.nil?)) or
+ (@os == 'linux' and (!@version.nil? and other.version.nil?)) or
+ @version == other.version
+ )
end
+
##
# Does +other+ match this platform? If +other+ is a String it will be
# converted to a Gem::Platform first. See #=== for matching rules.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment