Class: RuboCop::Cop::FormulaCop Abstract Private

Inherits:
Base
  • Object
show all
Extended by:
T::Helpers
Includes:
RangeHelp, HelperFunctions
Defined in:
rubocops/extend/formula_cop.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 class is abstract.

It cannot be directly instantiated. Subclasses must implement the abstract methods below.

Abstract base class for all formula cops.

Direct Known Subclasses

RuboCop::Cop::FormulaAudit::AssertStatements, RuboCop::Cop::FormulaAudit::BottleDigestIndentation, RuboCop::Cop::FormulaAudit::BottleFormat, RuboCop::Cop::FormulaAudit::BottleOrder, RuboCop::Cop::FormulaAudit::BottleTagIndentation, RuboCop::Cop::FormulaAudit::Caveats, RuboCop::Cop::FormulaAudit::Checksum, RuboCop::Cop::FormulaAudit::ChecksumCase, RuboCop::Cop::FormulaAudit::ClassInheritance, RuboCop::Cop::FormulaAudit::ClassName, RuboCop::Cop::FormulaAudit::Comments, RuboCop::Cop::FormulaAudit::ComponentsOrder, RuboCop::Cop::FormulaAudit::ComponentsRedundancy, RuboCop::Cop::FormulaAudit::Conflicts, RuboCop::Cop::FormulaAudit::DependencyOrder, RuboCop::Cop::FormulaAudit::DeprecateDisableDate, RuboCop::Cop::FormulaAudit::DeprecateDisableReason, RuboCop::Cop::FormulaAudit::Desc, RuboCop::Cop::FormulaAudit::Files, RuboCop::Cop::FormulaAudit::GenerateCompletionsDSL, RuboCop::Cop::FormulaAudit::GitUrls, RuboCop::Cop::FormulaAudit::Homepage, RuboCop::Cop::FormulaAudit::KegOnly, RuboCop::Cop::FormulaAudit::LicenseArrays, RuboCop::Cop::FormulaAudit::Licenses, RuboCop::Cop::FormulaAudit::Lines, RuboCop::Cop::FormulaAudit::LivecheckRegexCaseInsensitive, RuboCop::Cop::FormulaAudit::LivecheckRegexExtension, RuboCop::Cop::FormulaAudit::LivecheckRegexIfPageMatch, RuboCop::Cop::FormulaAudit::LivecheckRegexParentheses, RuboCop::Cop::FormulaAudit::LivecheckSkip, RuboCop::Cop::FormulaAudit::LivecheckUrlProvided, RuboCop::Cop::FormulaAudit::LivecheckUrlSymbol, RuboCop::Cop::FormulaAudit::MacOSOnLinux, RuboCop::Cop::FormulaAudit::Miscellaneous, RuboCop::Cop::FormulaAudit::MpiCheck, RuboCop::Cop::FormulaAudit::OnSystemConditionals, RuboCop::Cop::FormulaAudit::OptionDeclarations, RuboCop::Cop::FormulaAudit::Options, RuboCop::Cop::FormulaAudit::Patches, RuboCop::Cop::FormulaAudit::ProvidedByMacos, RuboCop::Cop::FormulaAudit::PyPiUrls, RuboCop::Cop::FormulaAudit::PyoxidizerCheck, RuboCop::Cop::FormulaAudit::PythonVersions, RuboCop::Cop::FormulaAudit::QuicTLSCheck, RuboCop::Cop::FormulaAudit::ResourceRequiresDependencies, RuboCop::Cop::FormulaAudit::SafePopenCommands, RuboCop::Cop::FormulaAudit::Service, RuboCop::Cop::FormulaAudit::ShellVariables, RuboCop::Cop::FormulaAudit::SingleGenerateCompletionsDSLCall, RuboCop::Cop::FormulaAudit::Test, RuboCop::Cop::FormulaAudit::Text, RuboCop::Cop::FormulaAudit::Urls, RuboCop::Cop::FormulaAudit::UsesFromMacos, RuboCop::Cop::FormulaAudit::Version, RuboCop::Cop::FormulaAuditStrict::GitUrls, RuboCop::Cop::FormulaAuditStrict::MakeCheck, RuboCop::Cop::FormulaAuditStrict::Requirements, RuboCop::Cop::FormulaAuditStrict::RustCheck, RuboCop::Cop::FormulaAuditStrict::TestPresent, RuboCop::Cop::FormulaAuditStrict::Text

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from HelperFunctions

#block_method_called_in_block?, #block_size, #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, #size, #source_buffer, #start_column, #string_content

Instance Attribute Details

#file_pathObject

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.



19
20
21
# File 'rubocops/extend/formula_cop.rb', line 19

def file_path
  @file_path
end

Instance Method Details

#audit_commentsObject

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.

Yields to a block with comment text as parameter.



150
151
152
153
154
155
# File 'rubocops/extend/formula_cop.rb', line 150

def audit_comments
  processed_source.comments.each do |comment_node|
    @offensive_node = comment_node
    yield comment_node.text
  end
end

#audit_formula(node, class_node, parent_class_node, body_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 is abstract.

This method returns an undefined value.

Parameters:

  • node (RuboCop::AST::ClassNode)
  • class_node (RuboCop::AST::ConstNode)
  • parent_class_node (RuboCop::AST::ConstNode)
  • body_node (RuboCop::AST::Node)


44
# File 'rubocops/extend/formula_cop.rb', line 44

def audit_formula(node, class_node, parent_class_node, body_node); end

#audit_urls(urls, regex) ⇒ 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.

Yields to block when there is a match.

Parameters:

  • urls (Array)

    url/mirror method call nodes

  • regex (Regexp)

    pattern to match URLs



50
51
52
53
54
55
56
57
58
59
60
# File 'rubocops/extend/formula_cop.rb', line 50

def audit_urls(urls, regex)
  urls.each_with_index do |url_node, index|
    url_string_node = parameters(url_node).first
    url_string = string_content(url_string_node)
    match_object = regex_match_group(url_string_node, regex)
    next unless match_object

    offending_node(url_string_node.parent)
    yield match_object, url_string, index
  end
end

#caveats_stringsObject

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.

Return all the caveats’ string nodes in an array.



121
122
123
124
125
# File 'rubocops/extend/formula_cop.rb', line 121

def caveats_strings
  return [] if @body.nil?

  find_strings(find_method_def(@body, :caveats))
end

#depends_on?(dependency_name, *types) ⇒ 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 if the formula depends on dependency_name.

Parameters:

  • dependency_name

    dependency’s name

Returns:

  • (Boolean)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'rubocops/extend/formula_cop.rb', line 65

def depends_on?(dependency_name, *types)
  return false if @body.nil?

  types = [:any] if types.empty?
  dependency_nodes = find_every_method_call_by_name(@body, :depends_on)
  idx = dependency_nodes.index do |n|
    types.any? { |type| depends_on_name_type?(n, dependency_name, type) }
  end
  return false if idx.nil?

  @offensive_node = dependency_nodes[idx]

  true
end

#depends_on_name_type?(node, name = nil, type = :required) ⇒ 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 true if given dependency name and dependency type exist in given dependency method call node.

Returns:

  • (Boolean)


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

def depends_on_name_type?(node, name = nil, type = :required)
  name_match = !name # Match only by type when name is nil

  case type
  when :required
    type_match = required_dependency?(node)
    name_match ||= required_dependency_name?(node, name) if type_match
  when :build, :test, :optional, :recommended
    type_match = dependency_type_hash_match?(node, type)
    name_match ||= dependency_name_hash_match?(node, name) if type_match
  when :any
    type_match = true
    name_match ||= required_dependency_name?(node, name)
    name_match ||= dependency_name_hash_match?(node, name)
  else
    type_match = false
  end

  @offensive_node = node if type_match || name_match
  type_match && name_match
end

#formula_tapObject

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 the formula tap.



163
164
165
166
167
# File 'rubocops/extend/formula_cop.rb', line 163

def formula_tap
  return unless (match_obj = @file_path.match(%r{/(homebrew-\w+)/}))

  match_obj[1]
end

#get_checksum_node(call) ⇒ 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.

Returns the sha256 str node given a sha256 call node.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'rubocops/extend/formula_cop.rb', line 128

def get_checksum_node(call)
  return if parameters(call).empty? || parameters(call).nil?

  if parameters(call).first.str_type?
    parameters(call).first
  # sha256 is passed as a key-value pair in bottle blocks
  elsif parameters(call).first.hash_type?
    if parameters(call).first.keys.first.value == :cellar
      # sha256 :cellar :any, :tag "hexdigest"
      parameters(call).first.values.last
    elsif parameters(call).first.keys.first.is_a?(RuboCop::AST::SymbolNode)
      # sha256 :tag "hexdigest"
      parameters(call).first.values.first
    else
      # Legacy bottle block syntax
      # sha256 "hexdigest" => :tag
      parameters(call).first.keys.first
    end
  end
end

#on_class(node) ⇒ 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.

This method is called by RuboCop and is the main entry point.



24
25
26
27
28
29
30
31
32
33
# File 'rubocops/extend/formula_cop.rb', line 24

def on_class(node)
  @file_path = processed_source.buffer.name
  return unless file_path_allowed?
  return unless formula_class?(node)

  class_node, parent_class_node, @body = *node
  @formula_name = Pathname.new(@file_path).basename(".rb").to_s
  @tap_style_exceptions = nil
  audit_formula(node, class_node, parent_class_node, @body)
end

#style_exceptions_dirObject

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 the style exceptions directory from the file path.



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'rubocops/extend/formula_cop.rb', line 170

def style_exceptions_dir
  file_directory = File.dirname(@file_path)

  # if we're in a sharded subdirectory, look below that.
  directory_name = File.basename(file_directory)
  formula_directory = if directory_name.length == 1 || directory_name == "lib"
    File.dirname(file_directory)
  else
    file_directory
  end

  # if we're in a Formula or HomebrewFormula subdirectory, look below that.
  formula_directory_names = ["Formula", "HomebrewFormula"].freeze
  directory_name = File.basename(formula_directory)
  tap_root_directory = if formula_directory_names.include?(directory_name)
    File.dirname(formula_directory)
  else
    formula_directory
  end

  "#{tap_root_directory}/style_exceptions"
end

#tap_style_exception?(list, formula = 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.

Returns whether the given formula exists in the given style exception list. Defaults to the current formula being checked.

Returns:

  • (Boolean)


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'rubocops/extend/formula_cop.rb', line 195

def tap_style_exception?(list, formula = nil)
  if @tap_style_exceptions.nil? && !formula_tap.nil?
    @tap_style_exceptions = {}

    Pathname.glob("#{style_exceptions_dir}/*.json").each do |exception_file|
      list_name = exception_file.basename.to_s.chomp(".json").to_sym
      list_contents = begin
        JSON.parse exception_file.read
      rescue JSON::ParserError
        nil
      end
      next if list_contents.nil? || list_contents.count.zero?

      @tap_style_exceptions[list_name] = list_contents
    end
  end

  return false if @tap_style_exceptions.nil? || @tap_style_exceptions.count.zero?
  return false unless @tap_style_exceptions.key? list

  @tap_style_exceptions[list].include?(formula || @formula_name)
end

#versioned_formula?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 true if the formula is versioned.

Returns:

  • (Boolean)


158
159
160
# File 'rubocops/extend/formula_cop.rb', line 158

def versioned_formula?
  @formula_name.include?("@")
end