Skip to content

Commit ce2640d

Browse files
deivid-rodriguezhsbt
authored andcommitted
[rubygems/rubygems] Fix edge case making bundle update behave incorrectly
If both a native and a generic version are locked, but the native version is incompatible with the running Ruby, Bundler will still keep the native version in the lockfile, since it could be potentially useful when using other rubies. However, when `bundle update` is run, this was not the case because the locked native gems were not using the right source when materializing. They were using the lockfile source instead of the Gemfile source, and that meant they could not be found when materializing, because the lockfile source always uses local mode so does not see them. The effect of this was normally that they were incorrectly removed from the lockfile and a strange "this spec has been possibly yanked" was printed in verbose mode. However, in certain situations (i.e., when the generic gem would bring extra dependencies), it could also make `bundle update` crash. The solution is, when adding this extra locked specs to the result after resolving, maybe sure they inherit the source from the resolved specs, so they can be found when materializing. `bundle install` did not have the issue because it passes locked specs to the resolver, and assigns the right source to them in `Definition#converge_locked_specs`. ruby/rubygems@91ce881fda
1 parent 66aa713 commit ce2640d

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

lib/bundler/spec_set.rb

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ def delete_by_name(name)
181181
end
182182

183183
def version_for(name)
184-
self[name].first&.version
184+
exemplary_spec(name)&.version
185185
end
186186

187187
def what_required(spec)
@@ -286,8 +286,13 @@ def all_platforms
286286
end
287287

288288
def additional_variants_from(other)
289-
other.select do |spec|
290-
version_for(spec.name) == spec.version && valid_dependencies?(spec)
289+
other.select do |other_spec|
290+
spec = exemplary_spec(other_spec.name)
291+
next unless spec
292+
293+
selected = spec.version == other_spec.version && valid_dependencies?(other_spec)
294+
other_spec.source = spec.source if selected
295+
selected
291296
end
292297
end
293298

@@ -364,5 +369,9 @@ def index_spec(hash, key, value)
364369
hash[key] ||= []
365370
hash[key] << value
366371
end
372+
373+
def exemplary_spec(name)
374+
self[name].first
375+
end
367376
end
368377
end

spec/bundler/install/gems/resolving_spec.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,14 +540,23 @@
540540
lockfile original_lockfile
541541
end
542542

543-
it "keeps both variants in the lockfile, and uses the generic one since it's compatible" do
543+
it "keeps both variants in the lockfile when installing, and uses the generic one since it's compatible" do
544544
simulate_platform "x86_64-linux" do
545545
bundle "install --verbose"
546546

547547
expect(lockfile).to eq(original_lockfile)
548548
expect(the_bundle).to include_gems("nokogiri 1.16.3")
549549
end
550550
end
551+
552+
it "keeps both variants in the lockfile when updating, and uses the generic one since it's compatible" do
553+
simulate_platform "x86_64-linux" do
554+
bundle "update --verbose"
555+
556+
expect(lockfile).to eq(original_lockfile)
557+
expect(the_bundle).to include_gems("nokogiri 1.16.3")
558+
end
559+
end
551560
end
552561

553562
it "gives a meaningful error on ruby version mismatches between dependencies" do

0 commit comments

Comments
 (0)