[rubygems/rubygems] Fix resolver hangs when dealing with an incomplete lockfile
While working on locking multiple platforms by default, I got an infinite resolution loop in one of our resolver specs. The culprit ended up being that when dealing with lockfile specs with incomplete dependencies (spec appears in lockfile, but its dependencies don't), those specs were not being properly expired and that tripped up resolution. The issue for some reason only manifests when dealing with multiple lockfile platforms, that's why it only manifested when working on locking multiple platforms by default. https://github.com/rubygems/rubygems/commit/4ca72913bb
This commit is contained in:
parent
c257380965
commit
f3d69bed62
@ -668,9 +668,17 @@ module Bundler
|
||||
def check_missing_lockfile_specs
|
||||
all_locked_specs = @locked_specs.map(&:name) << "bundler"
|
||||
|
||||
@locked_specs.any? do |s|
|
||||
missing = @locked_specs.select do |s|
|
||||
s.dependencies.any? {|dep| !all_locked_specs.include?(dep.name) }
|
||||
end
|
||||
|
||||
if missing.any?
|
||||
@locked_specs.delete(missing)
|
||||
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def converge_paths
|
||||
|
@ -35,9 +35,7 @@ module Bundler
|
||||
end
|
||||
|
||||
def delete(specs)
|
||||
specs.each do |spec|
|
||||
@base.delete(spec)
|
||||
end
|
||||
@base.delete(specs)
|
||||
end
|
||||
|
||||
def get_package(name)
|
||||
|
@ -63,8 +63,8 @@ module Bundler
|
||||
@sorted = nil
|
||||
end
|
||||
|
||||
def delete(spec)
|
||||
@specs.delete(spec)
|
||||
def delete(specs)
|
||||
specs.each {|spec| @specs.delete(spec) }
|
||||
@lookup = nil
|
||||
@sorted = nil
|
||||
end
|
||||
|
@ -1008,6 +1008,29 @@ RSpec.describe "bundle lock" do
|
||||
So, because Gemfile depends on rails >= 7.0.2.3,
|
||||
version solving has failed.
|
||||
ERR
|
||||
|
||||
lockfile lockfile.gsub(/PLATFORMS\n #{lockfile_platforms}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}")
|
||||
|
||||
bundle "lock", :raise_on_error => false
|
||||
|
||||
expect(err).to eq <<~ERR.strip
|
||||
Could not find compatible versions
|
||||
|
||||
Because rails >= 7.0.3.1, < 7.0.4 depends on activemodel = 7.0.3.1
|
||||
and rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3,
|
||||
rails >= 7.0.2.3, < 7.0.4 requires activemodel = 7.0.2.3 OR = 7.0.3.1.
|
||||
And because every version of activemodel depends on activesupport = 6.0.4,
|
||||
rails >= 7.0.2.3, < 7.0.4 requires activesupport = 6.0.4.
|
||||
Because rails >= 7.0.3.1, < 7.0.4 depends on activesupport = 7.0.3.1
|
||||
and rails >= 7.0.2.3, < 7.0.3.1 depends on activesupport = 7.0.2.3,
|
||||
rails >= 7.0.2.3, < 7.0.4 requires activesupport = 7.0.2.3 OR = 7.0.3.1.
|
||||
Thus, rails >= 7.0.2.3, < 7.0.4 cannot be used.
|
||||
And because rails >= 7.0.4 depends on activemodel = 7.0.4,
|
||||
rails >= 7.0.2.3 requires activemodel = 7.0.4.
|
||||
So, because activemodel = 7.0.4 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally
|
||||
and Gemfile depends on rails >= 7.0.2.3,
|
||||
version solving has failed.
|
||||
ERR
|
||||
end
|
||||
|
||||
it "does not accidentally resolves to prereleases" do
|
||||
|
Loading…
x
Reference in New Issue
Block a user