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

Defined Under Namespace

Classes: FormulaNodes

Constant Summary

Constants included from Kernel

Kernel::IGNORE_INTERRUPTS_MUTEX

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.



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

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

#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 is abstract.

This method returns an undefined value.

Parameters:



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

def audit_formula(formula_nodes); 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



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

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.



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

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)


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

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)


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

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.



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

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.



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

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.



29
30
31
32
33
34
35
36
37
38
# File 'rubocops/extend/formula_cop.rb', line 29

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(FormulaNodes.new(node:, class_node:, parent_class_node:, body_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.



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

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)


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

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)


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

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