Class: RuboCop::Cop::FormulaAudit::DependencyOrder Private

Inherits:
RuboCop::Cop::FormulaCop show all
Extended by:
AutoCorrector
Defined in:
rubocops/dependency_order.rb,
sorbet/rbi/dsl/rubo_cop/cop/formula_audit/dependency_order.rbi

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.

This cop checks for correct order of depends_on in formulae.

precedence order: build-time > test > normal > recommended > optional

Instance Attribute Summary

Attributes inherited from RuboCop::Cop::FormulaCop

#file_path

Instance Method Summary collapse

Methods inherited from RuboCop::Cop::FormulaCop

#audit_comments, #audit_urls, #caveats_strings, #dependency_name_hash_match?, #dependency_type_hash_match?, #depends_on?, #depends_on_name_type?, #formula_tap, #get_checksum_node, #on_class, #required_dependency?, #required_dependency_name?, #style_exceptions_dir, #tap_style_exception?, #versioned_formula?

Methods included from HelperFunctions

#block_method_called_in_block?, #check_precedence, #class_name, #component_precedes?, #end_column, #expression_negated?, #find_all_blocks, #find_block, #find_blocks, #find_const, #find_every_func_call_by_name, #find_every_method_call_by_name, #find_instance_call, #find_instance_method_call, #find_method_calls_by_name, #find_method_def, #find_method_with_args, #find_node_method_by_name, #find_strings, #format_component, #line_number, #line_start_column, #method_called?, #method_called_ever?, #method_name, #node_equals?, #offending_node, #parameters, #parameters_passed?, #problem, #regex_match_group, #source_buffer, #start_column, #string_content

Instance Method Details

#audit_formula(formula_nodes) ⇒ void

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.

Parameters:



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'rubocops/dependency_order.rb', line 17

def audit_formula(formula_nodes)
  body_node = formula_nodes.body_node

  check_dependency_nodes_order(body_node)
  check_uses_from_macos_nodes_order(body_node)
  ([:head, :stable] + on_system_methods).each do |block_name|
    block = find_block(body_node, block_name)
    next unless block

    check_dependency_nodes_order(block.body)
    check_uses_from_macos_nodes_order(block.body)
  end
end

#build_with_dependency_name(node) ⇒ Array<String>?

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:



175
176
177
178
179
# File 'rubocops/dependency_order.rb', line 175

def build_with_dependency_name(node)
  match_nodes = build_with_dependency_node(node)
  match_nodes = match_nodes.to_a.compact
  match_nodes.map { |n| string_content(n) } unless match_nodes.empty?
end

#build_with_dependency_node(node, *pattern, **kwargs, &block) ⇒ T.untyped

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.untyped)


17
# File 'sorbet/rbi/dsl/rubo_cop/cop/formula_audit/dependency_order.rbi', line 17

def build_with_dependency_node(node, *pattern, **kwargs, &block); end

#buildtime_dependency?(node, *pattern, **kwargs, &block) ⇒ 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:

Returns:

  • (Boolean)


27
# File 'sorbet/rbi/dsl/rubo_cop/cop/formula_audit/dependency_order.rbi', line 27

def buildtime_dependency?(node, *pattern, **kwargs, &block); end

#check_dependency_nodes_order(parent_node) ⇒ void

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.

Parameters:



40
41
42
43
44
45
# File 'rubocops/dependency_order.rb', line 40

def check_dependency_nodes_order(parent_node)
  return if parent_node.nil?

  dependency_nodes = parent_node.each_child_node.select { |x| depends_on_node?(x) }
  ensure_dependency_order(dependency_nodes)
end

#check_uses_from_macos_nodes_order(parent_node) ⇒ void

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.

Parameters:



32
33
34
35
36
37
# File 'rubocops/dependency_order.rb', line 32

def check_uses_from_macos_nodes_order(parent_node)
  return if parent_node.nil?

  dependency_nodes = parent_node.each_child_node.select { |x| uses_from_macos_node?(x) }
  ensure_dependency_order(dependency_nodes)
end

#dependency_name(dependency_node) ⇒ String?

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:



182
183
184
185
# File 'rubocops/dependency_order.rb', line 182

def dependency_name(dependency_node)
  match_node = dependency_name_node(dependency_node).to_a.first
  string_content(match_node) if match_node
end

#dependency_name_node(node, *pattern, **kwargs, &block) ⇒ T.untyped

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.untyped)


37
# File 'sorbet/rbi/dsl/rubo_cop/cop/formula_audit/dependency_order.rbi', line 37

def dependency_name_node(node, *pattern, **kwargs, &block); end

#depends_on_node?(node, **kwargs, &block) ⇒ T.untyped

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.untyped)


40
# File 'sorbet/rbi/dsl/rubo_cop/cop/formula_audit/dependency_order.rbi', line 40

def depends_on_node?(node, **kwargs, &block); end

#ensure_dependency_order(nodes) ⇒ void

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.

Parameters:



48
49
50
51
52
53
54
55
56
57
58
59
# File 'rubocops/dependency_order.rb', line 48

def ensure_dependency_order(nodes)
  name_node_pairs = nodes.filter_map do |node|
    name = dependency_name(node)
    next unless name

    [name, node]
  end
  name_node_pairs.sort_by! { |name, _| name.downcase }
  ordered = sort_dependencies_by_type(name_node_pairs.map { |_, node| node })
  sort_conditional_dependencies!(ordered)
  verify_order_in_source(ordered)
end

#insert_after!(arr, idx1, idx2) ⇒ void

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.

Parameters:



167
168
169
170
171
172
# File 'rubocops/dependency_order.rb', line 167

def insert_after!(arr, idx1, idx2)
  arr.insert(
    idx2+1,
    arr.delete_at(idx1) || raise("unexpected nil value for arr.delete_at(idx1)"),
  )
end

#negate_normal_dependency?(node, *pattern, **kwargs, &block) ⇒ 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:

Returns:

  • (Boolean)


50
# File 'sorbet/rbi/dsl/rubo_cop/cop/formula_audit/dependency_order.rbi', line 50

def negate_normal_dependency?(node, *pattern, **kwargs, &block); end

#optional_dependency?(node, *pattern, **kwargs, &block) ⇒ 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:

Returns:

  • (Boolean)


60
# File 'sorbet/rbi/dsl/rubo_cop/cop/formula_audit/dependency_order.rbi', line 60

def optional_dependency?(node, *pattern, **kwargs, &block); end

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:

  • (Boolean)


70
# File 'sorbet/rbi/dsl/rubo_cop/cop/formula_audit/dependency_order.rbi', line 70

def recommended_dependency?(node, *pattern, **kwargs, &block); end

#sort_conditional_dependencies!(ordered) ⇒ Array<RuboCop::AST::Node>

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.

depends_on :apple if build.with? "foo" should always be defined after depends_on :foo. This method reorders the dependencies array according to the above rule.

Parameters:

Returns:



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'rubocops/dependency_order.rb', line 82

def sort_conditional_dependencies!(ordered)
  length = ordered.size
  idx = 0
  while idx < length
    idx1 = T.let(nil, T.nilable(Integer))
    idx2 = T.let(nil, T.nilable(Integer))
    ordered.each_with_index do |dep, pos|
      idx = pos+1
      match_nodes = build_with_dependency_name(dep)
      next if match_nodes.blank?

      idx1 = pos
      ordered.drop(idx1+1).each_with_index do |dep2, pos2|
        next unless match_nodes.index(dependency_name(dep2))

        idx2 = pos2 if idx2.nil? || pos2 > idx2
      end
      break if idx2
    end
    insert_after!(ordered, idx1, idx2 + idx1) if idx1 &&idx2
  end
  ordered
end

#sort_dependencies_by_type(dependency_nodes) ⇒ Array<RuboCop::AST::Node>

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.

Separate dependencies according to precedence order: build-time > test > normal > recommended > optional

Parameters:

Returns:



64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'rubocops/dependency_order.rb', line 64

def sort_dependencies_by_type(dependency_nodes)
  unsorted_deps = dependency_nodes.to_a
  ordered = []
  ordered.concat(unsorted_deps.select { |dep| buildtime_dependency? dep })
  unsorted_deps -= ordered
  ordered.concat(unsorted_deps.select { |dep| test_dependency? dep })
  unsorted_deps -= ordered
  ordered.concat(unsorted_deps.reject { |dep| negate_normal_dependency? dep })
  unsorted_deps -= ordered
  ordered.concat(unsorted_deps.select { |dep| recommended_dependency? dep })
  unsorted_deps -= ordered
  ordered.concat(unsorted_deps.select { |dep| optional_dependency? dep })
end

#test_dependency?(node, *pattern, **kwargs, &block) ⇒ 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:

Returns:

  • (Boolean)


80
# File 'sorbet/rbi/dsl/rubo_cop/cop/formula_audit/dependency_order.rbi', line 80

def test_dependency?(node, *pattern, **kwargs, &block); end

#uses_from_macos_node?(node, **kwargs, &block) ⇒ T.untyped

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.untyped)


83
# File 'sorbet/rbi/dsl/rubo_cop/cop/formula_audit/dependency_order.rbi', line 83

def uses_from_macos_node?(node, **kwargs, &block); end

#verify_order_in_source(ordered) ⇒ void

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.

Verify actual order of sorted depends_on nodes in source code; raise RuboCop problem otherwise.

Parameters:



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'rubocops/dependency_order.rb', line 109

def verify_order_in_source(ordered)
  ordered.each_with_index do |node_1, idx|
    l1 = line_number(node_1)
    l2 = T.let(nil, T.nilable(Integer))
    node_2 = T.let(nil, T.nilable(RuboCop::AST::Node))
    ordered.drop(idx + 1).each do |test_node|
      l2 = line_number(test_node)
      node_2 = test_node if l2 < l1
    end
    next unless node_2

    offending_node(node_1)

    problem "`dependency \"#{dependency_name(node_1)}\"` (line #{l1}) should be put before " \
            "`dependency \"#{dependency_name(node_2)}\"` (line #{l2})" do |corrector|
      indentation = " " * (start_column(node_2) - line_start_column(node_2))
      line_breaks = "\n"
      corrector.insert_before(node_2.source_range,
                              node_1.source + line_breaks + indentation)
      corrector.remove(range_with_surrounding_space(range: node_1.source_range, side: :left))
    end
  end
end