Skip to content

Commit

Permalink
Merge pull request #4488 from lloeki/support-non-gnu-libc-linux-2
Browse files Browse the repository at this point in the history
Backport non gnu libc linux support from RubyGems

(cherry picked from commit 95114c8)
  • Loading branch information
deivid-rodriguez committed Aug 24, 2022
1 parent 8a50f20 commit bce7400
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
26 changes: 26 additions & 0 deletions bundler/lib/bundler/rubygems_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,32 @@ class Platform
MINGW = Gem::Platform.new("x86-mingw32")
X64_MINGW = [Gem::Platform.new("x64-mingw32"),
Gem::Platform.new("x64-mingw-ucrt")].freeze

if Gem::Platform.new("x86_64-linux-musl") === Gem::Platform.new("x86_64-linux")
remove_method :===

def ===(other)
return nil unless Gem::Platform === other

# universal-mingw32 matches x64-mingw-ucrt
return true if (@cpu == "universal" || other.cpu == "universal") &&
@os.start_with?("mingw") && other.os.start_with?("mingw")

# cpu
([nil,"universal"].include?(@cpu) || [nil, "universal"].include?(other.cpu) || @cpu == other.cpu ||
(@cpu == "arm" && other.cpu.start_with?("arm"))) &&

# os
@os == other.os &&

# version
(
(@os != "linux" && (@version.nil? || other.version.nil?)) ||
(@os == "linux" && ((@version.nil? && ["gnu", "musl"].include?(other.version)) || (@version == "gnu" && other.version.nil?))) ||
@version == other.version
)
end
end
end

Platform.singleton_class.module_eval do
Expand Down
73 changes: 73 additions & 0 deletions bundler/spec/resolver/platform_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,79 @@
should_resolve_as %w[foo-1.0.0-x64-mingw32]
end

describe "on a linux platform", :rubygems => ">= 3.1.0.pre.1" do
# Ruby's platform is *-linux => platform's libc is glibc, so not musl
# Ruby's platform is *-linux-musl => platform's libc is musl, so not glibc
# Gem's platform is *-linux => gem is glibc + maybe musl compatible
# Gem's platform is *-linux-musl => gem is musl compatible but not glibc

it "favors the platform version-specific gem on a version-specifying linux platform" do
@index = build_index do
gem "foo", "1.0.0"
gem "foo", "1.0.0", "x86_64-linux"
gem "foo", "1.0.0", "x86_64-linux-musl"
end
dep "foo"
platforms "x86_64-linux-musl"

should_resolve_as %w[foo-1.0.0-x86_64-linux-musl]
end

it "favors the version-less gem over the version-specific gem on a gnu linux platform" do
@index = build_index do
gem "foo", "1.0.0"
gem "foo", "1.0.0", "x86_64-linux"
gem "foo", "1.0.0", "x86_64-linux-musl"
end
dep "foo"
platforms "x86_64-linux"

should_resolve_as %w[foo-1.0.0-x86_64-linux]
end

it "ignores the platform version-specific gem on a gnu linux platform" do
@index = build_index do
gem "foo", "1.0.0", "x86_64-linux-musl"
end
dep "foo"
platforms "x86_64-linux"

should_not_resolve
end

it "falls back to the platform version-less gem on a linux platform with a version" do
@index = build_index do
gem "foo", "1.0.0"
gem "foo", "1.0.0", "x86_64-linux"
end
dep "foo"
platforms "x86_64-linux-musl"

should_resolve_as %w[foo-1.0.0-x86_64-linux]
end

it "falls back to the ruby platform gem on a gnu linux platform when only a version-specifying gem is available" do
@index = build_index do
gem "foo", "1.0.0"
gem "foo", "1.0.0", "x86_64-linux-musl"
end
dep "foo"
platforms "x86_64-linux"

should_resolve_as %w[foo-1.0.0]
end

it "falls back to the platform version-less gem on a version-specifying linux platform and no ruby platform gem is available" do
@index = build_index do
gem "foo", "1.0.0", "x86_64-linux"
end
dep "foo"
platforms "x86_64-linux-musl"

should_resolve_as %w[foo-1.0.0-x86_64-linux]
end
end

it "takes the latest ruby gem if the platform specific gem doesn't match the required_ruby_version" do
@index = build_index do
gem "foo", "1.0.0"
Expand Down
4 changes: 4 additions & 0 deletions bundler/spec/support/indexes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ def resolve(args = [])
Bundler::Resolver.resolve(deps, source_requirements, *args)
end

def should_not_resolve
expect { resolve }.to raise_error(Bundler::GemNotFound)
end

def should_resolve_as(specs)
got = resolve
got = got.map(&:full_name).sort
Expand Down

0 comments on commit bce7400

Please sign in to comment.