Class: Dependency

Inherits:
Object show all
Extended by:
Cachable
Includes:
Dependable
Defined in:
dependency.rb

Overview

This class is part of an internal API. This class may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this class if possible, as it may be removed or changed without warning.

A dependency on another Homebrew formula.

Direct Known Subclasses

UsesFromMacOSDependency

Constant Summary

Constants included from Dependable

Dependable::RESERVED_TAGS

Instance Attribute Summary collapse

Attributes included from Dependable

#tags

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Cachable

cache, clear_cache

Methods included from Dependable

#build?, #implicit?, #option_tags, #optional?, #options, #prune_from_option?, #prune_if_build_and_not_dependent?, #recommended?, #required?, #test?

Constructor Details

#initialize(name, tags = []) ⇒ Dependency

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns a new instance of Dependency.

Raises:

  • (ArgumentError)


19
20
21
22
23
24
25
26
27
28
# File 'dependency.rb', line 19

def initialize(name, tags = [])
  raise ArgumentError, "Dependency must have a name!" unless name

  @name = name
  @tags = tags

  return unless (tap_with_name = Tap.with_formula_name(name))

  @tap, = tap_with_name
end

Instance Attribute Details

#nameString (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.

Returns:



14
15
16
# File 'dependency.rb', line 14

def name
  @name
end

#tapTap? (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.

Returns:



17
18
19
# File 'dependency.rb', line 17

def tap
  @tap
end

Class Method Details

.action(dependent, dep, &block) ⇒ Object

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



170
171
172
173
174
175
176
177
178
# File 'dependency.rb', line 170

def action(dependent, dep, &block)
  catch(:action) do
    if block
      yield dependent, dep
    elsif dep.optional? || dep.recommended?
      prune unless dependent.build.with?(dep)
    end
  end
end

.expand(dependent, deps = dependent.deps, cache_key: nil, &block) ⇒ Object

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Expand the dependencies of each dependent recursively, optionally yielding [dependent, dep] pairs to allow callers to apply arbitrary filters to the list. The default filter, which is applied when a block is not given, omits optionals and recommends based on what the dependent has asked for



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'dependency.rb', line 127

def expand(dependent, deps = dependent.deps, cache_key: nil, &block)
  # Keep track dependencies to avoid infinite cyclic dependency recursion.
  @expand_stack ||= []
  @expand_stack.push dependent.name

  if cache_key.present?
    cache[cache_key] ||= {}
    return cache[cache_key][cache_id dependent].dup if cache[cache_key][cache_id dependent]
  end

  expanded_deps = []

  deps.each do |dep|
    next if dependent.name == dep.name

    case action(dependent, dep, &block)
    when :prune
      next
    when :skip
      next if @expand_stack.include? dep.name

      expanded_deps.concat(expand(dep.to_formula, cache_key:, &block))
    when :keep_but_prune_recursive_deps
      expanded_deps << dep
    else
      next if @expand_stack.include? dep.name

      dep_formula = dep.to_formula
      expanded_deps.concat(expand(dep_formula, cache_key:, &block))

      # Fixes names for renamed/aliased formulae.
      dep = dep.dup_with_formula_name(dep_formula)
      expanded_deps << dep
    end
  end

  expanded_deps = merge_repeats(expanded_deps)
  cache[cache_key][cache_id dependent] = expanded_deps.dup if cache_key.present?
  expanded_deps
ensure
  @expand_stack.pop
end

.keep_but_prune_recursive_depsvoid

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.

Keep a dependency, but prune its dependencies.



196
197
198
# File 'dependency.rb', line 196

def keep_but_prune_recursive_deps
  throw(:action, :keep_but_prune_recursive_deps)
end

.merge_repeats(all) ⇒ Object

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



200
201
202
203
204
205
206
207
208
209
210
211
# File 'dependency.rb', line 200

def merge_repeats(all)
  grouped = all.group_by(&:name)

  all.map(&:name).uniq.map do |name|
    deps = grouped.fetch(name)
    dep  = deps.first
    tags = merge_tags(deps)
    kwargs = {}
    kwargs[:bounds] = dep.bounds if dep.uses_from_macos?
    dep.class.new(name, tags, **kwargs)
  end
end

.prunevoid

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.

This method returns an undefined value.

Prune a dependency and its dependencies recursively.



182
183
184
# File 'dependency.rb', line 182

def prune
  throw(:action, :prune)
end

.skipvoid

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.

This method returns an undefined value.

Prune a single dependency but do not prune its dependencies.



188
189
190
# File 'dependency.rb', line 188

def skip
  throw(:action, :skip)
end

Instance Method Details

#dup_with_formula_name(formula) ⇒ T.self_type

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.

Parameters:

Returns:

  • (T.self_type)


115
116
117
# File 'dependency.rb', line 115

def dup_with_formula_name(formula)
  self.class.new(formula.full_name.to_s, tags)
end

#installed?(minimum_version: nil, minimum_revision: nil) ⇒ 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.

Parameters:

  • minimum_version (Version, nil) (defaults to: nil)
  • minimum_revision (Integer, nil) (defaults to: nil)

Returns:

  • (Boolean)


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'dependency.rb', line 46

def installed?(minimum_version: nil, minimum_revision: nil)
  formula = begin
    to_formula
  rescue FormulaUnavailableError
    nil
  end
  return false unless formula

  return true if formula.latest_version_installed?

  return false if minimum_version.blank?

  # If the opt prefix doesn't exist: we likely have an incomplete installation.
  return false unless formula.opt_prefix.exist?

  installed_keg = formula.any_installed_keg
  return false unless installed_keg

  # If the keg name doesn't match, we may have moved from an alias to a full formula and need to upgrade.
  return false unless formula.possible_names.include?(installed_keg.name)

  installed_version = installed_keg.version

  # Tabs prior to 4.1.18 did not have revision or pkg_version fields.
  # As a result, we have to be more conversative when we do not have
  # a minimum revision from the tab and assume that if the formula has a
  # the same version and a non-zero revision that it needs upgraded.
  if minimum_revision.present?
    minimum_pkg_version = PkgVersion.new(minimum_version, minimum_revision)
    installed_version >= minimum_pkg_version
  elsif installed_version.version == minimum_version
    formula.revision.zero?
  else
    installed_version.version > minimum_version
  end
end

#missing_options(inherited_options) ⇒ Object

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



88
89
90
91
92
93
94
95
# File 'dependency.rb', line 88

def missing_options(inherited_options)
  formula = to_formula
  required = options
  required |= inherited_options
  required &= formula.options.to_a
  required -= Tab.for_formula(formula).used_options
  required
end

#option_namesObject

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



97
98
99
# File 'dependency.rb', line 97

def option_names
  [name.split("/").last].freeze
end

#satisfied?(inherited_options = [], minimum_version: nil, minimum_revision: nil) ⇒ Boolean

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


83
84
85
86
# File 'dependency.rb', line 83

def satisfied?(inherited_options = [], minimum_version: nil, minimum_revision: nil)
  installed?(minimum_version:, minimum_revision:) &&
    missing_options(inherited_options).empty?
end

#to_formulaObject

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



39
40
41
42
43
# File 'dependency.rb', line 39

def to_formula
  formula = Formulary.factory(name, warn: false)
  formula.build = BuildOptions.new(options, formula.options)
  formula
end

#uses_from_macos?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)


102
103
104
# File 'dependency.rb', line 102

def uses_from_macos?
  false
end