Skip to content

Commit

Permalink
Auto-heal on corrupted lockfile with missing deps
Browse files Browse the repository at this point in the history
Following up on rubygems#6355, which
turned a crash into a nicer error message, this commit auto-heals the
corrupt lockfile instead.

Since in this particular case (a corrupt Gemfile.lock with missing
dependencies) the LazySpecification will not have accurate dependency
information, we have to materialize the SpecSet to determine there are
missing dependencies. Since we've already got some
incomplete-spec-auto-healing here, I've treated this as another brand of
incomplete spec.
  • Loading branch information
composerinteralia committed Feb 21, 2023
1 parent 75dac08 commit b472eff
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
12 changes: 11 additions & 1 deletion bundler/lib/bundler/spec_set.rb
Expand Up @@ -78,7 +78,7 @@ def to_hash
def materialize(deps)
materialized = self.for(deps, true)

SpecSet.new(materialized, incomplete_specs)
SpecSet.new(materialized, incomplete_specs + specs_with_missing_dependencies(materialized))
end

# Materialize for all the specs in the spec set, regardless of what platform they're for
Expand Down Expand Up @@ -202,5 +202,15 @@ def tsort_each_child(s)
lookup[d.name].each {|s2| yield s2 }
end
end

def specs_with_missing_dependencies(materialized)
materialized.
select {|spec| missing_dependencies?(spec) }.
flat_map {|spec| lookup[spec.name] }
end

def missing_dependencies?(spec)
spec.dependencies.any? {|dep| lookup[dep.name].empty? }
end
end
end
23 changes: 19 additions & 4 deletions bundler/spec/lock/lockfile_spec.rb
Expand Up @@ -1221,7 +1221,7 @@
and include("Either installing with `--full-index` or running `bundle update rack_middleware` should fix the problem.")
end

it "errors gracefully on a corrupt lockfile" do
it "auto-heals when the lockfile is missing dependent specs" do
build_repo4 do
build_gem "minitest-bisect", "1.6.0" do |s|
s.add_dependency "path_expander", "~> 1.1"
Expand Down Expand Up @@ -1253,10 +1253,25 @@
L

cache_gems "minitest-bisect-1.6.0", "path_expander-1.1.1", :gem_repo => gem_repo4
bundle :install, :raise_on_error => false
bundle :install

expect(err).not_to include("ERROR REPORT TEMPLATE")
expect(err).to include("path_expander (~> 1.1), dependency of minitest-bisect-1.6.0 but missing from lockfile")
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
minitest-bisect (1.6.0)
path_expander (~> 1.1)
path_expander (1.1.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
minitest-bisect
BUNDLED WITH
#{Bundler::VERSION}
L
end

it "auto-heals when the lockfile is missing specs" do
Expand Down

0 comments on commit b472eff

Please sign in to comment.