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. https://github.com/rubygems/rubygems/commit/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()
|
||||
@name = name
|
||||
@version = Gem::Version.create version
|
||||
@platform = platform
|
||||
@platform = Gem::Platform.new(platform)
|
||||
@spec_fetcher = spec_fetcher
|
||||
@dependencies = dependencies.map {|dep, reqs| build_dependency(dep, reqs) }
|
||||
|
||||
|
|
|
@ -238,8 +238,10 @@ module Gem
|
|||
X64_MINGW = [Gem::Platform.new("x64-mingw32"),
|
||||
Gem::Platform.new("x64-mingw-ucrt")].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 :===
|
||||
|
||||
def ===(other)
|
||||
|
@ -275,14 +277,21 @@ module Gem
|
|||
def match_gem?(platform, gem_name)
|
||||
match_platforms?(platform, Gem.platforms)
|
||||
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
|
||||
|
||||
remove_method :match_platforms? if match_platforms_defined
|
||||
|
||||
def match_platforms?(platform, platforms)
|
||||
platforms.any? do |local_platform|
|
||||
platform.nil? ||
|
||||
local_platform == platform ||
|
||||
(local_platform != Gem::Platform::RUBY && local_platform =~ platform)
|
||||
(local_platform != Gem::Platform::RUBY && platform =~ local_platform)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,9 +4,9 @@ RSpec.describe "real world edgecases", :realworld => true do
|
|||
def rubygems_version(name, requirement)
|
||||
ruby <<-RUBY
|
||||
require "#{spec_dir}/support/artifice/vcr"
|
||||
require "#{entrypoint}"
|
||||
require "#{entrypoint}/source/rubygems/remote"
|
||||
require "#{entrypoint}/fetcher"
|
||||
require "bundler"
|
||||
require "bundler/source/rubygems/remote"
|
||||
require "bundler/fetcher"
|
||||
rubygem = Bundler.ui.silence do
|
||||
source = Bundler::Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org"))
|
||||
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
|
||||
# from https://github.com/rubygems/bundler/issues/5031
|
||||
|
||||
system_gems "bundler-2.99.0"
|
||||
pristine_system_gems "bundler-1.99.0"
|
||||
|
||||
gemfile <<-G
|
||||
source "https://rubygems.org"
|
||||
|
@ -154,7 +154,7 @@ RSpec.describe "real world edgecases", :realworld => true do
|
|||
activemodel (= 4.2.7.1)
|
||||
activerecord (= 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)
|
||||
sprockets-rails
|
||||
rails-deprecated_sanitizer (1.0.3)
|
||||
|
@ -191,7 +191,7 @@ RSpec.describe "real world edgecases", :realworld => true do
|
|||
rails (~> 4.2.7.1)
|
||||
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"))
|
||||
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"
|
||||
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
|
||||
simulate_windows do
|
||||
install_gemfile <<-G
|
||||
|
|
Loading…
Add table
Reference in a new issue