uses: properly handle recursive deps exceptions

Fixes #1776.

If any known formula had a dependency on an untapped tap,
Formula#recursive_dependencies would throw an exception, which would be
caught by the outer exception handler, causing the rest of the
dependencies for that formula to be skipped and incomplete output to be
generated.

To fix this, I added a check to avoid analysing the dependencies of
formulae from uninstalled taps.

Additionally, I removed the aforementioned outer exception handler added
in 5fdb89aed90f03413cdb21af430411c4a722876e, because the only other
place that should be capable of throwing such an exception is the
statement that was surrounded by another wider exception handler in
Homebrew/legacy-homebrew#40682.
This commit is contained in:
Alyssa Ross 2017-01-05 00:24:49 +00:00
parent 4c061fc183
commit 536b6e2396

View File

@ -47,48 +47,49 @@ module Homebrew
uses = formulae.select do |f| uses = formulae.select do |f|
used_formulae.all? do |ff| used_formulae.all? do |ff|
begin if recursive
if recursive deps = f.recursive_dependencies do |dependent, dep|
deps = f.recursive_dependencies do |dependent, dep| if dep.recommended?
if dep.recommended? Dependency.prune if ignores.include?("recommended?") || dependent.build.without?(dep)
Dependency.prune if ignores.include?("recommended?") || dependent.build.without?(dep) elsif dep.optional?
elsif dep.optional? Dependency.prune if !includes.include?("optional?") && !dependent.build.with?(dep)
Dependency.prune if !includes.include?("optional?") && !dependent.build.with?(dep) elsif dep.build?
elsif dep.build? Dependency.prune unless includes.include?("build?")
Dependency.prune unless includes.include?("build?")
end
end end
reqs = f.recursive_requirements do |dependent, req|
if req.recommended?
Requirement.prune if ignores.include?("recommended?") || dependent.build.without?(req)
elsif req.optional?
Requirement.prune if !includes.include?("optional?") && !dependent.build.with?(req)
elsif req.build?
Requirement.prune unless includes.include?("build?")
end
end
else
deps = f.deps.reject do |dep|
ignores.any? { |ignore| dep.send(ignore) } && !includes.any? { |include| dep.send(include) }
end
reqs = f.requirements.reject do |req|
ignores.any? { |ignore| req.send(ignore) } && !includes.any? { |include| req.send(include) }
end
end
next true if deps.any? do |dep|
begin
dep.to_formula.full_name == ff.full_name
rescue
dep.name == ff.name
end
end
reqs.any? do |req| # If a tap isn't installed, we can't find the dependencies of one
req.name == ff.name || [ff.name, ff.full_name].include?(req.default_formula) # its formulae, and an exception will be thrown if we try.
if dep.is_a?(TapDependency) && !dep.tap.installed?
Dependency.keep_but_prune_recursive_deps
end
end end
rescue FormulaUnavailableError reqs = f.recursive_requirements do |dependent, req|
# Silently ignore this case as we don't care about things used in if req.recommended?
# taps that aren't currently tapped. Requirement.prune if ignores.include?("recommended?") || dependent.build.without?(req)
elsif req.optional?
Requirement.prune if !includes.include?("optional?") && !dependent.build.with?(req)
elsif req.build?
Requirement.prune unless includes.include?("build?")
end
end
else
deps = f.deps.reject do |dep|
ignores.any? { |ignore| dep.send(ignore) } && !includes.any? { |include| dep.send(include) }
end
reqs = f.requirements.reject do |req|
ignores.any? { |ignore| req.send(ignore) } && !includes.any? { |include| req.send(include) }
end
end
next true if deps.any? do |dep|
begin
dep.to_formula.full_name == ff.full_name
rescue
dep.name == ff.name
end
end
reqs.any? do |req|
req.name == ff.name || [ff.name, ff.full_name].include?(req.default_formula)
end end
end end
end end