Class: RuboCop::Cop::FormulaAuditStrict::TestResource Private

Inherits:
RuboCop::Cop::FormulaCop show all
Extended by:
AutoCorrector
Defined in:
rubocops/class.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.

This cop moves resource declarations outside test blocks for prefetching.

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_name, #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?, descendant_send_nodes, descendant_send_nodes_by_method_name, #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:



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'rubocops/class.rb', line 79

def audit_formula(formula_nodes)
  test = find_block(formula_nodes.body_node, :test)
  return unless test

  find_all_blocks(test, :resource).reverse_each do |resource|
    next if resource.send_node.receiver

    add_offense(
      resource.send_node,
      message: 'Declare test resources outside `test do` using `resource "name", :test do`.',
    ) do |corrector|
      next if find_every_method_call_by_name(formula_nodes.body_node, :resources).any?

      name = resource.send_node.first_argument
      next unless name&.str_type?
      next if resource.parent != test && resource.parent != test.body
      next if resource.single_line? || test.single_line?
      if !resource.send_node.arguments.one? &&
         (resource.send_node.arguments.size != 2 || resource.send_node.last_argument&.source != ":test")
        next
      end

      # Moving runtime expressions or multiline strings can change their meaning.
      next if resource.each_descendant.any? do |node|
        next false if node.true_type? || node.false_type?

        if node.is_a?(RuboCop::AST::SendNode)
          node.receiver || ![:resource, :url, :sha256, :mirror, :version, :patch].include?(node.method_name)
        else
          ![:block, :args, :begin, :str, :sym, :int, :nil, :hash, :pair, :array].include?(node.type) ||
          (node.is_a?(RuboCop::AST::StrNode) && (node.multiline? || node.heredoc?))
        end
      end

      range = range_with_comments_and_lines(resource)
      next unless resource.source_range.source_line[0...resource.source_range.column].strip.empty?

      trailing = range.source_buffer.source[resource.source_range.end_pos...range.end_pos].strip
      next if trailing.present? && !trailing.start_with?("#")

      source = range.source
      if resource.send_node.arguments.one?
        source.insert(name.source_range.end_pos - range.begin_pos,
                      ", :test")
      end
      source = source.gsub(/^ {#{resource.source_range.column - test.source_range.column}}/, "")
      corrector.insert_before(range_with_comments_and_lines(test), "#{source}\n")
      range = range.adjust(end_pos: 1) if range.source_buffer.source[range.end_pos] == "\n"
      corrector.remove(range)
    end
  end
end