Merge pull request #10300 from jonchang/rubocop-v1-api

rubocops: migrate to rubocop v1 API
This commit is contained in:
Jonathan Chang 2021-01-13 21:20:55 +11:00 committed by GitHub
commit 71f7ef0058
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 1655 additions and 1921 deletions

View File

@ -11,19 +11,15 @@ module RuboCop
module Cask
# This cop audits `desc` in casks.
# See the {DescHelper} module for details of the checks.
class Desc < Cop
class Desc < Base
include OnDescStanza
include DescHelper
extend AutoCorrector
def on_desc_stanza(stanza)
name = cask_block.header.cask_token
@name = cask_block.header.cask_token
desc_call = stanza.stanza_node
audit_desc(:cask, name, desc_call)
end
def autocorrect(node)
name = cask_block.header.cask_token
autocorrect_desc(node, name)
audit_desc(:cask, @name, desc_call)
end
end
end

View File

@ -9,8 +9,9 @@ module RuboCop
module Cask
# This cop checks that a cask's homepage ends with a slash
# if it does not have a path component.
class HomepageUrlTrailingSlash < Cop
class HomepageUrlTrailingSlash < Base
include OnHomepageStanza
extend AutoCorrector
MSG_NO_SLASH = "'%<url>s' must have a slash after the domain."
@ -26,19 +27,14 @@ module RuboCop
return unless url&.match?(%r{^.+://[^/]+$})
add_offense(url_node, location: :expression,
message: format(MSG_NO_SLASH, url: url))
end
def autocorrect(node)
domain = URI(node.str_content).host
domain = URI(url_node.str_content).host
# This also takes URLs like 'https://example.org?path'
# and 'https://example.org#path' into account.
corrected_source = node.source.sub("://#{domain}", "://#{domain}/")
corrected_source = url_node.source.sub("://#{domain}", "://#{domain}/")
lambda do |corrector|
corrector.replace(node.source_range, corrected_source)
add_offense(url_node.loc.expression, message: format(MSG_NO_SLASH, url: url)) do |corrector|
corrector.replace(url_node.source_range, corrected_source)
end
end
end

View File

@ -18,10 +18,11 @@ module RuboCop
# cask 'foo' do
# ...
# end
class NoDslVersion < Cop
class NoDslVersion < Base
extend T::Sig
extend Forwardable
extend AutoCorrector
include CaskHelp
MESSAGE = "Use `%<preferred>s` instead of `%<current>s`"
@ -33,13 +34,6 @@ module RuboCop
offense
end
def autocorrect(method_node)
@cask_header = cask_header(method_node)
lambda do |corrector|
corrector.replace(header_range, preferred_header_str)
end
end
private
def_delegator :@cask_header, :source_range, :header_range
@ -54,8 +48,9 @@ module RuboCop
end
def offense
add_offense(@cask_header.method_node, location: header_range,
message: error_msg)
add_offense(header_range, message: error_msg) do |corrector|
corrector.replace(header_range, preferred_header_str)
end
end
sig { returns(String) }

View File

@ -8,8 +8,9 @@ module RuboCop
module Cask
# This cop checks that a cask's stanzas are grouped correctly.
# @see https://github.com/Homebrew/homebrew-cask/blob/HEAD/doc/cask_language_reference/readme.md#stanza-order
class StanzaGrouping < Cop
class StanzaGrouping < Base
extend Forwardable
extend AutoCorrector
include CaskHelp
include RangeHelp
@ -25,17 +26,6 @@ module RuboCop
add_offenses
end
def autocorrect(range)
lambda do |corrector|
case line_ops[range.line - 1]
when :insert
corrector.insert_before(range, "\n")
when :remove
corrector.remove(range)
end
end
end
private
attr_reader :cask_block, :line_ops
@ -79,20 +69,24 @@ module RuboCop
def add_offense_missing_line(stanza)
line_index = index_of_line_after(stanza)
line_ops[line_index] = :insert
add_offense(line_index, message: MISSING_LINE_MSG)
add_offense(line_index, message: MISSING_LINE_MSG) do |corrector|
corrector.insert_before(@range, "\n")
end
end
def add_offense_extra_line(stanza)
line_index = index_of_line_after(stanza)
line_ops[line_index] = :remove
add_offense(line_index, message: EXTRA_LINE_MSG)
add_offense(line_index, message: EXTRA_LINE_MSG) do |corrector|
corrector.remove(@range)
end
end
def add_offense(line_index, message:)
line_length = [processed_source[line_index].size, 1].max
range = source_range(processed_source.buffer, line_index + 1, 0,
@range = source_range(processed_source.buffer, line_index + 1, 0,
line_length)
super(range, location: range, message: message)
super(@range, message: message)
end
end
end

View File

@ -8,8 +8,9 @@ module RuboCop
module Cask
# This cop checks that a cask's stanzas are ordered correctly.
# @see https://github.com/Homebrew/homebrew-cask/blob/HEAD/doc/cask_language_reference/readme.md#stanza-order
class StanzaOrder < Cop
class StanzaOrder < Base
extend Forwardable
extend AutoCorrector
include CaskHelp
MESSAGE = "`%<stanza>s` stanza out of order"
@ -19,15 +20,6 @@ module RuboCop
add_offenses
end
def autocorrect(stanza)
lambda do |corrector|
correct_stanza_index = toplevel_stanzas.index(stanza)
correct_stanza = sorted_toplevel_stanzas[correct_stanza_index]
corrector.replace(stanza.source_range_with_comments,
correct_stanza.source_with_comments)
end
end
private
attr_reader :cask_block
@ -38,8 +30,12 @@ module RuboCop
def add_offenses
offending_stanzas.each do |stanza|
message = format(MESSAGE, stanza: stanza.stanza_name)
add_offense(stanza, location: stanza.source_range_with_comments,
message: message)
add_offense(stanza.source_range_with_comments, message: message) do |corrector|
correct_stanza_index = toplevel_stanzas.index(stanza)
correct_stanza = sorted_toplevel_stanzas[correct_stanza_index]
corrector.replace(stanza.source_range_with_comments,
correct_stanza.source_with_comments)
end
end
end

View File

@ -28,7 +28,6 @@ module RuboCop
return if checksum.nil?
if regex_match_group(checksum, /^$/)
@offense_source_range = @offensive_node.source_range
problem "sha256 is empty"
return
end
@ -39,7 +38,7 @@ module RuboCop
return unless regex_match_group(checksum, /[^a-f0-9]+/i)
problem "sha256 contains invalid characters"
add_offense(@offensive_source_range, message: "sha256 contains invalid characters")
end
end
@ -47,6 +46,8 @@ module RuboCop
#
# @api private
class ChecksumCase < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
return if body_node.nil?
@ -56,16 +57,12 @@ module RuboCop
next if checksum.nil?
next unless regex_match_group(checksum, /[A-F]+/)
problem "sha256 should be lowercase"
add_offense(@offensive_source_range, message: "sha256 should be lowercase") do |corrector|
correction = @offensive_node.source.downcase
corrector.insert_before(@offensive_node.source_range, correction)
corrector.remove(@offensive_node.source_range)
end
end
def autocorrect(node)
lambda do |corrector|
correction = node.source.downcase
corrector.insert_before(node.source_range, correction)
corrector.remove(node.source_range)
end
end
end
end

View File

@ -10,6 +10,8 @@ module RuboCop
#
# @api private
class ClassName < FormulaCop
extend AutoCorrector
DEPRECATED_CLASSES = %w[
GithubGistFormula
ScriptFileFormula
@ -20,12 +22,8 @@ module RuboCop
parent_class = class_name(parent_class_node)
return unless DEPRECATED_CLASSES.include?(parent_class)
problem "#{parent_class} is deprecated, use Formula instead"
end
def autocorrect(node)
lambda do |corrector|
corrector.replace(node.source_range, "Formula")
problem "#{parent_class} is deprecated, use Formula instead" do |corrector|
corrector.replace(parent_class_node.source_range, "Formula")
end
end
end
@ -34,6 +32,8 @@ module RuboCop
#
# @api private
class Test < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
test = find_block(body_node, :test)
return unless test
@ -49,33 +49,19 @@ module RuboCop
p1, p2 = params
if match = string_content(p1).match(%r{(/usr/local/(s?bin))})
offending_node(p1)
problem "use \#{#{match[2]}} instead of #{match[1]} in #{node}"
problem "use \#{#{match[2]}} instead of #{match[1]} in #{node}" do |corrector|
corrector.replace(p1.source_range, p1.source.sub(match[1], "\#{#{match[2]}}"))
end
end
if node == :shell_output && node_equals?(p2, 0)
offending_node(p2)
problem "Passing 0 to shell_output() is redundant"
problem "Passing 0 to shell_output() is redundant" do |corrector|
corrector.remove(range_with_surrounding_comma(range_with_surrounding_space(range: p2.source_range,
side: :left)))
end
end
end
def autocorrect(node)
lambda do |corrector|
case node.type
when :str, :dstr
# Rubocop: intentionally outputted non-interpolated strings
corrector.replace(node.source_range,
node.source.to_s.sub(%r{(/usr/local/(s?bin))},
'#{\2}')) # rubocop:disable Lint/InterpolationCheck
when :int
corrector.remove(
range_with_surrounding_comma(
range_with_surrounding_space(range: node.source_range,
side: :left),
),
)
end
end
end
def_node_search :test_calls, <<~EOS

View File

@ -12,6 +12,8 @@ module RuboCop
# - `component_precedence_list` has component hierarchy in a nested list
# where each sub array contains components' details which are at same precedence level
class ComponentsOrder < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
@present_components, @offensive_nodes = check_order(FORMULA_COMPONENT_PRECEDENCE_LIST, body_node)
@ -27,7 +29,6 @@ module RuboCop
if on_macos_blocks.length > 1
@offensive_node = on_macos_blocks.second
@offense_source_range = on_macos_blocks.second.source_range
problem "there can only be one `on_macos` block in a formula."
end
@ -37,7 +38,6 @@ module RuboCop
if on_linux_blocks.length > 1
@offensive_node = on_linux_blocks.second
@offense_source_range = on_linux_blocks.second.source_range
problem "there can only be one `on_linux` block in a formula."
end
@ -58,7 +58,6 @@ module RuboCop
end
@offensive_node = resource_block
@offense_source_range = resource_block.source_range
next if on_macos_blocks.length.zero? && on_linux_blocks.length.zero?
@ -122,7 +121,6 @@ module RuboCop
valid_node ||= on_os_allowed_methods.include? child.method_name.to_s
@offensive_node = child
@offense_source_range = child.source_range
next if valid_node
problem "`#{on_os_block.method_name}` cannot include `#{child.method_name}`. " \
@ -130,17 +128,6 @@ module RuboCop
end
end
# {autocorrect} gets called just after {component_problem}.
def autocorrect(_node)
return if @offensive_nodes.nil?
succeeding_node = @offensive_nodes[0]
preceding_node = @offensive_nodes[1]
lambda do |corrector|
reorder_components(corrector, succeeding_node, preceding_node)
end
end
# Reorder two nodes in the source, using the corrector instance in autocorrect method.
# Components of same type are grouped together when rewriting the source.
# Linebreaks are introduced if components are of two different methods/blocks/multilines.
@ -201,13 +188,15 @@ module RuboCop
nil
end
# Method to format message for reporting component precedence violations.
# Method to report and correct component precedence violations.
def component_problem(c1, c2)
return if tap_style_exception? :components_order_exceptions
problem "`#{format_component(c1)}` (line #{line_number(c1)}) " \
"should be put before `#{format_component(c2)}` " \
"(line #{line_number(c2)})"
"(line #{line_number(c2)})" do |corrector|
reorder_components(corrector, c1, c2)
end
end
# Node pattern method to match

View File

@ -9,6 +9,8 @@ module RuboCop
module FormulaAudit
# This cop audits versioned formulae for `conflicts_with`.
class Conflicts < FormulaCop
extend AutoCorrector
MSG = "Versioned formulae should not use `conflicts_with`. " \
"Use `keg_only :versioned_formula` instead."
@ -19,31 +21,29 @@ module RuboCop
reason = parameters(conflicts_with_call).last.values.first
offending_node(reason)
name = Regexp.new(@formula_name, Regexp::IGNORECASE)
reason = string_content(reason).sub(name, "")
first_word = reason.split.first
reason_text = string_content(reason).sub(name, "")
first_word = reason_text.split.first
if reason.match?(/\A[A-Z]/)
problem "'#{first_word}' from the `conflicts_with` reason should be '#{first_word.downcase}'."
if reason_text.match?(/\A[A-Z]/)
problem "'#{first_word}' from the `conflicts_with` reason "\
"should be '#{first_word.downcase}'." do |corrector|
reason_text[0] = reason_text[0].downcase
corrector.replace(reason.source_range, "\"#{reason_text}\"")
end
end
next unless reason_text.end_with?(".")
problem "`conflicts_with` reason should not end with a period." if reason.end_with?(".")
problem "`conflicts_with` reason should not end with a period." do |corrector|
corrector.replace(reason.source_range, "\"#{reason_text.chop}\"")
end
end
return unless versioned_formula?
problem MSG if !tap_style_exception?(:versioned_formulae_conflicts_allowlist) &&
method_called_ever?(body_node, :conflicts_with)
end
def autocorrect(node)
lambda do |corrector|
if versioned_formula?
corrector.replace(node.source_range, "keg_only :versioned_formula")
else
reason = string_content(node)
reason[0] = reason[0].downcase
reason = reason.delete_suffix(".")
corrector.replace(node.source_range, "\"#{reason}\"")
if !tap_style_exception?(:versioned_formulae_conflicts_allowlist) && method_called_ever?(body_node,
:conflicts_with)
problem MSG do |corrector|
corrector.replace(@offensive_node.source_range, "keg_only :versioned_formula")
end
end
end

View File

@ -11,6 +11,8 @@ module RuboCop
# precedence order:
# build-time > test > normal > recommended > optional
class DependencyOrder < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
check_dependency_nodes_order(body_node)
check_uses_from_macos_nodes_order(body_node)
@ -89,17 +91,26 @@ module RuboCop
# Verify actual order of sorted `depends_on` nodes in source code;
# raise RuboCop problem otherwise.
def verify_order_in_source(ordered)
ordered.each_with_index do |dependency_node_1, idx|
l1 = line_number(dependency_node_1)
dependency_node_2 = nil
ordered.drop(idx+1).each do |node2|
l2 = line_number(node2)
dependency_node_2 = node2 if l2 < l1
ordered.each_with_index do |node_1, idx|
l1 = line_number(node_1)
l2 = nil
node_2 = nil
ordered.drop(idx + 1).each do |test_node|
l2 = line_number(test_node)
node_2 = test_node if l2 < l1
end
next unless dependency_node_2
next unless node_2
@offensive_nodes = [dependency_node_1, dependency_node_2]
component_problem dependency_node_1, dependency_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
@ -150,31 +161,6 @@ module RuboCop
match_node = dependency_name_node(dependency_node).to_a.first
string_content(match_node) if match_node
end
def autocorrect(_node)
succeeding_node = @offensive_nodes[0]
preceding_node = @offensive_nodes[1]
lambda do |corrector|
reorder_components(corrector, succeeding_node, preceding_node)
end
end
private
def component_problem(c1, c2)
offending_node(c1)
problem "dependency \"#{dependency_name(c1)}\" " \
"(line #{line_number(c1)}) should be put before dependency "\
"\"#{dependency_name(c2)}\" (line #{line_number(c2)})"
end
# Reorder two nodes in the source, using the corrector instance in the {autocorrect} method.
def reorder_components(corrector, node1, node2)
indentation = " " * (start_column(node2) - line_start_column(node2))
line_breaks = "\n"
corrector.insert_before(node2.source_range, node1.source + line_breaks + indentation)
corrector.remove(range_with_surrounding_space(range: node1.source_range, side: :left))
end
end
end
end

View File

@ -8,6 +8,8 @@ module RuboCop
module FormulaAudit
# This cop audits `deprecate!` and `disable!` dates.
class DeprecateDisableDate < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
[:deprecate!, :disable!].each do |method|
node = find_node_method_by_name(body_node, method)
@ -19,16 +21,11 @@ module RuboCop
rescue ArgumentError
fixed_date_string = Date.parse(string_content(date_node)).iso8601
offending_node(date_node)
problem "Use `#{fixed_date_string}` to comply with ISO 8601"
problem "Use `#{fixed_date_string}` to comply with ISO 8601" do |corrector|
corrector.replace(date_node.source_range, "\"#{fixed_date_string}\"")
end
end
end
def autocorrect(node)
lambda do |corrector|
fixed_fixed_date_string = Date.parse(string_content(node)).iso8601
corrector.replace(node.source_range, "\"#{fixed_fixed_date_string}\"")
end
end
def_node_search :date, <<~EOS
@ -38,6 +35,8 @@ module RuboCop
# This cop audits `deprecate!` and `disable!` reasons.
class DeprecateDisableReason < FormulaCop
extend AutoCorrector
PUNCTUATION_MARKS = %w[. ! ?].freeze
def audit_formula(_node, _class_node, _parent_class_node, body_node)
@ -54,9 +53,17 @@ module RuboCop
offending_node(reason_node)
reason_string = string_content(reason_node)
problem "Do not start the reason with `it`" if reason_string.start_with?("it ")
if reason_string.start_with?("it ")
problem "Do not start the reason with `it`" do |corrector|
corrector.replace(@offensive_node.source_range, "\"#{reason_string[3..]}\"")
end
end
problem "Do not end the reason with a punctuation mark" if PUNCTUATION_MARKS.include?(reason_string[-1])
if PUNCTUATION_MARKS.include?(reason_string[-1])
problem "Do not end the reason with a punctuation mark" do |corrector|
corrector.replace(@offensive_node.source_range, "\"#{reason_string.chop}\"")
end
end
end
next if reason_found
@ -70,17 +77,6 @@ module RuboCop
end
end
def autocorrect(node)
return unless node.str_type?
lambda do |corrector|
reason = string_content(node)
reason = reason[3..] if reason.start_with?("it ")
reason.chop! if PUNCTUATION_MARKS.include?(reason[-1])
corrector.replace(node.source_range, "\"#{reason}\"")
end
end
def_node_search :reason, <<~EOS
(pair (sym :because) ${str sym})
EOS

View File

@ -18,7 +18,7 @@ module RuboCop
# Superclass for all formula cops.
#
# @api private
class FormulaCop < Cop
class FormulaCop < Base
include RangeHelp
include HelperFunctions
@ -71,19 +71,16 @@ module RuboCop
next unless method_node.method_name == method_name
@offensive_node = method_node
@offense_source_range = method_node.source_range
return method_node
end
# If not found then, parent node becomes the offensive node
@offensive_node = node.parent
@offense_source_range = node.parent.source_range
nil
end
# Sets the given node as the offending node when required in custom cops.
def offending_node(node)
@offensive_node = node
@offense_source_range = node.source_range
end
# Returns an array of method call nodes matching method_name inside node with depth first order (child nodes).
@ -142,7 +139,6 @@ module RuboCop
next if method.receiver.const_name != instance &&
!(method.receiver.send_type? && method.receiver.method_name == instance)
@offense_source_range = method.source_range
@offensive_node = method
return true unless block_given?
@ -160,7 +156,6 @@ module RuboCop
next if method_node.receiver.const_name != name &&
!(method_node.receiver.send_type? && method_node.receiver.method_name == name)
@offense_source_range = method_node.receiver.source_range
@offensive_node = method_node.receiver
return true unless block_given?
@ -179,7 +174,6 @@ module RuboCop
end
return if idx.nil?
@offense_source_range = dependency_nodes[idx].source_range
@offensive_node = dependency_nodes[idx]
end
@ -207,10 +201,7 @@ module RuboCop
type_match = false
end
if type_match || name_match
@offensive_node = node
@offense_source_range = node.source_range
end
@offensive_node = node if type_match || name_match
type_match && name_match
end
@ -223,7 +214,6 @@ module RuboCop
next unless const_node.const_name == const_name
@offensive_node = const_node
@offense_source_range = const_node.source_range
yield const_node if block_given?
return true
end
@ -259,12 +249,10 @@ module RuboCop
next if block_node.method_name != block_name
@offensive_node = block_node
@offense_source_range = block_node.source_range
return block_node
end
# If not found then, parent node becomes the offensive node
@offensive_node = node.parent
@offense_source_range = node.parent.source_range
nil
end
@ -299,14 +287,12 @@ module RuboCop
next if method_name != def_method_name && method_name.present?
@offensive_node = def_node
@offense_source_range = def_node.source_range
return def_node
end
return if node.parent.nil?
# If not found then, parent node becomes the offensive node
@offensive_node = node.parent
@offense_source_range = node.parent.source_range
nil
end
@ -317,7 +303,6 @@ module RuboCop
next unless call_node.method_name == method_name
@offensive_node = call_node
@offense_source_range = call_node.source_range
return true
end
false
@ -345,7 +330,6 @@ module RuboCop
next unless call_node.method_name == method_name
@offensive_node = call_node
@offense_source_range = call_node.source_range
return true
end
false
@ -365,7 +349,6 @@ module RuboCop
def component_precedes?(first_node, next_node)
return false if line_number(first_node) < line_number(next_node)
@offense_source_range = first_node.source_range
@offensive_node = first_node
true
end
@ -394,7 +377,6 @@ module RuboCop
def parameters_passed?(method_node, *params)
method_params = parameters(method_node)
@offensive_node = method_node
@offense_source_range = method_node.source_range
params.all? do |given_param|
method_params.any? do |method_param|
if given_param.instance_of?(Regexp)
@ -420,9 +402,8 @@ module RuboCop
# Yields to a block with comment text as parameter.
def audit_comments
@processed_source.comments.each do |comment_node|
processed_source.comments.each do |comment_node|
@offensive_node = comment_node
@offense_source_range = :expression
yield comment_node.text
end
end
@ -435,7 +416,6 @@ module RuboCop
# Returns the class node's name, or nil if not a class node.
def class_name(node)
@offensive_node = node
@offense_source_range = node.source_range
node.const_name
end

View File

@ -12,14 +12,12 @@ module RuboCop
# See the {DescHelper} module for details of the checks.
class Desc < FormulaCop
include DescHelper
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
@name = @formula_name
desc_call = find_node_method_by_name(body_node, :desc)
audit_desc(:formula, @formula_name, desc_call)
end
def autocorrect(node)
autocorrect_desc(node, @formula_name)
audit_desc(:formula, @name, desc_call)
end
end
end

View File

@ -8,19 +8,23 @@ module RuboCop
module FormulaAudit
# This cop audits the `homepage` URL in formulae.
class Homepage < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
homepage_node = find_node_method_by_name(body_node, :homepage)
homepage = if homepage_node
string_content(parameters(homepage_node).first)
else
""
if homepage_node.nil?
problem "Formula should have a homepage."
return
end
problem "Formula should have a homepage." if homepage_node.nil? || homepage.empty?
homepage_parameter_node = parameters(homepage_node).first
offending_node(homepage_parameter_node)
homepage = string_content(homepage_parameter_node)
unless homepage.match?(%r{^https?://})
problem "The homepage should start with http or https (URL is #{homepage})."
end
problem "Formula should have a homepage." if homepage.empty?
problem "The homepage should start with http or https." unless homepage.match?(%r{^https?://})
case homepage
# Freedesktop is complicated to handle - It has SSL/TLS, but only on certain subdomains.
@ -29,25 +33,34 @@ module RuboCop
# "Software" is redirected to https://wiki.freedesktop.org/www/Software/project_name
when %r{^http://((?:www|nice|libopenraw|liboil|telepathy|xorg)\.)?freedesktop\.org/(?:wiki/)?}
if homepage.include?("Software")
problem "#{homepage} should be styled `https://wiki.freedesktop.org/www/Software/project_name`"
problem "Freedesktop homepages should be styled "\
"`https://wiki.freedesktop.org/www/Software/project_name`"
else
problem "#{homepage} should be styled `https://wiki.freedesktop.org/project_name`"
problem "Freedesktop homepages should be styled `https://wiki.freedesktop.org/project_name`"
end
# Google Code homepages should end in a slash
when %r{^https?://code\.google\.com/p/[^/]+[^/]$}
problem "#{homepage} should end with a slash"
problem "Google Code homepages should end with a slash" do |corrector|
corrector.replace(homepage_parameter_node.source_range, "\"#{homepage}/\"")
end
when %r{^http://([^/]*)\.(sf|sourceforge)\.net(/|$)}
problem "#{homepage} should be `https://#{Regexp.last_match(1)}.sourceforge.io/`"
fixed = "https://#{Regexp.last_match(1)}.sourceforge.io/"
problem "Sourceforge homepages should be `#{fixed}`" do |corrector|
corrector.replace(homepage_parameter_node.source_range, "\"#{fixed}\"")
end
when /readthedocs\.org/
offending_node(parameters(homepage_node).first)
problem "#{homepage} should be `#{homepage.sub("readthedocs.org", "readthedocs.io")}`"
fixed = homepage.sub("readthedocs.org", "readthedocs.io")
problem "Readthedocs homepages should be `#{fixed}`" do |corrector|
corrector.replace(homepage_parameter_node.source_range, "\"#{fixed}\"")
end
when %r{^https://github.com.*\.git}
offending_node(parameters(homepage_node).first)
problem "GitHub homepages (`#{homepage}`) should not end with .git"
problem "GitHub homepages should not end with .git" do |corrector|
corrector.replace(homepage_parameter_node.source_range, "\"#{homepage.delete_suffix(".git")}\"")
end
# People will run into mixed content sometimes, but we should enforce and then add
# exemptions as they are discovered. Treat mixed content on homepages as a bug.
@ -81,21 +94,10 @@ module RuboCop
%r{^http://code\.google\.com/},
%r{^http://bitbucket\.org/},
%r{^http://(?:[^/]*\.)?archive\.org}
problem "Please use https:// for #{homepage}"
problem "Please use https:// for #{homepage}" do |corrector|
corrector.replace(homepage_parameter_node.source_range, "\"#{homepage.sub("http", "https")}\"")
end
end
def autocorrect(node)
lambda do |corrector|
return if node.nil?
homepage = string_content(node).dup
return if homepage.nil? || homepage.empty?
homepage.sub!("readthedocs.org", "readthedocs.io")
homepage.delete_suffix!(".git") if homepage.start_with?("https://github.com")
corrector.replace(node.source_range, "\"#{homepage}\"")
end
end
end
end

View File

@ -10,6 +10,8 @@ module RuboCop
#
# @api private
class KegOnly < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
keg_only_node = find_node_method_by_name(body_node, :keg_only)
return unless keg_only_node
@ -33,12 +35,17 @@ module RuboCop
first_word = reason.split.first
if reason =~ /\A[A-Z]/ && !reason.start_with?(*allowlist)
problem "'#{first_word}' from the `keg_only` reason should be '#{first_word.downcase}'."
problem "'#{first_word}' from the `keg_only` reason should be '#{first_word.downcase}'." do |corrector|
reason[0] = reason[0].downcase
corrector.replace(@offensive_node.source_range, "\"#{reason}\"")
end
end
return unless reason.end_with?(".")
problem "`keg_only` reason should not end with a period."
problem "`keg_only` reason should not end with a period." do |corrector|
corrector.replace(@offensive_node.source_range, "\"#{reason.chop}\"")
end
end
def autocorrect(node)

View File

@ -197,21 +197,18 @@ module RuboCop
#
# @api private
class MpiCheck < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
# Enforce use of OpenMPI for MPI dependency in core
return unless formula_tap == "homebrew-core"
find_method_with_args(body_node, :depends_on, "mpich") do
problem "Formulae in homebrew/core should use 'depends_on \"open-mpi\"' " \
"instead of '#{@offensive_node.source}'."
"instead of '#{@offensive_node.source}'." do |corrector|
corrector.replace(@offensive_node.source_range, "depends_on \"open-mpi\"")
end
end
def autocorrect(node)
# The dependency nodes may need to be re-sorted because of this
lambda do |corrector|
corrector.replace(node.source_range, "depends_on \"open-mpi\"")
end
end
end
@ -219,6 +216,8 @@ module RuboCop
#
# @api private
class SafePopenCommands < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
test = find_block(body_node, :test)
@ -233,16 +232,12 @@ module RuboCop
find_instance_method_call(body_node, "Utils", unsafe_command) do |method|
unless test_methods.include?(method.source_range)
problem "Use `Utils.safe_#{unsafe_command}` instead of `Utils.#{unsafe_command}`"
problem "Use `Utils.safe_#{unsafe_command}` instead of `Utils.#{unsafe_command}`" do |corrector|
corrector.replace(@offensive_node.loc.selector, "safe_#{@offensive_node.method_name}")
end
end
end
end
def autocorrect(node)
lambda do |corrector|
corrector.replace(node.loc.selector, "safe_#{node.method_name}")
end
end
end
@ -250,6 +245,8 @@ module RuboCop
#
# @api private
class ShellVariables < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
popen_commands = [
:popen,
@ -265,16 +262,12 @@ module RuboCop
good_args = "Utils.#{command}({ \"#{match[1]}\" => \"#{match[2]}\" }, \"#{match[3]}\")"
problem "Use `#{good_args}` instead of `#{method.source}`"
problem "Use `#{good_args}` instead of `#{method.source}`" do |corrector|
corrector.replace(@offensive_node.source_range,
"{ \"#{match[1]}\" => \"#{match[2]}\" }, \"#{match[3]}\"")
end
end
end
def autocorrect(node)
lambda do |corrector|
match = regex_match_group(node, /^([^"' ]+)=([^"' ]+)(?: (.*))?$/)
corrector.replace(node.source_range, "{ \"#{match[1]}\" => \"#{match[2]}\" }, \"#{match[3]}\"")
end
end
end
@ -282,6 +275,8 @@ module RuboCop
#
# @api private
class LicenseArrays < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
license_node = find_node_method_by_name(body_node, :license)
return unless license_node
@ -289,12 +284,8 @@ module RuboCop
license = parameters(license_node).first
return unless license.array_type?
problem "Use `license any_of: #{license.source}` instead of `license #{license.source}`"
end
def autocorrect(node)
lambda do |corrector|
corrector.replace(node.source_range, "license any_of: #{parameters(node).first.source}")
problem "Use `license any_of: #{license.source}` instead of `license #{license.source}`" do |corrector|
corrector.replace(license_node.source_range, "license any_of: #{parameters(license_node).first.source}")
end
end
end
@ -324,6 +315,8 @@ module RuboCop
#
# @api private
class PythonVersions < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
python_formula_node = find_every_method_call_by_name(body_node, :depends_on).find do |dep|
string_content(parameters(dep).first).start_with? "python@"
@ -334,26 +327,23 @@ module RuboCop
python_version = string_content(parameters(python_formula_node).first).split("@").last
find_strings(body_node).each do |str|
string_content = string_content(str)
content = string_content(str)
next unless match = string_content.match(/^python(@)?(\d\.\d+)$/)
next unless match = content.match(/^python(@)?(\d\.\d+)$/)
next if python_version == match[2]
@fix = if match[1]
fix = if match[1]
"python@#{python_version}"
else
"python#{python_version}"
end
offending_node(str)
problem "References to `#{string_content}` should match the specified python dependency (`#{@fix}`)"
problem "References to `#{content}` should "\
"match the specified python dependency (`#{fix}`)" do |corrector|
corrector.replace(str.source_range, "\"#{fix}\"")
end
end
def autocorrect(node)
lambda do |corrector|
corrector.replace(node.source_range, "\"#{@fix}\"")
end
end
end
@ -534,7 +524,7 @@ module RuboCop
"Pass explicit paths to prevent Homebrew from removing empty folders."
end
if find_method_def(@processed_source.ast)
if find_method_def(processed_source.ast)
problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level"
end
@ -661,6 +651,8 @@ module RuboCop
#
# @api private
class ShellCommands < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
# Match shell commands separated by spaces in the same string
shell_cmd_with_spaces_regex = /[^"' ]*(?:\s[^"' ]*)+/
@ -682,7 +674,9 @@ module RuboCop
good_args = match[0].gsub(" ", "\", \"")
offending_node(parameters(method).first)
problem "Separate `system` commands into `\"#{good_args}\"`"
problem "Separate `system` commands into `\"#{good_args}\"`" do |corrector|
corrector.replace(@offensive_node.source_range, @offensive_node.source.gsub(" ", "\", \""))
end
end
popen_commands.each do |command|
@ -696,16 +690,12 @@ module RuboCop
good_args = match[0].gsub(" ", "\", \"")
offending_node(parameters(method)[index])
problem "Separate `Utils.#{command}` commands into `\"#{good_args}\"`"
problem "Separate `Utils.#{command}` commands into `\"#{good_args}\"`" do |corrector|
good_args = @offensive_node.source.gsub(" ", "\", \"")
corrector.replace(@offensive_node.source_range, good_args)
end
end
end
def autocorrect(node)
lambda do |corrector|
good_args = node.source.gsub(" ", "\", \"")
corrector.replace(node.source_range, good_args)
end
end
end
end

View File

@ -11,6 +11,8 @@ module RuboCop
#
# @api private
class LivecheckSkip < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
livecheck_node = find_block(body_node, :livecheck)
return if livecheck_node.blank?
@ -21,16 +23,12 @@ module RuboCop
return if find_every_method_call_by_name(livecheck_node).length < 3
offending_node(livecheck_node)
problem "Skipped formulae must not contain other livecheck information."
end
def autocorrect(node)
lambda do |corrector|
skip = find_every_method_call_by_name(node, :skip).first
problem "Skipped formulae must not contain other livecheck information." do |corrector|
skip = find_every_method_call_by_name(livecheck_node, :skip).first
skip = find_strings(skip).first
skip = string_content(skip) if skip.present?
corrector.replace(
node.source_range,
livecheck_node.source_range,
<<~EOS.strip,
livecheck do
skip#{" \"#{skip}\"" if skip.present?}
@ -65,7 +63,7 @@ module RuboCop
#
# @api private
class LivecheckUrlSymbol < FormulaCop
@offense = nil
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
livecheck_node = find_block(body_node, :livecheck)
@ -110,24 +108,20 @@ module RuboCop
next if url != livecheck_url && url != "#{livecheck_url}/" && "#{url}/" != livecheck_url
offending_node(livecheck_url_node)
@offense = symbol
problem "Use `url :#{symbol}`"
problem "Use `url :#{symbol}`" do |corrector|
corrector.replace(livecheck_url_node.source_range, "url :#{symbol}")
end
break
end
end
def autocorrect(node)
lambda do |corrector|
corrector.replace(node.source_range, "url :#{@offense}")
@offense = nil
end
end
end
# This cop ensures that the `regex` call in the `livecheck` block uses parentheses.
#
# @api private
class LivecheckRegexParentheses < FormulaCop
extend AutoCorrector
def audit_formula(_node, _class_node, _parent_class_node, body_node)
livecheck_node = find_block(body_node, :livecheck)
return if livecheck_node.blank?
@ -141,13 +135,9 @@ module RuboCop
return if parentheses?(livecheck_regex_node)
offending_node(livecheck_regex_node)
problem "The `regex` call should always use parentheses."
end
def autocorrect(node)
lambda do |corrector|
pattern = node.source.split[1..].join
corrector.replace(node.source_range, "regex(#{pattern})")
problem "The `regex` call should always use parentheses." do |corrector|
pattern = livecheck_regex_node.source.split[1..].join
corrector.replace(livecheck_regex_node.source_range, "regex(#{pattern})")
end
end
end
@ -157,6 +147,8 @@ module RuboCop
#
# @api private
class LivecheckRegexExtension < FormulaCop
extend AutoCorrector
TAR_PATTERN = /\\?\.t(ar|(g|l|x)z$|[bz2]{2,4}$)(\\?\.((g|l|x)z)|[bz2]{2,4}|Z)?$/i.freeze
def audit_formula(_node, _class_node, _parent_class_node, body_node)
@ -175,12 +167,8 @@ module RuboCop
return if match.blank?
offending_node(regex_node)
problem "Use `\\.t` instead of `#{match}`"
end
def autocorrect(node)
lambda do |corrector|
node = find_strings(node).first
problem "Use `\\.t` instead of `#{match}`" do |corrector|
node = find_strings(regex_node).first
correct = node.source.gsub(TAR_PATTERN, "\\.t")
corrector.replace(node.source_range, correct)
end
@ -218,6 +206,10 @@ module RuboCop
#
# @api private
class LivecheckRegexCaseInsensitive < FormulaCop
extend AutoCorrector
MSG = "Regexes should be case-insensitive unless sensitivity is explicitly required for proper matching."
def audit_formula(_node, _class_node, _parent_class_node, body_node)
return if tap_style_exception? :regex_case_sensitive_allowlist
@ -235,12 +227,8 @@ module RuboCop
return if options_node.source.include?("i")
offending_node(regex_node)
problem "Regexes should be case-insensitive unless sensitivity is explicitly required for proper matching."
end
def autocorrect(node)
lambda do |corrector|
node = node.regopt
problem MSG do |corrector|
node = regex_node.regopt
corrector.replace(node.source_range, "i#{node.source}".chars.sort.join)
end
end

View File

@ -8,6 +8,7 @@ module RuboCop
module Cop
module FormulaAudit
# This cop audits `patch`es in formulae.
# TODO: Many of these could be auto-corrected.
class Patches < FormulaCop
extend T::Sig
@ -26,7 +27,7 @@ module RuboCop
if inline_patches.empty? && patch_end?
offending_patch_end_node(node)
problem "patch is missing 'DATA'"
add_offense(@offense_source_range, message: "patch is missing 'DATA'")
end
patches_node = find_method_def(body, :patches)

View File

@ -27,7 +27,6 @@ module RuboCop
end
@offensive_node = desc_call
@offense_source_range = desc_call.source_range
desc = desc_call.first_argument
@ -39,39 +38,41 @@ module RuboCop
end
# Check the desc for leading whitespace.
problem "Description shouldn't have leading spaces." if regex_match_group(desc, /^\s+/)
desc_problem "Description shouldn't have leading spaces." if regex_match_group(desc, /^\s+/)
# Check the desc for trailing whitespace.
problem "Description shouldn't have trailing spaces." if regex_match_group(desc, /\s+$/)
desc_problem "Description shouldn't have trailing spaces." if regex_match_group(desc, /\s+$/)
# Check if "command-line" is spelled incorrectly in the desc.
if match = regex_match_group(desc, /(command ?line)/i)
c = match.to_s[0]
problem "Description should use \"#{c}ommand-line\" instead of \"#{match}\"."
desc_problem "Description should use \"#{c}ommand-line\" instead of \"#{match}\"."
end
# Check if the desc starts with an article.
problem "Description shouldn't start with an article." if regex_match_group(desc, /^(the|an?)(?=\s)/i)
desc_problem "Description shouldn't start with an article." if regex_match_group(desc, /^(the|an?)(?=\s)/i)
# Check if invalid lowercase words are at the start of a desc.
if !VALID_LOWERCASE_WORDS.include?(string_content(desc).split.first) &&
regex_match_group(desc, /^[a-z]/)
problem "Description should start with a capital letter."
desc_problem "Description should start with a capital letter."
end
# Check if the desc starts with the formula's or cask's name.
name_regex = name.delete("-").split("").join('[\s\-]?')
problem "Description shouldn't start with the #{type} name." if regex_match_group(desc, /^#{name_regex}\b/i)
if regex_match_group(desc, /^#{name_regex}\b/i)
desc_problem "Description shouldn't start with the #{type} name."
end
if type == :cask &&
(match = regex_match_group(desc, /\b(macOS|Mac( ?OS( ?X)?)?|OS ?X)(?! virtual machines?)\b/i)) &&
match[1] != "MAC"
problem "Description shouldn't contain the platform."
desc_problem "Description shouldn't contain the platform."
end
# Check if a full stop is used at the end of a desc (apart from in the case of "etc.").
if regex_match_group(desc, /\.$/) && !string_content(desc).end_with?("etc.")
problem "Description shouldn't end with a full stop."
desc_problem "Description shouldn't end with a full stop."
end
# Check if the desc length exceeds maximum length.
@ -81,9 +82,10 @@ module RuboCop
"The current length is #{desc_length}."
end
def autocorrect_desc(node, name)
lambda do |corrector|
/\A(?<quote>["'])(?<correction>.*)(?:\k<quote>)\Z/ =~ node.source
# Auto correct desc problems. `regex_match_group` must be called before this to populate @offense_source_range.
def desc_problem(message)
add_offense(@offensive_source_range, message: message) do |corrector|
/\A(?<quote>["'])(?<correction>.*)(?:\k<quote>)\Z/ =~ @offensive_node.source
next if correction.nil?
@ -99,12 +101,12 @@ module RuboCop
end
correction.gsub!(/(ommand ?line)/i, "ommand-line")
correction.gsub!(/(^|[^a-z])#{name}([^a-z]|$)/i, "\\1\\2")
correction.gsub!(/(^|[^a-z])#{@name}([^a-z]|$)/i, "\\1\\2")
correction.gsub!(/^\s+/, "")
correction.gsub!(/\s+$/, "")
correction.gsub!(/\.$/, "")
corrector.replace(node.source_range, "#{quote}#{correction}#{quote}")
corrector.replace(@offensive_node.source_range, "#{quote}#{correction}#{quote}")
end
end
end

View File

@ -28,8 +28,8 @@ module RuboCop
@length = match_object.to_s.length
@line_no = line_number(node)
@source_buf = source_buffer(node)
@offense_source_range = source_range(@source_buf, @line_no, @column, @length)
@offensive_node = node
@offensive_source_range = source_range(@source_buf, @line_no, @column, @length)
match_object
end
@ -77,8 +77,8 @@ module RuboCop
end
end
def problem(msg)
add_offense(@offensive_node, location: @offense_source_range, message: msg)
def problem(msg, &block)
add_offense(@offensive_node, message: msg, &block)
end
end
end

View File

@ -10,17 +10,16 @@ module RuboCop
#
# @api private
class Text < FormulaCop
def audit_formula(node, _class_node, _parent_class_node, body_node)
@full_source_content = source_buffer(node).source
extend AutoCorrector
if match = @full_source_content.match(/^require ['"]formula['"]$/)
@offensive_node = node
@source_buf = source_buffer(node)
@line_no = match.pre_match.count("\n") + 1
@column = 0
@length = match[0].length
@offense_source_range = source_range(@source_buf, @line_no, @column, @length)
problem "`#{match}` is now unnecessary"
def audit_formula(node, _class_node, _parent_class_node, body_node)
full_source_content = source_buffer(node).source
if match = full_source_content.match(/^require ['"]formula['"]$/)
range = source_range(source_buffer(node), match.pre_match.count("\n") + 1, 0, match[0].length)
add_offense(range, message: "`#{match}` is now unnecessary") do |corrector|
corrector.remove(range_with_surrounding_space(range: range))
end
end
if !find_node_method_by_name(body_node, :plist_options) &&

View File

@ -7,8 +7,9 @@ module RuboCop
# This cop checks that `unless` is not used with multiple conditions.
#
# @api private
class UnlessMultipleConditions < Cop
class UnlessMultipleConditions < Base
extend T::Sig
extend AutoCorrector
MSG = "Avoid using `unless` with multiple conditions."
@ -16,12 +17,7 @@ module RuboCop
def on_if(node)
return if !node.unless? || (!node.condition.and_type? && !node.condition.or_type?)
add_offense(node, location: node.condition.source_range.with(begin_pos: node.loc.keyword.begin_pos))
end
sig { params(node: RuboCop::AST::IfNode).returns(T.proc.params(arg0: RuboCop::Cop::Corrector).void) }
def autocorrect(node)
lambda do |corrector|
add_offense(node.condition.source_range.with(begin_pos: node.loc.keyword.begin_pos)) do |corrector|
corrector.replace(node.loc.keyword, "if")
corrector.replace(node.condition.loc.operator, node.condition.inverse_operator)
[node.condition.lhs, node.condition.rhs].each do |subcondition|

View File

@ -21,14 +21,13 @@ module CaskCop
end
def expect_no_offenses(source)
inspect_source(source)
expect(cop.offenses).to be_empty
expect(inspect_source(source)).to be_empty
end
def expect_reported_offenses(source, expected_offenses)
inspect_source(source)
expect(cop.offenses.size).to eq(expected_offenses.size)
expected_offenses.zip(cop.offenses).each do |expected, actual|
offenses = inspect_source(source)
expect(offenses.size).to eq(expected_offenses.size)
expected_offenses.zip(offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end

View File

@ -14,7 +14,7 @@ describe RuboCop::Cop::FormulaAudit::Caveats do
url "https://brew.sh/foo-1.0.tgz"
def caveats
"setuid"
^^^^^^ Don\'t recommend setuid in the caveats, suggest sudo instead.
^^^^^^^^ Don\'t recommend setuid in the caveats, suggest sudo instead.
end
end
RUBY

View File

@ -33,12 +33,12 @@ describe RuboCop::Cop::FormulaAudit::Checksum do
stable do
url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz"
sha256 "5cf6e1ae0a645b426c0474cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9ad"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ sha256 should be 64 characters
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ sha256 should be 64 characters
resource "foo-package" do
url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz"
sha256 "5cf6e1ae0a645b426c047aaa4cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ sha256 should be 64 characters
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ sha256 should be 64 characters
end
end
end
@ -89,7 +89,7 @@ describe RuboCop::Cop::FormulaAudit::ChecksumCase do
RUBY
end
it "reports an offense if a checksum outside a `stable` block contains uppercase letters" do
it "reports and corrects an offense if a checksum outside a `stable` block contains uppercase letters" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -109,27 +109,14 @@ describe RuboCop::Cop::FormulaAudit::ChecksumCase do
end
end
RUBY
end
it "auto-corrects checksums that contain uppercase letters" do
source = <<~RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
stable do
url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz"
sha256 "5cf6e1ae0A645b426c0a7cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9a"
resource "foo-package" do
url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz"
sha256 "5cf6e1Ae0a645b426b047aa4cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea9"
resource "foo-outside" do
url "https://github.com/foo-lang/foo-outside/archive/0.18.0.tar.gz"
sha256 "a4cc7cd3f7d1605ffa1ac5755cf6e1ae0a645b426b047a6a39a8b2268ddc7ea9"
end
end
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
stable do
url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz"
sha256 "5cf6e1ae0a645b426c0a7cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9a"
@ -141,9 +128,6 @@ describe RuboCop::Cop::FormulaAudit::ChecksumCase do
end
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
end
end

View File

@ -6,55 +6,47 @@ require "rubocops/class"
describe RuboCop::Cop::FormulaAudit::ClassName do
subject(:cop) { described_class.new }
it "reports an offense when using ScriptFileFormula" do
expect_offense(<<~RUBY)
class Foo < ScriptFileFormula
^^^^^^^^^^^^^^^^^ ScriptFileFormula is deprecated, use Formula instead
url 'https://brew.sh/foo-1.0.tgz'
end
RUBY
end
it "reports an offense when using GithubGistFormula" do
expect_offense(<<~RUBY)
class Foo < GithubGistFormula
^^^^^^^^^^^^^^^^^ GithubGistFormula is deprecated, use Formula instead
url 'https://brew.sh/foo-1.0.tgz'
end
RUBY
end
it "reports an offense when using AmazonWebServicesFormula" do
expect_offense(<<~RUBY)
class Foo < AmazonWebServicesFormula
^^^^^^^^^^^^^^^^^^^^^^^^ AmazonWebServicesFormula is deprecated, use Formula instead
url 'https://brew.sh/foo-1.0.tgz'
end
RUBY
end
it "supports auto-correcting deprecated parent classes" do
source = <<~RUBY
class Foo < AmazonWebServicesFormula
url 'https://brew.sh/foo-1.0.tgz'
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
it "reports and corrects an offense when using ScriptFileFormula" do
expect_offense(<<~RUBY)
class Foo < ScriptFileFormula
^^^^^^^^^^^^^^^^^ ScriptFileFormula is deprecated, use Formula instead
url 'https://brew.sh/foo-1.0.tgz'
end
RUBY
expect_correction(corrected_source)
end
it "reports and corrects an offense when using GithubGistFormula" do
expect_offense(<<~RUBY)
class Foo < GithubGistFormula
^^^^^^^^^^^^^^^^^ GithubGistFormula is deprecated, use Formula instead
url 'https://brew.sh/foo-1.0.tgz'
end
RUBY
expect_correction(corrected_source)
end
it "reports and corrects an offense when using AmazonWebServicesFormula" do
expect_offense(<<~RUBY)
class Foo < AmazonWebServicesFormula
^^^^^^^^^^^^^^^^^^^^^^^^ AmazonWebServicesFormula is deprecated, use Formula instead
url 'https://brew.sh/foo-1.0.tgz'
end
RUBY
expect_correction(corrected_source)
end
end
describe RuboCop::Cop::FormulaAudit::Test do
subject(:cop) { described_class.new }
it "reports an offense when /usr/local/bin is found in test calls" do
it "reports and corrects an offense when /usr/local/bin is found in test calls" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -65,9 +57,19 @@ describe RuboCop::Cop::FormulaAudit::Test do
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
test do
system "\#{bin}/test"
end
end
RUBY
end
it "reports an offense when passing 0 as the second parameter to shell_output" do
it "reports and corrects an offense when passing 0 as the second parameter to shell_output" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -78,6 +80,16 @@ describe RuboCop::Cop::FormulaAudit::Test do
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
test do
shell_output("\#{bin}/test")
end
end
RUBY
end
it "reports an offense when there is an empty test block" do
@ -104,31 +116,6 @@ describe RuboCop::Cop::FormulaAudit::Test do
end
RUBY
end
it "supports auto-correcting test calls" do
source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
test do
shell_output("/usr/local/sbin/test", 0)
end
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
test do
shell_output("\#{sbin}/test")
end
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
end
describe RuboCop::Cop::FormulaAuditStrict::TestPresent do

View File

@ -7,7 +7,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
subject(:cop) { described_class.new }
context "When auditing formula components order" do
it "When uses_from_macos precedes depends_on" do
it "reports and corrects an offense when `uses_from_macos` precedes `depends_on`" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -18,9 +18,20 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
^^^^^^^^^^^^^^^^ `depends_on` (line 6) should be put before `uses_from_macos` (line 5)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
depends_on "foo"
uses_from_macos "apple"
end
RUBY
end
it "When license precedes sha256" do
it "reports and corrects an offense when `license` precedes `sha256`" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -30,9 +41,18 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
^^^^^^^^^^^^^^^^^^^^^ `sha256` (line 5) should be put before `license` (line 4)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
sha256 "samplesha256"
license "0BSD"
end
RUBY
end
it "When `bottle` precedes `livecheck`" do
it "reports and corrects an offense when `bottle` precedes `livecheck`" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -47,9 +67,23 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
livecheck do
url "https://brew.sh/foo/versions/"
regex(/href=.+?foo-(\d+(?:\.\d+)+)\.t/)
end
it "When url precedes homepage" do
bottle :unneeded
end
RUBY
end
it "reports and corrects an offense when `url` precedes `homepage`" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -57,9 +91,16 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
^^^^^^^^^^^^^^^^^^^^^^^^^^ `homepage` (line 3) should be put before `url` (line 2)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
end
it "When `resource` precedes `depends_on`" do
it "reports and corrects an offense when `resource` precedes `depends_on`" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -72,9 +113,21 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
^^^^^^^^^^^^^^^^^^^^ `depends_on` (line 8) should be put before `resource` (line 4)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
depends_on "openssl"
resource "foo2" do
url "https://brew.sh/foo-2.0.tgz"
end
end
RUBY
end
it "When `test` precedes `plist`" do
it "reports and corrects an offense when `test` precedes `plist`" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -88,9 +141,22 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
def plist
end
it "When `install` precedes `depends_on`" do
test do
expect(shell_output("./dogs")).to match("Dogs are terrific")
end
end
RUBY
end
it "reports and corrects an offense when `install` precedes `depends_on`" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -102,9 +168,20 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
^^^^^^^^^^^^^^^^^^^^ `depends_on` (line 7) should be put before `install` (line 4)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
depends_on "openssl"
def install
end
end
RUBY
end
it "When `test` precedes `depends_on`" do
it "reports and corrects an offense when `test` precedes `depends_on`" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -119,9 +196,23 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
^^^^^^^^^^^^^^^^^^^^ `depends_on` (line 10) should be put before `install` (line 4)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
depends_on "openssl"
def install
end
it "When only one of many `depends_on` precedes `conflicts_with`" do
def test
end
end
RUBY
end
it "reports and corrects an offense when only one of many `depends_on` precedes `conflicts_with`" do
expect_offense(<<~RUBY)
class Foo < Formula
depends_on "autoconf" => :build
@ -133,9 +224,20 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
depends_on "gettext"
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
depends_on "autoconf" => :build
depends_on "automake" => :build
depends_on "libtool" => :build
depends_on "pkg-config" => :build
depends_on "gettext"
conflicts_with "visionmedia-watch"
end
RUBY
end
it "the on_macos block is not after uses_from_macos" do
it "reports and corrects an offense when the `on_macos` block precedes `uses_from_macos`" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -146,9 +248,20 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
^^^^^^^^^^^^^^^^^^^^^ `uses_from_macos` (line 6) should be put before `on_macos` (line 3)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
uses_from_macos "bar"
on_macos do
depends_on "readline"
end
end
RUBY
end
it "the on_linux block is not after uses_from_macos" do
it "reports and corrects an offense when the `on_linux` block precedes `uses_from_macos`" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -159,9 +272,20 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
^^^^^^^^^^^^^^^^^^^^^ `uses_from_macos` (line 6) should be put before `on_linux` (line 3)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
uses_from_macos "bar"
on_linux do
depends_on "readline"
end
end
RUBY
end
it "the on_linux block is not after the on_macos block" do
it "reports and corrects an offense when the `on_linux` block precedes the `on_macos` block" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -174,70 +298,35 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
end
end
RUBY
end
end
context "When auditing formula components order with autocorrect" do
it "When url precedes homepage" do
source = <<~RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
homepage "https://brew.sh"
end
RUBY
correct_source = <<~RUBY
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
corrected_source = autocorrect_source(source)
expect(corrected_source).to eq(correct_source)
on_macos do
depends_on "readline"
end
it "When `resource` precedes `depends_on`" do
source = <<~RUBY
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
resource "foo2" do
url "https://brew.sh/foo-2.0.tgz"
end
depends_on "openssl"
end
RUBY
correct_source = <<~RUBY
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
depends_on "openssl"
resource "foo2" do
url "https://brew.sh/foo-2.0.tgz"
on_linux do
depends_on "vim"
end
end
RUBY
corrected_source = autocorrect_source(source)
expect(corrected_source).to eq(correct_source)
end
end
it "When `depends_on` precedes `deprecate!`" do
source = <<~RUBY
it "reports and corrects an offense when `depends_on` precedes `deprecate!`" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
depends_on "openssl"
deprecate! because: "has been replaced by bar"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `deprecate!` (line 6) should be put before `depends_on` (line 4)
end
RUBY
correct_source = <<~RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -246,10 +335,6 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
depends_on "openssl"
end
RUBY
corrected_source = autocorrect_source(source)
expect(corrected_source).to eq(correct_source)
end
end
context "no on_os_block" do
@ -351,9 +436,8 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
end
RUBY
end
end
it "there can only be one on_macos block" do
it "reports an offense when there are multiple `on_macos` blocks" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -369,7 +453,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "there can only be one on_linux block" do
it "reports an offense when there are multiple `on_linux` blocks" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -385,7 +469,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "the on_macos block can only contain depends_on, patch and resource nodes" do
it "reports an offense when the `on_macos` block contains nodes other than `depends_on`, `patch` or `resource`" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -398,7 +482,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "the on_linux block can only contain depends_on, patch and resource nodes" do
it "reports an offense when the `on_linux` block contains nodes other than `depends_on`, `patch` or `resource`" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -412,7 +496,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
end
context "in a resource block" do
it "reports no offenses for a valid on_macos and on_linux block" do
it "reports no offenses for a valid `on_macos` and `on_linux` block" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -432,7 +516,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "reports no offenses for a valid on_macos and on_linux block with versions" do
it "reports no offenses for a valid `on_macos` and `on_linux` block with versions" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -454,7 +538,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "reports an offense if there are two on_macos blocks" do
it "reports an offense if there are two `on_macos` blocks" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -475,7 +559,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "reports an offense if there are two on_linux blocks" do
it "reports an offense if there are two `on_linux` blocks" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -496,7 +580,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "reports no offenses if there is an on_macos block but no on_linux block" do
it "reports no offenses if there is an `on_macos` block but no `on_linux` block" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -510,7 +594,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "reports no offenses if there is an on_linux block but no on_macos block" do
it "reports no offenses if there is an `on_linux` block but no `on_macos` block" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -524,7 +608,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "reports an offense if the content of an on_macos block is improperly formatted" do
it "reports an offense if the content of an `on_macos` block is improperly formatted" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -545,7 +629,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "reports no offenses if an on_macos block has if-else branches that are properly formatted" do
it "reports no offenses if an `on_macos` block has if-else branches that are properly formatted" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -570,7 +654,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "reports an offense if an on_macos block has if-else branches that aren't properly formatted" do
it "reports an offense if an `on_macos` block has if-else branches that aren't properly formatted" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -596,7 +680,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "reports an offense if the content of an on_linux block is improperly formatted" do
it "reports an offense if the content of an `on_linux` block is improperly formatted" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -617,7 +701,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "reports no offenses if an on_linux block has if-else branches that are properly formatted" do
it "reports no offenses if an `on_linux` block has if-else branches that are properly formatted" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -642,7 +726,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
it "reports an offense if an on_linux block has if-else branches that aren't properly formatted" do
it "reports an offense if an `on_linux` block has if-else branches that aren't properly formatted" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -668,4 +752,5 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY
end
end
end
end

View File

@ -7,7 +7,7 @@ describe RuboCop::Cop::FormulaAudit::Conflicts do
subject(:cop) { described_class.new }
context "when auditing `conflicts_with`" do
it "reports an offense if reason is capitalized" do
it "reports and corrects an offense if reason is capitalized" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -16,9 +16,17 @@ describe RuboCop::Cop::FormulaAudit::Conflicts do
conflicts_with "baz", :because => "Foo is the formula name which does not require downcasing"
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
conflicts_with "bar", :because => "reason"
conflicts_with "baz", :because => "Foo is the formula name which does not require downcasing"
end
RUBY
end
it "reports an offense if reason ends with a period" do
it "reports and corrects an offense if reason ends with a period" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -26,6 +34,13 @@ describe RuboCop::Cop::FormulaAudit::Conflicts do
^^^^^^^^^ `conflicts_with` reason should not end with a period.
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
conflicts_with "bar", "baz", :because => "reason"
end
RUBY
end
it "reports an offense if it is present in a versioned formula" do
@ -46,43 +61,5 @@ describe RuboCop::Cop::FormulaAudit::Conflicts do
end
RUBY
end
it "auto-corrects capitalized reason" do
source = <<~RUBY
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
conflicts_with "bar", :because => "Reason"
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
conflicts_with "bar", :because => "reason"
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
it "auto-corrects trailing period" do
source = <<~RUBY
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
conflicts_with "bar", :because => "reason."
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
conflicts_with "bar", :because => "reason"
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
end
end

View File

@ -7,7 +7,7 @@ describe RuboCop::Cop::FormulaAudit::DependencyOrder do
subject(:cop) { described_class.new }
context "when auditing `uses_from_macos`" do
it "reports an offense if wrong conditional order" do
it "reports and corrects incorrectly ordered conditional dependencies" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -17,9 +17,18 @@ describe RuboCop::Cop::FormulaAudit::DependencyOrder do
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 5) should be put before dependency "apple" (line 4)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
uses_from_macos "foo" => :optional
uses_from_macos "apple" if build.with? "foo"
end
RUBY
end
it "reports an offense if wrong alphabetical order" do
it "reports and corrects incorrectly ordered alphabetical dependencies" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -29,9 +38,18 @@ describe RuboCop::Cop::FormulaAudit::DependencyOrder do
^^^^^^^^^^^^^^^^^^^^^ dependency "bar" (line 5) should be put before dependency "foo" (line 4)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
uses_from_macos "bar"
uses_from_macos "foo"
end
RUBY
end
it "supports requirement constants" do
it "reports and corrects incorrectly ordered dependencies that are Requirements" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -41,9 +59,18 @@ describe RuboCop::Cop::FormulaAudit::DependencyOrder do
^^^^^^^^^^^^^^^^^^^^^ dependency "bar" (line 5) should be put before dependency "FooRequirement" (line 4)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
uses_from_macos "bar"
uses_from_macos FooRequirement
end
RUBY
end
it "reports an offense if wrong conditional order with block" do
it "reports and corrects wrong conditional order within a spec block" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -60,6 +87,20 @@ describe RuboCop::Cop::FormulaAudit::DependencyOrder do
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 10) should be put before dependency "apple" (line 9)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
head do
uses_from_macos "bar"
uses_from_macos "foo" => :optional
uses_from_macos "apple" if build.with? "foo"
end
uses_from_macos "foo" => :optional
uses_from_macos "apple" if build.with? "foo"
end
RUBY
end
it "reports no offenses if correct order for multiple tags" do
@ -76,7 +117,7 @@ describe RuboCop::Cop::FormulaAudit::DependencyOrder do
end
context "when auditing `depends_on`" do
it "reports an offense if wrong conditional order" do
it "reports and corrects incorrectly ordered conditional dependencies" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -86,9 +127,18 @@ describe RuboCop::Cop::FormulaAudit::DependencyOrder do
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 5) should be put before dependency "apple" (line 4)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
depends_on "foo" => :optional
depends_on "apple" if build.with? "foo"
end
RUBY
end
it "reports an offense if wrong alphabetical order" do
it "reports and corrects incorrectly ordered alphabetical dependencies" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -98,9 +148,18 @@ describe RuboCop::Cop::FormulaAudit::DependencyOrder do
^^^^^^^^^^^^^^^^ dependency "bar" (line 5) should be put before dependency "foo" (line 4)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
depends_on "bar"
depends_on "foo"
end
RUBY
end
it "supports requirement constants" do
it "reports and corrects incorrectly ordered dependencies that are Requirements" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -110,9 +169,18 @@ describe RuboCop::Cop::FormulaAudit::DependencyOrder do
^^^^^^^^^^^^^^^^ dependency "bar" (line 5) should be put before dependency "FooRequirement" (line 4)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
depends_on "bar"
depends_on FooRequirement
end
RUBY
end
it "reports an offense if wrong conditional order with block" do
it "reports and corrects wrong conditional order within a spec block" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
@ -129,6 +197,20 @@ describe RuboCop::Cop::FormulaAudit::DependencyOrder do
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 10) should be put before dependency "apple" (line 9)
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
head do
depends_on "bar"
depends_on "foo" => :optional
depends_on "apple" if build.with? "foo"
end
depends_on "foo" => :optional
depends_on "apple" if build.with? "foo"
end
RUBY
end
it "reports no offenses if correct order for multiple tags" do
@ -143,52 +225,4 @@ describe RuboCop::Cop::FormulaAudit::DependencyOrder do
RUBY
end
end
context "when auto-correcting" do
it "supports wrong conditional `uses_from_macos` order" do
source = <<~RUBY
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
uses_from_macos "apple" if build.with? "foo"
uses_from_macos "foo" => :optional
end
RUBY
correct_source = <<~RUBY
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
uses_from_macos "foo" => :optional
uses_from_macos "apple" if build.with? "foo"
end
RUBY
corrected_source = autocorrect_source(source)
expect(corrected_source).to eq(correct_source)
end
it "supports wrong conditional `depends_on` order" do
source = <<~RUBY
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
depends_on "apple" if build.with? "foo"
depends_on "foo" => :optional
end
RUBY
correct_source = <<~RUBY
class Foo < Formula
homepage "https://brew.sh"
url "https://brew.sh/foo-1.0.tgz"
depends_on "foo" => :optional
depends_on "apple" if build.with? "foo"
end
RUBY
corrected_source = autocorrect_source(source)
expect(corrected_source).to eq(correct_source)
end
end
end

View File

@ -7,7 +7,7 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableDate do
subject(:cop) { described_class.new }
context "when auditing `deprecate!`" do
it "reports an offense if `date` is not ISO 8601 compliant" do
it "reports and corrects an offense if `date` is not ISO 8601 compliant" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -15,9 +15,16 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableDate do
^^^^^^^^^^^^^^^ Use `2020-06-25` to comply with ISO 8601
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! date: "2020-06-25"
end
RUBY
end
it "reports an offense if `date` is not ISO 8601 compliant (with `reason`)" do
it "reports and corrects an offense if `date` is not ISO 8601 compliant (with `reason`)" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -25,6 +32,13 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableDate do
^^^^^^^^^^^^^^^ Use `2020-06-25` to comply with ISO 8601
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! because: "is broken", date: "2020-06-25"
end
RUBY
end
it "reports no offenses if `date` is ISO 8601 compliant" do
@ -62,48 +76,10 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableDate do
end
RUBY
end
it "auto-corrects `date` to ISO 8601 format" do
source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! date: "June 25, 2020"
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! date: "2020-06-25"
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
it "auto-corrects `date` to ISO 8601 format (with `reason`)" do
source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! because: "is broken", date: "June 25, 2020"
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! because: "is broken", date: "2020-06-25"
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
end
context "when auditing `disable!`" do
it "reports an offense if `date` is not ISO 8601 compliant" do
it "reports and corrects an offense if `date` is not ISO 8601 compliant" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -111,9 +87,16 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableDate do
^^^^^^^^^^^^^^^ Use `2020-06-25` to comply with ISO 8601
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! date: "2020-06-25"
end
RUBY
end
it "reports an offense if `date` is not ISO 8601 compliant (with `reason`)" do
it "reports and corrects an offense if `date` is not ISO 8601 compliant (with `reason`)" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -121,6 +104,13 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableDate do
^^^^^^^^^^^^^^^ Use `2020-06-25` to comply with ISO 8601
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! because: "is broken", date: "2020-06-25"
end
RUBY
end
it "reports no offenses if `date` is ISO 8601 compliant" do
@ -158,44 +148,6 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableDate do
end
RUBY
end
it "auto-corrects `date` to ISO 8601 format" do
source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! date: "June 25, 2020"
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! date: "2020-06-25"
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
it "auto-corrects `date` to ISO 8601 format (with `reason`)" do
source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! because: "is broken", date: "June 25, 2020"
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! because: "is broken", date: "2020-06-25"
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
end
end
@ -259,7 +211,7 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
RUBY
end
it "reports an offense if `reason` starts with 'it'" do
it "reports and corrects an offense if `reason` starts with 'it'" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -267,9 +219,16 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
^^^^^^^^^^^^^^ Do not start the reason with `it`
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! because: "is broken"
end
RUBY
end
it "reports an offense if `reason` starts with 'it' (with `date`)" do
it "reports and corrects an offense if `reason` starts with 'it' (with `date`)" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -277,9 +236,16 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
^^^^^^^^^^^^^^ Do not start the reason with `it`
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! date: "2020-08-28", because: "is broken"
end
RUBY
end
it "reports an offense if `reason` ends with a period" do
it "reports and corrects an offense if `reason` ends with a period" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -287,9 +253,16 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
^^^^^^^^^^^^ Do not end the reason with a punctuation mark
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! because: "is broken"
end
RUBY
end
it "reports an offense if `reason` ends with an exclamation point" do
it "reports and corrects an offense if `reason` ends with an exclamation point" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -297,9 +270,16 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
^^^^^^^^^^^^ Do not end the reason with a punctuation mark
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! because: "is broken"
end
RUBY
end
it "reports an offense if `reason` ends with a question mark" do
it "reports and corrects an offense if `reason` ends with a question mark" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -307,9 +287,16 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
^^^^^^^^^^^^ Do not end the reason with a punctuation mark
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! because: "is broken"
end
RUBY
end
it "reports an offense if `reason` ends with a period (with `date`)" do
it "reports and corrects an offense if `reason` ends with a period (with `date`)" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -317,44 +304,13 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
^^^^^^^^^^^^ Do not end the reason with a punctuation mark
end
RUBY
end
it "auto-corrects `reason` to remove 'it'" do
source = <<~RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! because: "it is broken"
deprecate! date: "2020-08-28", because: "is broken"
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! because: "is broken"
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
it "auto-corrects `reason` to remove punctuation" do
source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! because: "is broken."
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
deprecate! because: "is broken"
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
end
@ -415,7 +371,7 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
RUBY
end
it "reports an offense if `reason` starts with 'it'" do
it "reports and corrects an offense if `reason` starts with 'it'" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -423,9 +379,16 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
^^^^^^^^^^^^^^ Do not start the reason with `it`
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! because: "is broken"
end
RUBY
end
it "reports an offense if `reason` starts with 'it' (with `date`)" do
it "reports and corrects an offense if `reason` starts with 'it' (with `date`)" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -433,9 +396,16 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
^^^^^^^^^^^^^^ Do not start the reason with `it`
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! date: "2020-08-28", because: "is broken"
end
RUBY
end
it "reports an offense if `reason` ends with a period" do
it "reports and corrects an offense if `reason` ends with a period" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -443,9 +413,16 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
^^^^^^^^^^^^ Do not end the reason with a punctuation mark
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! because: "is broken"
end
RUBY
end
it "reports an offense if `reason` ends with an exclamation point" do
it "reports and corrects an offense if `reason` ends with an exclamation point" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -453,9 +430,16 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
^^^^^^^^^^^^ Do not end the reason with a punctuation mark
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! because: "is broken"
end
RUBY
end
it "reports an offense if `reason` ends with a question mark" do
it "reports and corrects an offense if `reason` ends with a question mark" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -463,9 +447,16 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
^^^^^^^^^^^^ Do not end the reason with a punctuation mark
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! because: "is broken"
end
RUBY
end
it "reports an offense if `reason` ends with a period (with `date`)" do
it "reports and corrects an offense if `reason` ends with a period (with `date`)" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -473,44 +464,13 @@ describe RuboCop::Cop::FormulaAudit::DeprecateDisableReason do
^^^^^^^^^^^^ Do not end the reason with a punctuation mark
end
RUBY
end
it "auto-corrects to remove 'it'" do
source = <<~RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! because: "it is broken"
disable! date: "2020-08-28", because: "is broken"
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! because: "is broken"
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
it "auto-corrects to remove punctuation" do
source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! because: "is broken."
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
disable! because: "is broken"
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
end
end

View File

@ -6,8 +6,8 @@ require "rubocops/formula_desc"
describe RuboCop::Cop::FormulaAudit::Desc do
subject(:cop) { described_class.new }
context "When auditing formula desc" do
it "When there is no desc" do
context "When auditing formula `desc` methods" do
it "reports an offense when there is no `desc`" do
expect_offense(<<~RUBY)
class Foo < Formula
^^^^^^^^^^^^^^^^^^^ Formula should have a desc (Description).
@ -16,7 +16,7 @@ describe RuboCop::Cop::FormulaAudit::Desc do
RUBY
end
it "When desc is an empty string" do
it "reports an offense when `desc` is an empty string" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -26,7 +26,7 @@ describe RuboCop::Cop::FormulaAudit::Desc do
RUBY
end
it "When desc is too long" do
it "reports an offense when `desc` is too long" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -36,7 +36,7 @@ describe RuboCop::Cop::FormulaAudit::Desc do
RUBY
end
it "When desc is a multiline string" do
it "reports an offense when `desc` is a multiline string" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -48,39 +48,39 @@ describe RuboCop::Cop::FormulaAudit::Desc do
end
end
context "When auditing formula desc" do
it "When the description starts with a leading space" do
context "When auditing formula description texts" do
it "reports an offense when the description starts with a leading space" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
desc ' Description with a leading space'
^ Description shouldn\'t have leading spaces.
^ Description shouldn't have leading spaces.
end
RUBY
end
it "When the description ends with a trailing space" do
it "reports an offense when the description ends with a trailing space" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
desc 'Description with a trailing space '
^ Description shouldn\'t have trailing spaces.
^ Description shouldn't have trailing spaces.
end
RUBY
end
it "When \"command-line\" is incorrectly spelled in the desc" do
it "reports an offense when \"command-line\" is incorrectly spelled in the description" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
desc 'command line'
^ Description should start with a capital letter.
^^^^^^^^^^^^ Description should use \"command-line\" instead of \"command line\".
^^^^^^^^^^^^ Description should use "command-line" instead of "command line".
end
RUBY
end
it "When an article is used in the desc" do
it "reports an offense when an article is used in the description" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -98,7 +98,7 @@ describe RuboCop::Cop::FormulaAudit::Desc do
RUBY
end
it "When the desc starts with a lowercase letter" do
it "reports an offense when the description starts with a lowercase letter" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -108,7 +108,7 @@ describe RuboCop::Cop::FormulaAudit::Desc do
RUBY
end
it "When the desc starts with the formula name" do
it "reports an offense when the description starts with the formula name" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -118,7 +118,7 @@ describe RuboCop::Cop::FormulaAudit::Desc do
RUBY
end
it "When the description ends with a full stop" do
it "reports an offense when the description ends with a full stop" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -128,23 +128,23 @@ describe RuboCop::Cop::FormulaAudit::Desc do
RUBY
end
it "autocorrects all rules" do
source = <<~RUBY
it "reports and corrects all rules for description text" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
desc ' an bar: commandline foo '
^ Description shouldn't have trailing spaces.
^^^^^^^^^^^ Description should use "command-line" instead of "commandline".
^ Description shouldn't have leading spaces.
end
RUBY
correct_source = <<~RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
desc 'Bar: command-line'
end
RUBY
corrected_source = autocorrect_source(source, "/homebrew-core/Formula/foo.rb")
expect(corrected_source).to eq(correct_source)
end
end
end

View File

@ -7,64 +7,149 @@ describe RuboCop::Cop::FormulaAudit::Homepage do
subject(:cop) { described_class.new }
context "When auditing homepage" do
it "When there is no homepage" do
source = <<~RUBY
it "reports an offense when there is no homepage" do
expect_offense(<<~RUBY)
class Foo < Formula
^^^^^^^^^^^^^^^^^^^ Formula should have a homepage.
url 'https://brew.sh/foo-1.0.tgz'
end
RUBY
expected_offenses = [{ message: "Formula should have a homepage.",
severity: :convention,
line: 1,
column: 0,
source: source }]
inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
end
end
it "Homepage with ftp" do
source = <<~RUBY
it "reports an offense when the homepage is not HTTP or HTTPS" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "ftp://brew.sh/foo"
^^^^^^^^^^^^^^^^^^^ The homepage should start with http or https.
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
end
it "reports an offense for freedesktop.org wiki pages" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "http://www.freedesktop.org/wiki/bar"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Freedesktop homepages should be styled `https://wiki.freedesktop.org/project_name`
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
end
it "reports an offense for freedesktop.org software wiki pages" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "http://www.freedesktop.org/wiki/Software/baz"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Freedesktop homepages should be styled `https://wiki.freedesktop.org/www/Software/project_name`
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
end
it "reports and corrects Google Code homepages" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://code.google.com/p/qux"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Google Code homepages should end with a slash
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
expected_offenses = [{ message: "The homepage should start with http or " \
"https (URL is ftp://brew.sh/foo).",
severity: :convention,
line: 2,
column: 2,
source: source }]
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://code.google.com/p/qux/"
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
end
inspect_source(source)
it "reports and corrects GitHub homepages" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://github.com/foo/bar.git"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GitHub homepages should not end with .git
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
expected_offenses.zip(cop.offenses).each do |expected, actual|
expect_offense(expected, actual)
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://github.com/foo/bar"
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
end
context "for Sourceforge" do
correct_formula = <<~RUBY
class Foo < Formula
homepage "https://foo.sourceforge.io/"
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
it "reports and corrects [1]" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "http://foo.sourceforge.net/"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Sourceforge homepages should be `https://foo.sourceforge.io/`
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
expect_correction(correct_formula)
end
it "reports and corrects [2]" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "http://foo.sourceforge.net"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Sourceforge homepages should be `https://foo.sourceforge.io/`
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
expect_correction(correct_formula)
end
it "reports and corrects [3]" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "http://foo.sf.net/"
^^^^^^^^^^^^^^^^^^^^ Sourceforge homepages should be `https://foo.sourceforge.io/`
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
expect_correction(correct_formula)
end
end
it "Homepage URLs" do
it "reports and corrects readthedocs.org pages" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "https://foo.readthedocs.org"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Readthedocs homepages should be `https://foo.readthedocs.io`
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
homepage "https://foo.readthedocs.io"
url "https://brew.sh/foo-1.0.tgz"
end
RUBY
end
it "reports an offense for HTTP homepages" do
formula_homepages = {
"bar" => "http://www.freedesktop.org/wiki/bar",
"baz" => "http://www.freedesktop.org/wiki/Software/baz",
"qux" => "https://code.google.com/p/qux",
"quux" => "http://github.com/quux",
"sf" => "http://foo.sourceforge.io/",
"corge" => "http://savannah.nongnu.org/corge",
"grault" => "http://grault.github.io/",
"garply" => "http://www.gnome.org/garply",
"sf1" => "http://foo.sourceforge.net/",
"sf2" => "http://foo.sourceforge.net",
"sf3" => "http://foo.sf.net/",
"sf4" => "http://foo.sourceforge.io/",
"waldo" => "http://www.gnu.org/waldo",
"dotgit" => "https://github.com/foo/bar.git",
"rtd" => "https://foo.readthedocs.org",
"dotgit" => "http://github.com/quux",
}
formula_homepages.each do |name, homepage|
@ -75,65 +160,19 @@ describe RuboCop::Cop::FormulaAudit::Homepage do
end
RUBY
inspect_source(source)
if homepage.include?("http://www.freedesktop.org")
if homepage.include?("Software")
expected_offenses = [{ message: "#{homepage} should be styled " \
"`https://wiki.freedesktop.org/www/Software/project_name`",
severity: :convention,
line: 2,
column: 2,
source: source }]
else
expected_offenses = [{ message: "#{homepage} should be styled " \
"`https://wiki.freedesktop.org/project_name`",
severity: :convention,
line: 2,
column: 2,
source: source }]
end
elsif homepage.include?("https://code.google.com")
expected_offenses = [{ message: "#{homepage} should end with a slash",
severity: :convention,
line: 2,
column: 2,
source: source }]
elsif homepage.match?(/foo\.(sf|sourceforge)\.net/)
expected_offenses = [{ message: "#{homepage} should be `https://foo.sourceforge.io/`",
severity: :convention,
line: 2,
column: 2,
source: source }]
elsif homepage.match?("https://github.com/foo/bar.git")
expected_offenses = [{ message: "GitHub homepages (`#{homepage}`) should not end with .git",
severity: :convention,
line: 2,
column: 11,
source: source }]
elsif homepage.match?("https://foo.readthedocs.org")
expected_offenses = [{ message: "#{homepage} should be `https://foo.readthedocs.io`",
severity: :convention,
line: 2,
column: 11,
source: source }]
else
expected_offenses = [{ message: "Please use https:// for #{homepage}",
severity: :convention,
line: 2,
column: 2,
column: 11,
source: source }]
end
expected_offenses.zip([cop.offenses.last]).each do |expected, actual|
expect_offense(expected, actual)
end
end
end
def expect_offense(expected, actual)
expected_offenses.zip([inspect_source(source).last]).each do |expected, actual|
expect(actual.message).to eq(expected[:message])
expect(actual.severity).to eq(expected[:severity])
expect(actual.line).to eq(expected[:line])
expect(actual.column).to eq(expected[:column])
end
end
end
end
end

View File

@ -6,7 +6,7 @@ require "rubocops/keg_only"
describe RuboCop::Cop::FormulaAudit::KegOnly do
subject(:cop) { described_class.new }
specify "keg_only_needs_downcasing" do
it "reports and corrects an offense when the `keg_only` reason is capitalized" do
expect_offense(<<~RUBY)
class Foo < Formula
@ -17,9 +17,19 @@ describe RuboCop::Cop::FormulaAudit::KegOnly do
^^^^^^^^^^^^^^^^^ 'Because' from the `keg_only` reason should be 'because'.
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
homepage "https://brew.sh"
keg_only "because why not"
end
RUBY
end
specify "keg_only_redundant_period" do
it "reports and corrects an offense when the `keg_only` reason ends with a period" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -29,51 +39,18 @@ describe RuboCop::Cop::FormulaAudit::KegOnly do
^^^^^^^^^^^^^^^^^^^^^^^ `keg_only` reason should not end with a period.
end
RUBY
end
specify "keg_only_autocorrects_downcasing" do
source = <<~RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
homepage "https://brew.sh"
keg_only "Because why not"
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
homepage "https://brew.sh"
keg_only "because why not"
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
specify "keg_only_autocorrects_redundant_period" do
source = <<~RUBY
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
homepage "https://brew.sh"
keg_only "ending with a period."
end
RUBY
corrected_source = <<~RUBY
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
homepage "https://brew.sh"
keg_only "ending with a period"
end
RUBY
new_source = autocorrect_source(source)
expect(new_source).to eq(corrected_source)
end
specify "keg_only_handles_block_correctly" do
it "reports no offenses when a `keg_only` reason is a block" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -89,7 +66,7 @@ describe RuboCop::Cop::FormulaAudit::KegOnly do
RUBY
end
specify "keg_only_handles_allowlist_correctly" do
it "reports no offenses if a capitalized `keg-only` reason is an exempt proper noun" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -100,12 +77,8 @@ describe RuboCop::Cop::FormulaAudit::KegOnly do
RUBY
end
specify "keg_only does not need downcasing of formula name in reason" do
filename = Formulary.core_path("foo")
File.open(filename, "w") do |file|
FileUtils.chmod "-rwx", filename
expect_no_offenses(<<~RUBY, file)
it "reports no offenses if a capitalized `keg_only` reason is the formula's name" do
expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
@ -113,5 +86,4 @@ describe RuboCop::Cop::FormulaAudit::KegOnly do
end
RUBY
end
end
end

File diff suppressed because it is too large Load Diff

View File

@ -12,12 +12,12 @@ describe RuboCop::Cop::FormulaAudit::Options do
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
option "with-32-bit"
^^^^^^ macOS has been 64-bit only since 10.6 so 32-bit options are deprecated.
^^^^^^^^^^^^^ macOS has been 64-bit only since 10.6 so 32-bit options are deprecated.
end
RUBY
end
it "with universal" do
it "reports an offense when using `:universal`" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -27,7 +27,7 @@ describe RuboCop::Cop::FormulaAudit::Options do
RUBY
end
it "with bad option names" do
it "reports an offense when using bad option names" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -38,7 +38,7 @@ describe RuboCop::Cop::FormulaAudit::Options do
RUBY
end
it "with without-check option name" do
it "reports an offense when using `without-check` option names" do
expect_offense(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -48,7 +48,7 @@ describe RuboCop::Cop::FormulaAudit::Options do
RUBY
end
it "with deprecated_optionss" do
it "reports an offense when using `deprecated_option` in homebrew/core" do
expect_offense(<<~RUBY, "/homebrew-core/")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -58,7 +58,7 @@ describe RuboCop::Cop::FormulaAudit::Options do
RUBY
end
it "with options" do
it "reports an offense when using `option` in homebrew/core" do
expect_offense(<<~RUBY, "/homebrew-core/")
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'

View File

@ -7,7 +7,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
subject(:cop) { described_class.new }
context "When auditing legacy patches" do
it "When there is no legacy patch" do
it "reports no offenses when there is no legacy patch" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
url 'https://brew.sh/foo-1.0.tgz'
@ -15,7 +15,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
RUBY
end
it "Formula with `def patches`" do
it "reports an offense if `def patches` is present" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "ftp://brew.sh/foo"
@ -28,7 +28,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
RUBY
end
it "Patch URLs" do
it "reports an offense for various patch URLs" do
patch_urls = [
"https://raw.github.com/mogaal/sendemail",
"https://mirrors.ustc.edu.cn/macports/trunk/",
@ -48,7 +48,6 @@ describe RuboCop::Cop::FormulaAudit::Patches do
end
EOS
inspect_source(source)
expected_offense = if patch_url.include?("/raw.github.com/")
[{ message:
<<~EOS.chomp,
@ -57,7 +56,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
EOS
severity: :convention,
line: 5,
column: 12,
column: 4,
source: source }]
elsif patch_url.include?("macports/trunk")
[{ message:
@ -67,7 +66,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
EOS
severity: :convention,
line: 5,
column: 33,
column: 4,
source: source }]
elsif patch_url.start_with?("http://trac.macports.org")
[{ message:
@ -77,7 +76,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
EOS
severity: :convention,
line: 5,
column: 5,
column: 4,
source: source }]
elsif patch_url.start_with?("http://bugs.debian.org")
[{ message:
@ -87,7 +86,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
EOS
severity: :convention,
line: 5,
column: 5,
column: 4,
source: source }]
# rubocop:disable Layout/LineLength
elsif patch_url.match?(%r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)})
@ -95,7 +94,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
[{ message: "Use a commit hash URL rather than patch-diff: #{patch_url}",
severity: :convention,
line: 5,
column: 5,
column: 4,
source: source }]
elsif patch_url.match?(%r{https?://github\.com/.+/.+/(?:commit|pull)/[a-fA-F0-9]*.(?:patch|diff)})
[{ message:
@ -105,10 +104,10 @@ describe RuboCop::Cop::FormulaAudit::Patches do
EOS
severity: :convention,
line: 5,
column: 5,
column: 4,
source: source }]
end
expected_offense.zip([cop.offenses.last]).each do |expected, actual|
expected_offense.zip([inspect_source(source).last]).each do |expected, actual|
expect(actual.message).to eq(expected[:message])
expect(actual.severity).to eq(expected[:severity])
expect(actual.line).to eq(expected[:line])
@ -117,7 +116,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
end
end
it "Formula with nested `def patches`" do
it "reports an offense with nested `def patches`" do
source = <<~RUBY
class Foo < Formula
homepage "ftp://brew.sh/foo"
@ -144,12 +143,10 @@ describe RuboCop::Cop::FormulaAudit::Patches do
EOS
severity: :convention,
line: 8,
column: 26,
column: 25,
source: source }]
inspect_source(source)
expected_offenses.zip(cop.offenses).each do |expected, actual|
expected_offenses.zip(inspect_source(source)).each do |expected, actual|
expect(actual.message).to eq(expected[:message])
expect(actual.severity).to eq(expected[:severity])
expect(actual.line).to eq(expected[:line])
@ -206,7 +203,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
end
context "When auditing external patches" do
it "Patch URLs" do
it "reports an offense for various patch URLs" do
patch_urls = [
"https://raw.github.com/mogaal/sendemail",
"https://mirrors.ustc.edu.cn/macports/trunk/",
@ -230,7 +227,6 @@ describe RuboCop::Cop::FormulaAudit::Patches do
end
RUBY
inspect_source(source)
expected_offense = if patch_url.include?("/raw.github.com/")
[{ message:
<<~EOS.chomp,
@ -239,7 +235,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
EOS
severity: :convention,
line: 5,
column: 16,
column: 8,
source: source }]
elsif patch_url.include?("macports/trunk")
[{ message:
@ -249,7 +245,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
EOS
severity: :convention,
line: 5,
column: 37,
column: 8,
source: source }]
elsif patch_url.start_with?("http://trac.macports.org")
[{ message:
@ -259,7 +255,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
EOS
severity: :convention,
line: 5,
column: 9,
column: 8,
source: source }]
elsif patch_url.start_with?("http://bugs.debian.org")
[{ message:
@ -269,19 +265,19 @@ describe RuboCop::Cop::FormulaAudit::Patches do
EOS
severity: :convention,
line: 5,
column: 9,
column: 8,
source: source }]
elsif patch_url.match?(%r{https://github.com/[^/]*/[^/]*/pull})
[{ message: "Use a commit hash URL rather than an unstable pull request URL: #{patch_url}",
severity: :convention,
line: 5,
column: 9,
column: 8,
source: source }]
elsif patch_url.match?(%r{.*gitlab.*/merge_request.*})
[{ message: "Use a commit hash URL rather than an unstable merge request URL: #{patch_url}",
severity: :convention,
line: 5,
column: 9,
column: 8,
source: source }]
elsif patch_url.match?(%r{https://github.com/[^/]*/[^/]*/commit/})
[{ message:
@ -291,7 +287,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
EOS
severity: :convention,
line: 5,
column: 9,
column: 8,
source: source }]
elsif patch_url.match?(%r{.*gitlab.*/commit/})
[{ message:
@ -301,7 +297,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
EOS
severity: :convention,
line: 5,
column: 9,
column: 8,
source: source }]
# rubocop:disable Layout/LineLength
elsif patch_url.match?(%r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)})
@ -309,10 +305,10 @@ describe RuboCop::Cop::FormulaAudit::Patches do
[{ message: "Use a commit hash URL rather than patch-diff: #{patch_url}",
severity: :convention,
line: 5,
column: 9,
column: 8,
source: source }]
end
expected_offense.zip([cop.offenses.last]).each do |expected, actual|
expected_offense.zip([inspect_source(source).last]).each do |expected, actual|
expect(actual.message).to eq(expected[:message])
expect(actual.severity).to eq(expected[:severity])
expect(actual.line).to eq(expected[:line])

View File

@ -16,6 +16,13 @@ describe RuboCop::Cop::FormulaAudit::Text do
homepage "https://brew.sh"
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
homepage "https://brew.sh"
end
RUBY
end
it "with both openssl and libressl optional dependencies" do

View File

@ -200,9 +200,9 @@ describe RuboCop::Cop::FormulaAudit::Urls do
column: formula["col"],
source: source }]
inspect_source(source)
offenses = inspect_source(source)
expected_offenses.zip(cop.offenses.reverse).each do |expected, actual|
expected_offenses.zip(offenses.reverse).each do |expected, actual|
expect(actual.message).to eq(expected[:message])
expect(actual.severity).to eq(expected[:severity])
expect(actual.line).to eq(expected[:line])