Skip to content

Commit 55f8dcd

Browse files
committed
fix syncing a gem update that changes platforms
1 parent 5e887ca commit 55f8dcd

File tree

4 files changed

+50
-6
lines changed

4 files changed

+50
-6
lines changed

lib/bundler/multilock.rb

+2-3
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def after_install_all(install: true)
217217
end
218218

219219
# add a source for the current gem
220-
gem_spec = parent_specs[[File.basename(Bundler.root), "ruby"]]
220+
gem_spec = parent_specs.dig(File.basename(Bundler.root), "ruby")
221221

222222
if gem_spec
223223
adjusted_parent_lockfile_contents += <<~TEXT
@@ -257,9 +257,8 @@ def after_install_all(install: true)
257257

258258
# replace any duplicate specs with what's in the parent lockfile
259259
lockfile.specs.map! do |spec|
260-
parent_spec = parent_specs[[spec.name, spec.platform]]
260+
parent_spec = cache.find_matching_spec(parent_specs, spec)
261261
next spec unless parent_spec
262-
263262
next spec if check_precedence.call(spec, parent_spec) == :self
264263

265264
dependency_changes ||= spec != parent_spec

lib/bundler/multilock/cache.rb

+18-2
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,27 @@ def parser(lockfile_name)
5757
end
5858

5959
def specs(lockfile_name)
60-
@specs[lockfile_name] ||= parser(lockfile_name).specs.to_h do |spec|
61-
[[spec.name, spec.platform], spec]
60+
@specs[lockfile_name] ||= begin
61+
specs = {}
62+
parser(lockfile_name).specs.each do |spec|
63+
(specs[spec.name] ||= {})[spec.platform] = spec
64+
end
65+
specs
6266
end
6367
end
6468

69+
# sometimes a gem changes platforms with a new version, such as from aarch64-linux
70+
# to aarch64-linux-gnu. we need to still sync it
71+
def find_matching_spec(specs, spec)
72+
specs = self.specs(specs) unless specs.is_a?(Hash)
73+
platform_specs = specs[spec.name]
74+
return unless platform_specs
75+
76+
parent_spec = platform_specs[spec.platform]
77+
parent_spec ||= platform_specs.find { |platform, _| platform =~ spec.platform }&.last
78+
parent_spec || platform_specs.find { |platform, _| platform == "ruby" }&.last
79+
end
80+
6581
# @param lockfile_name [Pathname]
6682
# @return [Hash<String, Set<String>>] hash of gem name to set of gem names that depend on it
6783
def reverse_dependencies(lockfile_name)

lib/bundler/multilock/check.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def deep_check(lockfile_definition)
120120

121121
# check for conflicting requirements (and build list of pins, in the same loop)
122122
parser.specs.each do |spec|
123-
parent_spec = @cache.specs(parent_lockfile_name)[[spec.name, spec.platform]]
123+
parent_spec = @cache.find_matching_spec(parent_lockfile_name, spec)
124124

125125
if lockfile_definition[:enforce_pinned_additional_dependencies]
126126
# look through what this spec depends on, and keep track of all pinned requirements

spec/bundler/multilock_spec.rb

+29
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,35 @@
863863
end
864864
end
865865

866+
it "syncs gems whose platforms changed slightly" do
867+
if RUBY_VERSION < "3.0"
868+
skip "The test case that triggers this requires Ruby 3.0+; " \
869+
"just rely on this test running on other ruby versions"
870+
end
871+
872+
with_gemfile(<<~RUBY) do
873+
gem "sqlite3", "~> 1.7"
874+
875+
lockfile("all") {}
876+
RUBY
877+
invoke_bundler("install")
878+
879+
write_gemfile(<<~RUBY)
880+
gem "sqlite3"
881+
882+
lockfile("all") {}
883+
RUBY
884+
invoke_bundler("install")
885+
886+
expect(invoke_bundler("info sqlite3")).to include("1.7.3")
887+
expect(invoke_bundler("info sqlite3", env: { "BUNDLE_LOCKFILE" => "all" })).to include("1.7.3")
888+
889+
invoke_bundler("update sqlite3")
890+
expect(invoke_bundler("info sqlite3")).not_to include("1.7.3")
891+
expect(invoke_bundler("info sqlite3", env: { "BUNDLE_LOCKFILE" => "all" })).not_to include("1.7.3")
892+
end
893+
end
894+
866895
it "syncs ruby version" do
867896
with_gemfile(<<~RUBY) do
868897
gem "concurrent-ruby", "1.2.2"

0 commit comments

Comments
 (0)