mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[rubygems/rubygems] Fix resolution hanging on musl platforms
After recent musl support was added, Bundler started hanging in musl
platforms. I identified the issue where valid candidates were being
filtered out because their platform was specified as a string, and thus
`Gem::Platform.match_spec?` which under the hood ends up calling
`Gem::Platform#===` would return `nil`, because it does not support
comparing platforms to strings.
In particular, `Bundler::EndpointSpecification`'s platform coming from
the API was not instantiated as a `Gem::Platform`, hence the issue.
Also, this spec surfaced another issue where a bug corrected in
`Gem::Platform#match_platforms` had not been yet backported to Bundler.
So this commit also backports that to get the spec green across RubyGems
versions.
Finally, the fix in `Bundler::EndpointSpecification` made a realworld
spec start failing. This spec was faking out `rails-4.2.7.1` requirement
on Bundler in the `Gemfile.lock` file to be `>= 1.17, < 3` when the real
requirement is `>= 1.17, < 2`. Due to the bug in
`Bundler::EndpointSpecification`, the real requirement provided by the
compact index API (recorded with VCR) was being ignored, and the
`Gemfile.lock` fake requirement was being used, which made the spec
pass. This is all expected, and to fix the issue I changed the spec to
be really realworld and don't fake any Bundler requirements.
faf4ef46bc
This commit is contained in:
parent
1420333455
commit
f7cf641469
4 changed files with 35 additions and 9 deletions
|
@ -12,7 +12,7 @@ module Bundler
|
||||||
super()
|
super()
|
||||||
@name = name
|
@name = name
|
||||||
@version = Gem::Version.create version
|
@version = Gem::Version.create version
|
||||||
@platform = platform
|
@platform = Gem::Platform.new(platform)
|
||||||
@spec_fetcher = spec_fetcher
|
@spec_fetcher = spec_fetcher
|
||||||
@dependencies = dependencies.map {|dep, reqs| build_dependency(dep, reqs) }
|
@dependencies = dependencies.map {|dep, reqs| build_dependency(dep, reqs) }
|
||||||
|
|
||||||
|
|
|
@ -238,8 +238,10 @@ module Gem
|
||||||
X64_MINGW = [Gem::Platform.new("x64-mingw32"),
|
X64_MINGW = [Gem::Platform.new("x64-mingw32"),
|
||||||
Gem::Platform.new("x64-mingw-ucrt")].freeze
|
Gem::Platform.new("x64-mingw-ucrt")].freeze
|
||||||
WINDOWS = [MSWIN, MSWIN64, MINGW, X64_MINGW].flatten.freeze
|
WINDOWS = [MSWIN, MSWIN64, MINGW, X64_MINGW].flatten.freeze
|
||||||
|
X64_LINUX = Gem::Platform.new("x86_64-linux")
|
||||||
|
X64_LINUX_MUSL = Gem::Platform.new("x86_64-linux-musl")
|
||||||
|
|
||||||
if Gem::Platform.new("x86_64-linux-musl") === Gem::Platform.new("x86_64-linux")
|
if X64_LINUX === X64_LINUX_MUSL
|
||||||
remove_method :===
|
remove_method :===
|
||||||
|
|
||||||
def ===(other)
|
def ===(other)
|
||||||
|
@ -275,14 +277,21 @@ module Gem
|
||||||
def match_gem?(platform, gem_name)
|
def match_gem?(platform, gem_name)
|
||||||
match_platforms?(platform, Gem.platforms)
|
match_platforms?(platform, Gem.platforms)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
match_platforms_defined = Gem::Platform.respond_to?(:match_platforms?, true)
|
||||||
|
|
||||||
|
if !match_platforms_defined || Gem::Platform.send(:match_platforms?, Gem::Platform::X64_LINUX_MUSL, [Gem::Platform::X64_LINUX])
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
remove_method :match_platforms? if match_platforms_defined
|
||||||
|
|
||||||
def match_platforms?(platform, platforms)
|
def match_platforms?(platform, platforms)
|
||||||
platforms.any? do |local_platform|
|
platforms.any? do |local_platform|
|
||||||
platform.nil? ||
|
platform.nil? ||
|
||||||
local_platform == platform ||
|
local_platform == platform ||
|
||||||
(local_platform != Gem::Platform::RUBY && local_platform =~ platform)
|
(local_platform != Gem::Platform::RUBY && platform =~ local_platform)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,9 +4,9 @@ RSpec.describe "real world edgecases", :realworld => true do
|
||||||
def rubygems_version(name, requirement)
|
def rubygems_version(name, requirement)
|
||||||
ruby <<-RUBY
|
ruby <<-RUBY
|
||||||
require "#{spec_dir}/support/artifice/vcr"
|
require "#{spec_dir}/support/artifice/vcr"
|
||||||
require "#{entrypoint}"
|
require "bundler"
|
||||||
require "#{entrypoint}/source/rubygems/remote"
|
require "bundler/source/rubygems/remote"
|
||||||
require "#{entrypoint}/fetcher"
|
require "bundler/fetcher"
|
||||||
rubygem = Bundler.ui.silence do
|
rubygem = Bundler.ui.silence do
|
||||||
source = Bundler::Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org"))
|
source = Bundler::Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org"))
|
||||||
fetcher = Bundler::Fetcher.new(source)
|
fetcher = Bundler::Fetcher.new(source)
|
||||||
|
@ -64,7 +64,7 @@ RSpec.describe "real world edgecases", :realworld => true do
|
||||||
it "is able to update a top-level dependency when there is a conflict on a shared transitive child" do
|
it "is able to update a top-level dependency when there is a conflict on a shared transitive child" do
|
||||||
# from https://github.com/rubygems/bundler/issues/5031
|
# from https://github.com/rubygems/bundler/issues/5031
|
||||||
|
|
||||||
system_gems "bundler-2.99.0"
|
pristine_system_gems "bundler-1.99.0"
|
||||||
|
|
||||||
gemfile <<-G
|
gemfile <<-G
|
||||||
source "https://rubygems.org"
|
source "https://rubygems.org"
|
||||||
|
@ -154,7 +154,7 @@ RSpec.describe "real world edgecases", :realworld => true do
|
||||||
activemodel (= 4.2.7.1)
|
activemodel (= 4.2.7.1)
|
||||||
activerecord (= 4.2.7.1)
|
activerecord (= 4.2.7.1)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.7.1)
|
||||||
bundler (>= 1.3.0, < 3.0)
|
bundler (>= 1.3.0, < 2.0)
|
||||||
railties (= 4.2.7.1)
|
railties (= 4.2.7.1)
|
||||||
sprockets-rails
|
sprockets-rails
|
||||||
rails-deprecated_sanitizer (1.0.3)
|
rails-deprecated_sanitizer (1.0.3)
|
||||||
|
@ -191,7 +191,7 @@ RSpec.describe "real world edgecases", :realworld => true do
|
||||||
rails (~> 4.2.7.1)
|
rails (~> 4.2.7.1)
|
||||||
L
|
L
|
||||||
|
|
||||||
bundle "lock --update paperclip", :env => { "BUNDLER_VERSION" => "2.99.0" }
|
bundle "lock --update paperclip", :env => { "BUNDLER_VERSION" => "1.99.0" }
|
||||||
|
|
||||||
expect(lockfile).to include(rubygems_version("paperclip", "~> 5.1.0"))
|
expect(lockfile).to include(rubygems_version("paperclip", "~> 5.1.0"))
|
||||||
end
|
end
|
||||||
|
|
|
@ -344,6 +344,23 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
|
||||||
expect(the_bundle).to include_gems "platform_specific 1.0 RUBY"
|
expect(the_bundle).to include_gems "platform_specific 1.0 RUBY"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "pulls platform specific gems correctly on musl" do
|
||||||
|
build_repo4 do
|
||||||
|
build_gem "nokogiri", "1.13.8" do |s|
|
||||||
|
s.platform = "aarch64-linux"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
simulate_platform "aarch64-linux-musl" do
|
||||||
|
install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }, :verbose => true
|
||||||
|
source "https://gems.repo4"
|
||||||
|
gem "nokogiri"
|
||||||
|
G
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(out).to include("Fetching nokogiri 1.13.8 (aarch64-linux)")
|
||||||
|
end
|
||||||
|
|
||||||
it "allows specifying only-ruby-platform on windows with dependency platforms" do
|
it "allows specifying only-ruby-platform on windows with dependency platforms" do
|
||||||
simulate_windows do
|
simulate_windows do
|
||||||
install_gemfile <<-G
|
install_gemfile <<-G
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue