Check version conflicts using linkage.
Instead of refusing to install software preemptively by assuming multiple linkage to differing versions of the same library we now make `brew linkage --test` verify that we don't have two versions of the same library linked at the same time. This will be considerably more permissive whilst checking the actual problem that we're worried about.
This commit is contained in:
parent
31ab0bb391
commit
ca6c75d229
@ -155,8 +155,6 @@ class FormulaInstaller
|
||||
|
||||
recursive_deps = formula.recursive_dependencies
|
||||
recursive_formulae = recursive_deps.map(&:to_formula)
|
||||
recursive_runtime_formulae =
|
||||
formula.runtime_formula_dependencies(undeclared: false)
|
||||
|
||||
recursive_dependencies = []
|
||||
recursive_formulae.each do |dep|
|
||||
@ -182,25 +180,6 @@ class FormulaInstaller
|
||||
EOS
|
||||
end
|
||||
|
||||
version_hash = {}
|
||||
version_conflicts = Set.new
|
||||
recursive_runtime_formulae.each do |f|
|
||||
name = f.name
|
||||
unversioned_name, = name.split("@")
|
||||
next if unversioned_name == "python"
|
||||
version_hash[unversioned_name] ||= Set.new
|
||||
version_hash[unversioned_name] << name
|
||||
next if version_hash[unversioned_name].length < 2
|
||||
version_conflicts += version_hash[unversioned_name]
|
||||
end
|
||||
unless version_conflicts.empty?
|
||||
raise CannotInstallFormulaError, <<~EOS
|
||||
#{formula.full_name} contains conflicting version recursive dependencies:
|
||||
#{version_conflicts.to_a.join ", "}
|
||||
View these with `brew deps --tree #{formula.full_name}`.
|
||||
EOS
|
||||
end
|
||||
|
||||
pinned_unsatisfied_deps = recursive_deps.select do |dep|
|
||||
dep.to_formula.pinned? && !dep.satisfied?(inherited_options_for(dep))
|
||||
end
|
||||
|
@ -19,6 +19,7 @@ class LinkageChecker
|
||||
@indirect_deps = []
|
||||
@undeclared_deps = []
|
||||
@unnecessary_deps = []
|
||||
@version_conflict_deps = []
|
||||
|
||||
check_dylibs(rebuild_cache: rebuild_cache)
|
||||
end
|
||||
@ -50,11 +51,14 @@ class LinkageChecker
|
||||
def display_test_output(puts_output: true)
|
||||
display_items "Missing libraries", @broken_dylibs, puts_output: puts_output
|
||||
display_items "Broken dependencies", @broken_deps, puts_output: puts_output
|
||||
display_items "Conflicting libraries", @version_conflict_deps, puts_output: puts_output
|
||||
puts "No broken library linkage" unless broken_library_linkage?
|
||||
end
|
||||
|
||||
def broken_library_linkage?
|
||||
!@broken_dylibs.empty? || !@broken_deps.empty?
|
||||
!@broken_dylibs.empty? ||
|
||||
!@broken_deps.empty? ||
|
||||
!@version_conflict_deps.empty?
|
||||
end
|
||||
|
||||
private
|
||||
@ -127,8 +131,8 @@ class LinkageChecker
|
||||
end
|
||||
|
||||
if formula
|
||||
@indirect_deps, @undeclared_deps, @unnecessary_deps =
|
||||
check_undeclared_deps
|
||||
@indirect_deps, @undeclared_deps, @unnecessary_deps,
|
||||
@version_conflict_deps = check_formula_deps
|
||||
end
|
||||
|
||||
return unless keg_files_dylibs_was_empty
|
||||
@ -136,7 +140,7 @@ class LinkageChecker
|
||||
store&.update!(keg_files_dylibs: keg_files_dylibs)
|
||||
end
|
||||
|
||||
def check_undeclared_deps
|
||||
def check_formula_deps
|
||||
filter_out = proc do |dep|
|
||||
next true if dep.build?
|
||||
next false unless dep.optional? || dep.recommended?
|
||||
@ -170,13 +174,25 @@ class LinkageChecker
|
||||
unnecessary_deps = declared_deps_full_names.reject do |full_name|
|
||||
next true if Formula[full_name].bin.directory?
|
||||
name = full_name.split("/").last
|
||||
@brewed_dylibs.keys.map { |x| x.split("/").last }.include?(name)
|
||||
@brewed_dylibs.keys.map { |l| l.split("/").last }.include?(name)
|
||||
end
|
||||
|
||||
missing_deps = @broken_deps.values.flatten.map { |d| dylib_to_dep(d) }
|
||||
unnecessary_deps -= missing_deps
|
||||
|
||||
[indirect_deps, undeclared_deps, unnecessary_deps]
|
||||
version_hash = {}
|
||||
version_conflict_deps = Set.new
|
||||
@brewed_dylibs.keys.each do |l|
|
||||
name = l.split("/").last
|
||||
unversioned_name, = name.split("@")
|
||||
version_hash[unversioned_name] ||= Set.new
|
||||
version_hash[unversioned_name] << name
|
||||
next if version_hash[unversioned_name].length < 2
|
||||
version_conflict_deps += version_hash[unversioned_name]
|
||||
end
|
||||
|
||||
[indirect_deps, undeclared_deps,
|
||||
unnecessary_deps, version_conflict_deps.to_a]
|
||||
end
|
||||
|
||||
def sort_by_formula_full_name!(arr)
|
||||
|
Loading…
x
Reference in New Issue
Block a user