Create FormulaCop base class to reuse helper functions in custom cops

This commit is contained in:
Gautham Goli 2017-03-02 20:26:29 +05:30
parent 19f693d25b
commit d32978b859
4 changed files with 79 additions and 25 deletions

View File

@ -8,7 +8,17 @@ AllCops:
require: ./Homebrew/rubocops.rb
Homebrew/FormulaCop:
Enabled: false
Homebrew/CorrectBottleBlock:
Include:
- '**/Taps/homebrew/**/*.rb'
Enabled: true
Homebrew/FormulaDesc:
Include:
- '**/Taps/homebrew/**/*.rb'
Enabled: true
Metrics/AbcSize:

View File

@ -1,20 +1,31 @@
require_relative "./extend/formula_cop"
module RuboCop
module Cop
module Homebrew
class CorrectBottleBlock < Cop
# This cop audits `bottle` block in Formulae
#
# - `rebuild` should be used instead of `revision` in `bottle` block
class CorrectBottleBlock < FormulaCop
MSG = "Use rebuild instead of revision in bottle block".freeze
def on_block(node)
return if block_length(node).zero?
method, _args, body = *node
_keyword, method_name = *method
return unless method_name == :bottle
check_revision?(body)
def audit_formula(_node, _class_node, _parent_class_node, formula_class_body_node)
check(formula_class_body_node)
end
private
def check(formula_class_body_node)
formula_class_body_node.each_child_node(:block) do |block_node|
next if block_length(block_node).zero?
method, _args, block_body = *block_node
_keyword, method_name = *method
next unless method_name == :bottle
check_revision?(block_body)
end
end
def autocorrect(node)
lambda do |corrector|
correction = node.source.sub("revision", "rebuild")

View File

@ -0,0 +1,22 @@
module RuboCop
module Cop
module Homebrew
class FormulaCop < Cop
@registry = Cop.registry
def on_class(node)
# This method is called by RuboCop and is the main entry point
class_node, parent_class_node, body = *node
return unless a_formula_class?(parent_class_node)
audit_formula(node, class_node, parent_class_node, body)
end
private
def a_formula_class?(parent_class_node)
parent_class_node && parent_class_node.const_name == "Formula"
end
end
end
end
end

View File

@ -1,12 +1,20 @@
require_relative "./extend/formula_cop"
require_relative "../extend/string"
module RuboCop
module Cop
module Homebrew
class FormulaDesc < Cop
def on_class(node)
class_node, parent_class_node, body = *node
formula_name = class_node.const_name
return unless parent_class_node && parent_class_node.const_name == "Formula" && body
check(node, body, formula_name)
# This cop audits `desc` in Formulae
#
# - Checks for existence of `desc`
# - Checks if size of `desc` > 80
# - Checks if `desc` begins with an article
# - Checks for correct usage of `command-line` in `desc`
# - Checks if `desc` contains the formula name
class FormulaDesc < FormulaCop
def audit_formula(node, class_node, _parent_class_node, body)
check(node, body, class_node.const_name)
end
private
@ -14,7 +22,7 @@ module RuboCop
def check(node, body, formula_name)
body.each_child_node(:send) do |call_node|
_receiver, call_name, args = *call_node
next unless call_name == :desc && !args.children[0].empty?
next if call_name != :desc || args.children[0].empty?
description = args.children[0]
source_buffer = call_node.source_range.source_buffer
@ -27,27 +35,29 @@ module RuboCop
column = desc_begin_pos - line_begin_pos
length = call_node.children[2].source_range.size
sourcerange = source_range(source_buffer, line_number, column, length)
message = <<-EOS.strip_indent
Description is too long. \"name: desc\" should be less than 80 characters.
message = <<-EOS.undent
Description is too long. "name: desc" should be less than 80 characters.
Length is calculated as #{formula_name} + desc. (currently #{linelength})
EOS
add_offense(call_node, sourcerange, message)
end
match_object = description.match(/([Cc]ommand ?line)/)
match_object = description.match(/(command ?line)/i)
if match_object
column = desc_begin_pos+match_object.begin(0)-line_begin_pos+1
length = match_object.to_s.length
sourcerange = source_range(source_buffer, line_number, column, length)
add_offense(call_node, sourcerange, "Description should use \"command-line\" instead of \"#{match_object}\"")
message = "Description should use \"command-line\" instead of \"#{match_object}\""
add_offense(call_node, sourcerange, message)
end
match_object = description.match(/^([Aa]n?)\s/)
match_object = description.match(/^(an?)\s/i)
if match_object
column = desc_begin_pos+match_object.begin(0)-line_begin_pos+1
length = match_object.to_s.length
sourcerange = source_range(source_buffer, line_number, column, length)
add_offense(call_node, sourcerange, "Description shouldn't start with an indefinite article (#{match_object})")
message = "Description shouldn't start with an indefinite article (#{match_object})"
add_offense(call_node, sourcerange, message)
end
match_object = description.match(/^#{formula_name}/i)
@ -55,9 +65,10 @@ module RuboCop
column = desc_begin_pos+match_object.begin(0)-line_begin_pos+1
length = match_object.to_s.length
sourcerange = source_range(source_buffer, line_number, column, length)
add_offense(call_node, sourcerange, "Description shouldn't include the formula name")
message = "Description shouldn't include the formula name"
add_offense(call_node, sourcerange, message)
end
return
return nil
end
add_offense(node, node.source_range, "Formula should have a desc (Description).")
end