audit: Port rules from line_problems to rubocop part 3
This commit is contained in:
parent
3edae73cd9
commit
b8f811cca6
@ -866,10 +866,6 @@ class FormulaAuditor
|
|||||||
|
|
||||||
problem "Use spaces instead of tabs for indentation" if line =~ /^[ ]*\t/
|
problem "Use spaces instead of tabs for indentation" if line =~ /^[ ]*\t/
|
||||||
|
|
||||||
if line.include?("ENV.x11")
|
|
||||||
problem "Use \"depends_on :x11\" instead of \"ENV.x11\""
|
|
||||||
end
|
|
||||||
|
|
||||||
# Avoid hard-coding compilers
|
# Avoid hard-coding compilers
|
||||||
if line =~ %r{(system|ENV\[.+\]\s?=)\s?['"](/usr/bin/)?(gcc|llvm-gcc|clang)['" ]}
|
if line =~ %r{(system|ENV\[.+\]\s?=)\s?['"](/usr/bin/)?(gcc|llvm-gcc|clang)['" ]}
|
||||||
problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{Regexp.last_match(3)}\""
|
problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{Regexp.last_match(3)}\""
|
||||||
@ -883,14 +879,6 @@ class FormulaAuditor
|
|||||||
problem "Use ENV instead of invoking '#{Regexp.last_match(1)}' to modify the environment"
|
problem "Use ENV instead of invoking '#{Regexp.last_match(1)}' to modify the environment"
|
||||||
end
|
end
|
||||||
|
|
||||||
if formula.name != "wine" && line =~ /ENV\.universal_binary/
|
|
||||||
problem "macOS has been 64-bit only since 10.6 so ENV.universal_binary is deprecated."
|
|
||||||
end
|
|
||||||
|
|
||||||
if line =~ /build\.universal\?/
|
|
||||||
problem "macOS has been 64-bit only so build.universal? is deprecated."
|
|
||||||
end
|
|
||||||
|
|
||||||
if line =~ /version == ['"]HEAD['"]/
|
if line =~ /version == ['"]HEAD['"]/
|
||||||
problem "Use 'build.head?' instead of inspecting 'version'"
|
problem "Use 'build.head?' instead of inspecting 'version'"
|
||||||
end
|
end
|
||||||
@ -931,12 +919,6 @@ class FormulaAuditor
|
|||||||
problem "Use build instead of ARGV to check options"
|
problem "Use build instead of ARGV to check options"
|
||||||
end
|
end
|
||||||
|
|
||||||
problem "Use new-style option definitions" if line.include?("def options")
|
|
||||||
|
|
||||||
if line.end_with?("def test")
|
|
||||||
problem "Use new-style test definitions (test do)"
|
|
||||||
end
|
|
||||||
|
|
||||||
if line.include?("MACOS_VERSION")
|
if line.include?("MACOS_VERSION")
|
||||||
problem "Use MacOS.version instead of MACOS_VERSION"
|
problem "Use MacOS.version instead of MACOS_VERSION"
|
||||||
end
|
end
|
||||||
@ -950,11 +932,6 @@ class FormulaAuditor
|
|||||||
problem "\"#{$&}\" is deprecated, use a comparison to MacOS.version instead"
|
problem "\"#{$&}\" is deprecated, use a comparison to MacOS.version instead"
|
||||||
end
|
end
|
||||||
|
|
||||||
if line =~ /skip_clean\s+:all/
|
|
||||||
problem "`skip_clean :all` is deprecated; brew no longer strips symbols\n" \
|
|
||||||
"\tPass explicit paths to prevent Homebrew from removing empty folders."
|
|
||||||
end
|
|
||||||
|
|
||||||
if line =~ /depends_on [A-Z][\w:]+\.new$/
|
if line =~ /depends_on [A-Z][\w:]+\.new$/
|
||||||
problem "`depends_on` can take requirement classes instead of instances"
|
problem "`depends_on` can take requirement classes instead of instances"
|
||||||
end
|
end
|
||||||
@ -993,30 +970,6 @@ class FormulaAuditor
|
|||||||
problem "Use `assert_match` instead of `assert ...include?`"
|
problem "Use `assert_match` instead of `assert ...include?`"
|
||||||
end
|
end
|
||||||
|
|
||||||
if line.include?('system "npm", "install"') && !line.include?("Language::Node") &&
|
|
||||||
formula.name !~ /^kibana(\@\d+(\.\d+)?)?$/
|
|
||||||
problem "Use Language::Node for npm install args"
|
|
||||||
end
|
|
||||||
|
|
||||||
if line.include?("fails_with :llvm")
|
|
||||||
problem "'fails_with :llvm' is now a no-op so should be removed"
|
|
||||||
end
|
|
||||||
|
|
||||||
if line =~ /system\s+['"](otool|install_name_tool|lipo)/ && formula.name != "cctools"
|
|
||||||
problem "Use ruby-macho instead of calling #{Regexp.last_match(1)}"
|
|
||||||
end
|
|
||||||
|
|
||||||
if formula.tap.to_s == "homebrew/core"
|
|
||||||
["OS.mac?", "OS.linux?"].each do |check|
|
|
||||||
next unless line.include?(check)
|
|
||||||
problem "Don't use #{check}; Homebrew/core only supports macOS"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if line =~ /((revision|version_scheme)\s+0)/
|
|
||||||
problem "'#{Regexp.last_match(1)}' should be removed"
|
|
||||||
end
|
|
||||||
|
|
||||||
return unless @strict
|
return unless @strict
|
||||||
|
|
||||||
problem "`#{Regexp.last_match(1)}` in formulae is deprecated" if line =~ /(env :(std|userpaths))/
|
problem "`#{Regexp.last_match(1)}` in formulae is deprecated" if line =~ /(env :(std|userpaths))/
|
||||||
|
|||||||
@ -3,12 +3,13 @@ require "parser/current"
|
|||||||
module RuboCop
|
module RuboCop
|
||||||
module Cop
|
module Cop
|
||||||
class FormulaCop < Cop
|
class FormulaCop < Cop
|
||||||
|
attr_accessor :file_path
|
||||||
@registry = Cop.registry
|
@registry = Cop.registry
|
||||||
|
|
||||||
# This method is called by RuboCop and is the main entry point
|
# This method is called by RuboCop and is the main entry point
|
||||||
def on_class(node)
|
def on_class(node)
|
||||||
file_path = processed_source.buffer.name
|
@file_path = processed_source.buffer.name
|
||||||
return unless file_path_allowed?(file_path)
|
return unless file_path_allowed?
|
||||||
return unless formula_class?(node)
|
return unless formula_class?(node)
|
||||||
return unless respond_to?(:audit_formula)
|
return unless respond_to?(:audit_formula)
|
||||||
class_node, parent_class_node, @body = *node
|
class_node, parent_class_node, @body = *node
|
||||||
@ -99,8 +100,7 @@ module RuboCop
|
|||||||
def find_method_with_args(node, method_name, *args)
|
def find_method_with_args(node, method_name, *args)
|
||||||
methods = find_every_method_call_by_name(node, method_name)
|
methods = find_every_method_call_by_name(node, method_name)
|
||||||
methods.each do |method|
|
methods.each do |method|
|
||||||
next unless parameters_passed?(method, *args)
|
yield method if parameters_passed?(method, *args)
|
||||||
yield method
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ module RuboCop
|
|||||||
def find_instance_method_call(node, instance, method_name)
|
def find_instance_method_call(node, instance, method_name)
|
||||||
methods = find_every_method_call_by_name(node, method_name)
|
methods = find_every_method_call_by_name(node, method_name)
|
||||||
methods.each do |method|
|
methods.each do |method|
|
||||||
next unless method.receiver && method.receiver.const_name == instance
|
next unless method.receiver && (method.receiver.const_name == instance || method.receiver.method_name == instance)
|
||||||
@offense_source_range = method.source_range
|
@offense_source_range = method.source_range
|
||||||
@offensive_node = method
|
@offensive_node = method
|
||||||
yield method
|
yield method
|
||||||
@ -400,6 +400,12 @@ module RuboCop
|
|||||||
method_name(component_node) if component_node.def_type?
|
method_name(component_node) if component_node.def_type?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns the formula tap
|
||||||
|
def formula_tap
|
||||||
|
return unless match_obj = @file_path.match(%r{/(homebrew-\w+)/})
|
||||||
|
match_obj[1]
|
||||||
|
end
|
||||||
|
|
||||||
def problem(msg)
|
def problem(msg)
|
||||||
add_offense(@offensive_node, @offense_source_range, msg)
|
add_offense(@offensive_node, @offense_source_range, msg)
|
||||||
end
|
end
|
||||||
@ -411,11 +417,11 @@ module RuboCop
|
|||||||
class_node && string_content(class_node) == "Formula"
|
class_node && string_content(class_node) == "Formula"
|
||||||
end
|
end
|
||||||
|
|
||||||
def file_path_allowed?(file_path)
|
def file_path_allowed?
|
||||||
paths_to_exclude = [%r{/Library/Homebrew/compat/},
|
paths_to_exclude = [%r{/Library/Homebrew/compat/},
|
||||||
%r{/Library/Homebrew/test/}]
|
%r{/Library/Homebrew/test/}]
|
||||||
return true if file_path.nil? # file_path is nil when source is directly passed to the cop eg., in specs
|
return true if @file_path.nil? # file_path is nil when source is directly passed to the cop eg., in specs
|
||||||
file_path !~ Regexp.union(paths_to_exclude)
|
@file_path !~ Regexp.union(paths_to_exclude)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -73,7 +73,64 @@ module RuboCop
|
|||||||
next unless block_arg.source.size>1
|
next unless block_arg.source.size>1
|
||||||
problem "\"inreplace <filenames> do |s|\" is preferred over \"|#{block_arg.source}|\"."
|
problem "\"inreplace <filenames> do |s|\" is preferred over \"|#{block_arg.source}|\"."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
[:rebuild, :version_scheme].each do |m|
|
||||||
|
find_method_with_args(body_node, m, 0) do
|
||||||
|
problem "'#{m} 0' should be removed"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
[:mac?, :linux?].each do |m|
|
||||||
|
next unless formula_tap == "homebrew-core"
|
||||||
|
find_instance_method_call(body_node, "OS", m) do |check|
|
||||||
|
problem "Don't use #{check.source}; Homebrew/core only supports macOS"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
find_method_with_args(body_node, :fails_with, :llvm) do
|
||||||
|
problem "'fails_with :llvm' is now a no-op so should be removed"
|
||||||
|
end
|
||||||
|
|
||||||
|
find_method_with_args(body_node, :system, /^(otool|install_name_tool|lipo)$/) do
|
||||||
|
problem "Use ruby-macho instead of calling #{@offensive_node.source}"
|
||||||
|
end
|
||||||
|
#
|
||||||
|
find_method_with_args(body_node, :system, /npm/, /install/) do |m|
|
||||||
|
next if @formula_name =~ /^kibana(\@\d+(\.\d+)?)?$/
|
||||||
|
problem "Use Language::Node for npm install args" unless languageNode?(m)
|
||||||
|
end
|
||||||
|
if find_method_def(body_node, :test)
|
||||||
|
problem "Use new-style test definitions (test do)"
|
||||||
|
end
|
||||||
|
|
||||||
|
if find_method_def(body_node, :options)
|
||||||
|
problem "Use new-style option definitions"
|
||||||
|
end
|
||||||
|
|
||||||
|
find_method_with_args(body_node, :skip_clean, :all) do
|
||||||
|
problem "`skip_clean :all` is deprecated; brew no longer strips symbols\n" \
|
||||||
|
"\tPass explicit paths to prevent Homebrew from removing empty folders."
|
||||||
|
end
|
||||||
|
|
||||||
|
find_instance_method_call(body_node, :build, :universal?) do
|
||||||
|
problem "macOS has been 64-bit only so build.universal? is deprecated."
|
||||||
|
end
|
||||||
|
|
||||||
|
find_instance_method_call(body_node, "ENV", :universal_binary) do
|
||||||
|
problem "macOS has been 64-bit only since 10.6 so ENV.universal_binary is deprecated."
|
||||||
|
end
|
||||||
|
|
||||||
|
find_instance_method_call(body_node, "ENV", :x11) do
|
||||||
|
problem 'Use "depends_on :x11" instead of "ENV.x11"'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This is Pattern Matching method for AST
|
||||||
|
# Takes the AST node as argument and yields matching node if block given
|
||||||
|
# Else returns boolean for the match
|
||||||
|
def_node_search :languageNode?, <<-PATTERN
|
||||||
|
(const (const nil :Language) :Node)
|
||||||
|
PATTERN
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user