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,
sorbet/rbi/dsl/rubo_cop/cop/formula_cop.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 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

Methods included from Kernel

#disk_usage_readable, #ensure_executable!, #ensure_formula_installed!, #exec_browser, #exec_editor, #ignore_interrupts, #interactive_shell, #number_readable, #odebug, #odeprecated, #odie, #odisabled, #ofail, #oh1, #oh1_title, #ohai, #ohai_title, #onoe, #opoo, #paths, #pretty_duration, #pretty_installed, #pretty_outdated, #pretty_uninstalled, #quiet_system, #redact_secrets, #redirect_stdout, #require?, #safe_system, #tap_and_name_comparison, #truncate_text_to_approximate_size, #which, #which_all, #which_editor, #with_custom_locale, #with_env, #with_homebrew_path

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.



17
18
19
# File 'rubocops/extend/formula_cop.rb', line 17

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.



148
149
150
151
152
153
# File 'rubocops/extend/formula_cop.rb', line 148

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)


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

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



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

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.



119
120
121
122
123
# File 'rubocops/extend/formula_cop.rb', line 119

def caveats_strings
  return [] if @body.nil?

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

#dependency_name_hash_match?(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)


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

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

#dependency_type_hash_match?(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_cop.rbi', line 27

def dependency_type_hash_match?(node, *pattern, **kwargs, &block); 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)


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

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.

TODO:

Add case where key of hash is an array

Returns true if given dependency name and dependency type exist in given dependency method call node.

Returns:

  • (Boolean)


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

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.



161
162
163
164
165
# File 'rubocops/extend/formula_cop.rb', line 161

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.



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

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.



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

def on_class(node)
  @file_path = processed_source.file_path
  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

#required_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)


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

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

#required_dependency_name?(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)


47
# File 'sorbet/rbi/dsl/rubo_cop/cop/formula_cop.rbi', line 47

def required_dependency_name?(node, *pattern, **kwargs, &block); 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.



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

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)


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

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)


156
157
158
# File 'rubocops/extend/formula_cop.rb', line 156

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