Class: LinkageChecker Private

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
linkage_checker.rb,
extend/os/linux/linkage_checker.rb

Overview

This class is part of a private API. This class may only be used in the Homebrew/brew repository. Third parties should avoid using this class if possible, as it may be removed or changed without warning.

Check for broken/missing linkage in a formula’s keg.

Constant Summary collapse

SYSTEM_LIBRARY_ALLOWLIST =

Libraries provided by glibc and gcc.

%w[
  ld-linux-x86-64.so.2
  libanl.so.1
  libc.so.6
  libcrypt.so.1
  libdl.so.2
  libm.so.6
  libmvec.so.1
  libnsl.so.1
  libpthread.so.0
  libresolv.so.2
  librt.so.1
  libthread_db.so.1
  libutil.so.1
  libgcc_s.so.1
  libgomp.so.1
  libstdc++.so.6
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(keg, formula = nil, cache_db:, rebuild_cache: false) ⇒ LinkageChecker

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns a new instance of LinkageChecker.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'linkage_checker.rb', line 17

def initialize(keg, formula = nil, cache_db:, rebuild_cache: false)
  @keg = keg
  @formula = formula || resolve_formula(keg)
  @store = LinkageCacheStore.new(keg.to_s, cache_db)

  @system_dylibs    = Set.new
  @broken_dylibs    = Set.new
  @unexpected_broken_dylibs = nil
  @unexpected_present_dylibs = nil
  @variable_dylibs  = Set.new
  @brewed_dylibs    = Hash.new { |h, k| h[k] = Set.new }
  @reverse_links    = Hash.new { |h, k| h[k] = Set.new }
  @broken_deps      = Hash.new { |h, k| h[k] = [] }
  @indirect_deps    = []
  @undeclared_deps  = []
  @unnecessary_deps = []
  @unwanted_system_dylibs = []
  @version_conflict_deps = []

  check_dylibs(rebuild_cache: rebuild_cache)
end

Instance Attribute Details

#formulaObject (readonly)

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



15
16
17
# File 'linkage_checker.rb', line 15

def formula
  @formula
end

#kegObject (readonly)

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



15
16
17
# File 'linkage_checker.rb', line 15

def keg
  @keg
end

#storeObject (readonly)

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



15
16
17
# File 'linkage_checker.rb', line 15

def store
  @store
end

#undeclared_depsObject (readonly)

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



15
16
17
# File 'linkage_checker.rb', line 15

def undeclared_deps
  @undeclared_deps
end

Instance Method Details

#broken_dylibs_with_expectationsObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



107
108
109
110
111
112
113
114
115
116
117
# File 'linkage_checker.rb', line 107

def broken_dylibs_with_expectations
  output = {}
  @broken_dylibs.each do |broken_lib|
    output[broken_lib] = if unexpected_broken_dylibs.include? broken_lib
      ["unexpected"]
    else
      ["expected"]
    end
  end
  output
end

#broken_library_linkage?Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


74
75
76
77
# File 'linkage_checker.rb', line 74

def broken_library_linkage?
  issues = [@broken_deps, @unwanted_system_dylibs, @version_conflict_deps]
  [issues, unexpected_broken_dylibs, unexpected_present_dylibs].flatten.any?(&:present?)
end

#display_normal_outputObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



39
40
41
42
43
44
45
46
47
48
49
# File 'linkage_checker.rb', line 39

def display_normal_output
  display_items "System libraries", @system_dylibs
  display_items "Homebrew libraries", @brewed_dylibs
  display_items "Indirect dependencies with linkage", @indirect_deps
  display_items "Variable-referenced libraries", @variable_dylibs
  display_items "Missing libraries", @broken_dylibs
  display_items "Broken dependencies", @broken_deps
  display_items "Undeclared dependencies with linkage", @undeclared_deps
  display_items "Dependencies with no linkage", @unnecessary_deps
  display_items "Unwanted system libraries", @unwanted_system_dylibs
end

#display_reverse_outputObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'linkage_checker.rb', line 51

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.delete_prefix "#{keg}/"
      puts "  #{unprefixed}"
    end
    puts if dylib != sorted.last.first
  end
end

#display_test_output(puts_output: true) ⇒ Object

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



65
66
67
68
69
70
71
# File 'linkage_checker.rb', line 65

def display_test_output(puts_output: true)
  display_items "Missing libraries", broken_dylibs_with_expectations, puts_output: puts_output
  display_items "Unused missing linkage information", unexpected_present_dylibs, puts_output: puts_output
  display_items "Broken dependencies", @broken_deps, puts_output: puts_output
  display_items "Unwanted system libraries", @unwanted_system_dylibs, puts_output: puts_output
  display_items "Conflicting libraries", @version_conflict_deps, puts_output: puts_output
end

#unexpected_broken_dylibsObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'linkage_checker.rb', line 79

def unexpected_broken_dylibs
  return @unexpected_broken_dylibs if @unexpected_broken_dylibs

  @unexpected_broken_dylibs = @broken_dylibs.reject do |broken_lib|
    @formula.class.allowed_missing_libraries.any? do |allowed_missing_lib|
      case allowed_missing_lib
      when Regexp
        allowed_missing_lib.match? broken_lib
      when String
        broken_lib.include? allowed_missing_lib
      end
    end
  end
end

#unexpected_present_dylibsObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



94
95
96
97
98
99
100
101
102
103
104
105
# File 'linkage_checker.rb', line 94

def unexpected_present_dylibs
  @unexpected_present_dylibs ||= @formula.class.allowed_missing_libraries.reject do |allowed_missing_lib|
    @broken_dylibs.any? do |broken_lib|
      case allowed_missing_lib
      when Regexp
        allowed_missing_lib.match? broken_lib
      when String
        broken_lib.include? allowed_missing_lib
      end
    end
  end
end