diff options
| author | David RodrÃguez <deivid.rodriguez@riseup.net> | 2025-04-10 21:03:44 +0200 |
|---|---|---|
| committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2025-04-14 16:17:50 +0900 |
| commit | ce2640dde8c65d9e11c3bc2249c5cd5bb7d0dbce (patch) | |
| tree | a7d2524105deeb67b963fa35d4890d04042ba70a /lib | |
| parent | 66aa7139800e7ab5ef7d7a1b0dec73789936e672 (diff) | |
[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`.
https://github.com/rubygems/rubygems/commit/91ce881fda
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/bundler/spec_set.rb | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index 5abbaaeb4b..65c9c6e73e 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -181,7 +181,7 @@ module Bundler end def version_for(name) - self[name].first&.version + exemplary_spec(name)&.version end def what_required(spec) @@ -286,8 +286,13 @@ module Bundler end def additional_variants_from(other) - other.select do |spec| - version_for(spec.name) == spec.version && valid_dependencies?(spec) + other.select do |other_spec| + spec = exemplary_spec(other_spec.name) + next unless spec + + selected = spec.version == other_spec.version && valid_dependencies?(other_spec) + other_spec.source = spec.source if selected + selected end end @@ -364,5 +369,9 @@ module Bundler hash[key] ||= [] hash[key] << value end + + def exemplary_spec(name) + self[name].first + end end end |
