keg: installed dependencies of unknown formulae

Previously, trying to resolve the dependencies of a keg would raise an
exception if the formulae for any of the dependencies could not be found
(e.g. if it had been moved to another tap).

This commit updates the dependency finding logic to catch these
exceptions, and fall back to comparing names and taps of formulae, which
should give the correct behaviour.

Fixes #1586.
This commit is contained in:
Alyssa Ross 2016-12-27 17:26:21 +00:00
parent 0a20edf945
commit e5d7e13c63
2 changed files with 23 additions and 6 deletions

View File

@ -139,6 +139,10 @@ class Keg
raise NotAKegError, "#{path} is not inside a keg" raise NotAKegError, "#{path} is not inside a keg"
end end
def self.all
Formula.racks.flat_map(&:subdirs).map { |d| new(d) }
end
attr_reader :path, :name, :linked_keg_record, :opt_record attr_reader :path, :name, :linked_keg_record, :opt_record
protected :path protected :path
@ -353,14 +357,21 @@ class Keg
end end
def installed_dependents def installed_dependents
Formula.installed.flat_map(&:installed_kegs).select do |keg| my_tab = Tab.for_keg(self)
Keg.all.select do |keg|
tab = Tab.for_keg(keg) tab = Tab.for_keg(keg)
next if tab.runtime_dependencies.nil? # no dependency information saved. next if tab.runtime_dependencies.nil? # no dependency information saved.
tab.runtime_dependencies.any? do |dep| tab.runtime_dependencies.any? do |dep|
# Resolve formula rather than directly comparing names # Resolve formula rather than directly comparing names
# in case of conflicts between formulae from different taps. # in case of conflicts between formulae from different taps.
dep_formula = Formulary.factory(dep["full_name"]) begin
dep_formula == to_formula && dep["version"] == version.to_s dep_formula = Formulary.factory(dep["full_name"])
next false unless dep_formula == to_formula
rescue FormulaUnavailableError
next false unless my_tab["full_name"] = dep["full_name"]
end
dep["version"] == version.to_s
end end
end end
end end

View File

@ -47,6 +47,11 @@ class LinkTestCase < Homebrew::TestCase
end end
class LinkTests < LinkTestCase class LinkTests < LinkTestCase
def test_all
Formula.clear_racks_cache
assert_equal [@keg], Keg.all
end
def test_empty_installation def test_empty_installation
%w[.DS_Store INSTALL_RECEIPT.json LICENSE.txt].each do |file| %w[.DS_Store INSTALL_RECEIPT.json LICENSE.txt].each do |file|
touch @keg/file touch @keg/file
@ -355,10 +360,11 @@ class InstalledDependantsTests < LinkTestCase
# from a file path or URL. # from a file path or URL.
def test_unknown_formula def test_unknown_formula
Formulary.unstub(:loader_for) Formulary.unstub(:loader_for)
dependencies [] alter_tab { |t| t.source["tap"] = "some/tap" }
dependencies [{ "full_name" => "some/tap/bar", "version" => "1.0" }]
alter_tab { |t| t.source["path"] = nil } alter_tab { |t| t.source["path"] = nil }
assert_empty @keg.installed_dependents assert_equal [@dependent], @keg.installed_dependents
assert_nil Keg.find_some_installed_dependents([@keg]) assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg])
end end
def test_no_dependencies_anywhere def test_no_dependencies_anywhere