Skip to content

Commit

Permalink
fix syncing a gem update that changes platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
ccutrer committed May 17, 2024
1 parent 61bd316 commit 6a50e19
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 6 deletions.
11 changes: 8 additions & 3 deletions lib/bundler/multilock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def after_install_all(install: true)
end

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

if gem_spec
adjusted_parent_lockfile_contents += <<~TEXT
Expand Down Expand Up @@ -257,9 +257,14 @@ def after_install_all(install: true)

# replace any duplicate specs with what's in the parent lockfile
lockfile.specs.map! do |spec|
parent_spec = parent_specs[[spec.name, spec.platform]]
next spec unless parent_spec
platform_specs = parent_specs[spec.name]
next spec unless platform_specs

parent_spec = platform_specs[spec.platform]
# sometimes a gem changes platforms with a new version, such as from aarch64-linux
# to aarch64-linux-gnu. we need to still sync it
parent_spec ||= platform_specs.find { |platform, _| platform =~ spec.platform }&.last
next spec unless parent_spec
next spec if check_precedence.call(spec, parent_spec) == :self

dependency_changes ||= spec != parent_spec
Expand Down
8 changes: 6 additions & 2 deletions lib/bundler/multilock/cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,12 @@ def parser(lockfile_name)
end

def specs(lockfile_name)
@specs[lockfile_name] ||= parser(lockfile_name).specs.to_h do |spec|
[[spec.name, spec.platform], spec]
@specs[lockfile_name] ||= begin
specs = {}
parser(lockfile_name).specs.each do |spec|
(specs[spec.name] ||= {})[spec.platform] = spec
end
specs
end
end

Expand Down
4 changes: 3 additions & 1 deletion lib/bundler/multilock/check.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ def deep_check(lockfile_definition)

# check for conflicting requirements (and build list of pins, in the same loop)
parser.specs.each do |spec|
parent_spec = @cache.specs(parent_lockfile_name)[[spec.name, spec.platform]]
platform_specs = @cache.specs(parent_lockfile_name)[spec.name]
parent_spec = platform_specs[spec.platform]
parent_spec ||= platform_specs.find { |platform, _| platform =~ spec.platform }&.last

if lockfile_definition[:enforce_pinned_additional_dependencies]
# look through what this spec depends on, and keep track of all pinned requirements
Expand Down
29 changes: 29 additions & 0 deletions spec/bundler/multilock_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,35 @@
end
end

it "syncs gems whose platforms changed slightly" do
if RUBY_VERSION < "3.0"
skip "The test case that triggers this requires Ruby 3.0+; " \
"just rely on this test running on other ruby versions"
end

with_gemfile(<<~RUBY) do
gem "sqlite3", "~> 1.7"
lockfile("all") {}
RUBY
invoke_bundler("install")

write_gemfile(<<~RUBY)
gem "sqlite3"
lockfile("all") {}
RUBY
invoke_bundler("install")

expect(invoke_bundler("info sqlite3")).to include("1.7.3")
expect(invoke_bundler("info sqlite3", env: { "BUNDLE_LOCKFILE" => "all" })).to include("1.7.3")

invoke_bundler("update sqlite3")
expect(invoke_bundler("info sqlite3")).not_to include("1.7.3")
expect(invoke_bundler("info sqlite3", env: { "BUNDLE_LOCKFILE" => "all" })).not_to include("1.7.3")
end
end

it "syncs ruby version" do
with_gemfile(<<~RUBY) do
gem "concurrent-ruby", "1.2.2"
Expand Down

0 comments on commit 6a50e19

Please sign in to comment.