aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXu Cheng2016-07-07 20:41:14 +0800
committerXu Cheng2016-07-14 15:23:33 +0800
commit13730a9dadde8570e41cf5599b4f5c940014f190 (patch)
tree0a8b35c23598f34c8002305e26375c8b1b42c0df
parent28861ac92d910abbe014a05c4418ee077371d9ca (diff)
downloadbrew-13730a9dadde8570e41cf5599b4f5c940014f190.tar.bz2
move LinkageChecker to standalone file
-rw-r--r--Library/Homebrew/dev-cmd/linkage.rb109
-rw-r--r--Library/Homebrew/os/mac/linkage_checker.rb113
2 files changed, 115 insertions, 107 deletions
diff --git a/Library/Homebrew/dev-cmd/linkage.rb b/Library/Homebrew/dev-cmd/linkage.rb
index 078a3ea74..8ee0e87df 100644
--- a/Library/Homebrew/dev-cmd/linkage.rb
+++ b/Library/Homebrew/dev-cmd/linkage.rb
@@ -12,126 +12,21 @@
# --reverse - For each dylib the keg references, print the dylib followed by the
# binaries which link to it.
-require "set"
-require "keg"
-require "formula"
+require "os/mac/linkage_checker"
module Homebrew
def linkage
- found_broken_dylibs = false
ARGV.kegs.each do |keg|
ohai "Checking #{keg.name} linkage" if ARGV.kegs.size > 1
result = LinkageChecker.new(keg)
if ARGV.include?("--test")
result.display_test_output
+ Homebrew.failed = true if result.broken_dylibs?
elsif ARGV.include?("--reverse")
result.display_reverse_output
else
result.display_normal_output
end
- found_broken_dylibs = true unless result.broken_dylibs.empty?
- end
- if ARGV.include?("--test") && found_broken_dylibs
- exit 1
- end
- end
-
- class LinkageChecker
- attr_reader :keg
- attr_reader :broken_dylibs
-
- def initialize(keg)
- @keg = keg
- @brewed_dylibs = Hash.new { |h, k| h[k] = Set.new }
- @system_dylibs = Set.new
- @broken_dylibs = Set.new
- @variable_dylibs = Set.new
- @reverse_links = Hash.new { |h, k| h[k] = Set.new }
- check_dylibs
- end
-
- def check_dylibs
- @keg.find do |file|
- next if file.symlink? || file.directory?
- next unless file.dylib? || file.mach_o_executable? || file.mach_o_bundle?
- file.dynamically_linked_libraries.each do |dylib|
- @reverse_links[dylib] << file
- if dylib.start_with? "@"
- @variable_dylibs << dylib
- else
- begin
- owner = Keg.for Pathname.new(dylib)
- rescue NotAKegError
- @system_dylibs << dylib
- rescue Errno::ENOENT
- @broken_dylibs << dylib
- else
- @brewed_dylibs[owner.name] << dylib
- end
- end
- end
- end
-
- begin
- f = Formulary.from_rack(keg.rack)
- f.build = Tab.for_keg(keg)
- filter_out = proc do |dep|
- dep.build? || (dep.optional? && !dep.option_names.any? { |n| f.build.with?(n) })
- end
- declared_deps = f.deps.reject { |dep| filter_out.call(dep) }.map(&:name) +
- f.requirements.reject { |req| filter_out.call(req) }.map(&:default_formula).compact
- @undeclared_deps = @brewed_dylibs.keys - declared_deps.map { |dep| dep.split("/").last }
- @undeclared_deps -= [f.name]
- rescue FormulaUnavailableError
- opoo "Formula unavailable: #{keg.name}"
- @undeclared_deps = []
- end
- end
-
- def display_normal_output
- display_items "System libraries", @system_dylibs
- display_items "Homebrew libraries", @brewed_dylibs
- display_items "Variable-referenced libraries", @variable_dylibs
- display_items "Missing libraries", @broken_dylibs
- display_items "Possible undeclared dependencies", @undeclared_deps
- end
-
- def display_reverse_output
- return if @reverse_links.empty?
- sorted = @reverse_links.sort
- sorted.each do |dylib, files|
- puts dylib
- files.each do |f|
- unprefixed = f.to_s.strip_prefix "#{@keg.to_s}/"
- puts " #{unprefixed}"
- end
- puts unless dylib == sorted.last[0]
- end
- end
-
- def display_test_output
- display_items "Missing libraries", @broken_dylibs
- puts "No broken dylib links" if @broken_dylibs.empty?
- end
-
- private
-
- # Display a list of things.
- # Things may either be an array, or a hash of (label -> array)
- def display_items(label, things)
- return if things.empty?
- puts "#{label}:"
- if things.is_a? Hash
- things.sort.each do |list_label, list|
- list.sort.each do |item|
- puts " #{item} (#{list_label})"
- end
- end
- else
- things.sort.each do |item|
- puts " #{item}"
- end
- end
end
end
end
diff --git a/Library/Homebrew/os/mac/linkage_checker.rb b/Library/Homebrew/os/mac/linkage_checker.rb
new file mode 100644
index 000000000..c33b296c7
--- /dev/null
+++ b/Library/Homebrew/os/mac/linkage_checker.rb
@@ -0,0 +1,113 @@
+require "set"
+require "keg"
+require "formula"
+
+class LinkageChecker
+ attr_reader :keg
+ attr_reader :brewed_dylibs, :system_dylibs, :broken_dylibs, :variable_dylibs
+ attr_reader :undeclared_deps, :reverse_links
+
+ def initialize(keg)
+ @keg = keg
+ @brewed_dylibs = Hash.new { |h, k| h[k] = Set.new }
+ @system_dylibs = Set.new
+ @broken_dylibs = Set.new
+ @variable_dylibs = Set.new
+ @undeclared_deps = []
+ @reverse_links = Hash.new { |h, k| h[k] = Set.new }
+ check_dylibs
+ end
+
+ def check_dylibs
+ @keg.find do |file|
+ next if file.symlink? || file.directory?
+ next unless file.dylib? || file.mach_o_executable? || file.mach_o_bundle?
+ file.dynamically_linked_libraries.each do |dylib|
+ @reverse_links[dylib] << file
+ if dylib.start_with? "@"
+ @variable_dylibs << dylib
+ else
+ begin
+ owner = Keg.for Pathname.new(dylib)
+ rescue NotAKegError
+ @system_dylibs << dylib
+ rescue Errno::ENOENT
+ @broken_dylibs << dylib
+ else
+ @brewed_dylibs[owner.name] << dylib
+ end
+ end
+ end
+ end
+
+ begin
+ f = Formulary.from_rack(keg.rack)
+ f.build = Tab.for_keg(keg)
+ filter_out = proc do |dep|
+ dep.build? || (dep.optional? && !dep.option_names.any? { |n| f.build.with?(n) })
+ end
+ declared_deps = f.deps.reject { |dep| filter_out.call(dep) }.map(&:name) +
+ f.requirements.reject { |req| filter_out.call(req) }.map(&:default_formula).compact
+ @undeclared_deps = @brewed_dylibs.keys - declared_deps.map { |dep| dep.split("/").last }
+ @undeclared_deps -= [f.name]
+ rescue FormulaUnavailableError
+ opoo "Formula unavailable: #{keg.name}"
+ end
+ end
+
+ def display_normal_output
+ display_items "System libraries", @system_dylibs
+ display_items "Homebrew libraries", @brewed_dylibs
+ display_items "Variable-referenced libraries", @variable_dylibs
+ display_items "Missing libraries", @broken_dylibs
+ display_items "Possible undeclared dependencies", @undeclared_deps
+ end
+
+ def display_reverse_output
+ return if @reverse_links.empty?
+ sorted = @reverse_links.sort
+ sorted.each do |dylib, files|
+ puts dylib
+ files.each do |f|
+ unprefixed = f.to_s.strip_prefix "#{@keg}/"
+ puts " #{unprefixed}"
+ end
+ puts unless dylib == sorted.last[0]
+ end
+ end
+
+ def display_test_output
+ display_items "Missing libraries", @broken_dylibs
+ puts "No broken dylib links" if @broken_dylibs.empty?
+ display_items "Possible undeclared dependencies", @undeclared_deps
+ puts "No undeclared dependencies" if @undeclared_deps.empty?
+ end
+
+ def broken_dylibs?
+ !@broken_dylibs.empty?
+ end
+
+ def undeclared_deps?
+ !@undeclared_deps.empty?
+ end
+
+ private
+
+ # Display a list of things.
+ # Things may either be an array, or a hash of (label -> array)
+ def display_items(label, things)
+ return if things.empty?
+ puts "#{label}:"
+ if things.is_a? Hash
+ things.sort.each do |list_label, list|
+ list.sort.each do |item|
+ puts " #{item} (#{list_label})"
+ end
+ end
+ else
+ things.sort.each do |item|
+ puts " #{item}"
+ end
+ end
+ end
+end