summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Rodríguez <deivid.rodriguez@riseup.net>2025-04-10 21:03:44 +0200
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2025-04-14 16:17:50 +0900
commitce2640dde8c65d9e11c3bc2249c5cd5bb7d0dbce (patch)
treea7d2524105deeb67b963fa35d4890d04042ba70a /lib
parent66aa7139800e7ab5ef7d7a1b0dec73789936e672 (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.rb15
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