From bc2bcef1ba084e271ecdfd523a96e6db477e6475 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Sun, 30 Jul 2017 20:14:59 +0530 Subject: audit: Port classname and template comments audit rules from line_problems method to rubocop --- Library/Homebrew/dev-cmd/audit.rb | 25 -------------- Library/Homebrew/rubocops/extend/formula_cop.rb | 14 ++++++++ Library/Homebrew/rubocops/lines_cop.rb | 43 +++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 25 deletions(-) diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 1f07fa89e..323b37170 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -809,28 +809,6 @@ class FormulaAuditor end def line_problems(line, _lineno) - if line =~ /<(Formula|AmazonWebServicesFormula|ScriptFileFormula|GithubGistFormula)/ - problem "Use a space in class inheritance: class Foo < #{Regexp.last_match(1)}" - end - - # Commented-out cmake support from default template - problem "Commented cmake call found" if line.include?('# system "cmake') - - # Comments from default template - [ - "# PLEASE REMOVE", - "# Documentation:", - "# if this fails, try separate make/make install steps", - "# The URL of the archive", - "## Naming --", - "# if your formula requires any X11/XQuartz components", - "# if your formula fails when building in parallel", - "# Remove unrecognized options if warned by configure", - ].each do |comment| - next unless line.include?(comment) - problem "Please remove default template comments" - end - # FileUtils is included in Formula # encfs modifies a file with this name, so check for some leading characters if line =~ %r{[^'"/]FileUtils\.(\w+)} @@ -891,9 +869,6 @@ class FormulaAuditor end end - # Commented-out depends_on - problem "Commented-out dep #{Regexp.last_match(1)}" if line =~ /#\s*depends_on\s+(.+)\s*$/ - if line =~ /if\s+ARGV\.include\?\s+'--(HEAD|devel)'/ problem "Use \"if build.#{Regexp.last_match(1).downcase}?\" instead" end diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index 4be0c0fe3..e7a23ecae 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -302,6 +302,15 @@ module RuboCop end end + # Yields to a block with comment text as parameter + def audit_comments + @processed_source.comments.each do |comment_node| + @offensive_node = comment_node + @offense_source_range = :expression + yield comment_node.text + end + end + # Returns the begin position of the node's line in source code def line_start_column(node) node.source_range.source_buffer.line_range(node.loc.line).begin_pos @@ -312,6 +321,11 @@ module RuboCop node.source_range.begin_pos end + # Returns the ending position of the node in source code + def end_column(node) + node.source_range.end_pos + end + # Returns the line number of the node def line_number(node) node.loc.line diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 22039869b..748b662c4 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -15,6 +15,49 @@ module RuboCop problem ":tex is deprecated" if depends_on?(:tex) end end + + class ClassInheritance < FormulaCop + def audit_formula(_node, class_node, parent_class_node, _body_node) + begin_pos = start_column(parent_class_node) + end_pos = end_column(class_node) + return unless begin_pos-end_pos != 3 + problem "Use a space in class inheritance: class #{@formula_name} < #{class_name(parent_class_node)}" + end + end + + class Comments < FormulaCop + def audit_formula(_node, _class_node, _parent_class_node, _body_node) + # Commented-out cmake support from default template + audit_comments do |comment| + next unless comment.include?('# system "cmake') + problem "Commented cmake call found" + end + + # Comments from default template + audit_comments do |comment| + [ + "# PLEASE REMOVE", + "# Documentation:", + "# if this fails, try separate make/make install steps", + "# The URL of the archive", + "## Naming --", + "# if your formula requires any X11/XQuartz components", + "# if your formula fails when building in parallel", + "# Remove unrecognized options if warned by configure", + ].each do |template_comment| + next unless comment.include?(template_comment) + problem "Please remove default template comments" + break + end + end + + audit_comments do |comment| + # Commented-out depends_on + next unless comment =~ /#\s*depends_on\s+(.+)\s*$/ + problem "Commented-out dep #{Regexp.last_match(1)}" + end + end + end end end end -- cgit v1.2.3 From b5da76e28d0a01d8e07076f8bba6cd2733597d6c Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 31 Jul 2017 14:30:37 +0530 Subject: audit: Port FileUtils, inreplace audit rules in audit_lines to rubocop --- Library/Homebrew/dev-cmd/audit.rb | 11 ----------- Library/Homebrew/rubocops/extend/formula_cop.rb | 18 ++++++++++++++---- Library/Homebrew/rubocops/lines_cop.rb | 17 +++++++++++++++++ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 323b37170..cd5528cf5 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -809,17 +809,6 @@ class FormulaAuditor end def line_problems(line, _lineno) - # FileUtils is included in Formula - # encfs modifies a file with this name, so check for some leading characters - if line =~ %r{[^'"/]FileUtils\.(\w+)} - problem "Don't need 'FileUtils.' before #{Regexp.last_match(1)}." - end - - # Check for long inreplace block vars - if line =~ /inreplace .* do \|(.{2,})\|/ - problem "\"inreplace do |s|\" is preferred over \"|#{Regexp.last_match(1)}|\"." - end - # Check for string interpolation of single values. if line =~ /(system|inreplace|gsub!|change_make_var!).*[ ,]"#\{([\w.]+)\}"/ problem "Don't need to interpolate \"#{Regexp.last_match(2)}\" with #{Regexp.last_match(1)}" diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index e7a23ecae..f8864538a 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -85,9 +85,13 @@ module RuboCop end # Returns an array of method call nodes matching method_name in every descendant of node - def find_every_method_call_by_name(node, method_name) + # Returns every method call if no method_name is passed + def find_every_method_call_by_name(node, method_name = nil) return if node.nil? - node.each_descendant(:send).select { |method_node| method_name == method_node.method_name } + node.each_descendant(:send).select do |method_node| + method_name.nil? || + method_name == method_node.method_name + end end # Given a method_name and arguments, yields to a block with @@ -107,7 +111,7 @@ module RuboCop def find_instance_method_call(node, instance, method_name) methods = find_every_method_call_by_name(node, method_name) methods.each do |method| - next unless method.receiver.const_name == instance + next unless method.receiver && method.receiver.const_name == instance @offense_source_range = method.source_range @offensive_node = method yield method @@ -188,9 +192,15 @@ module RuboCop end # Returns an array of block nodes of any depth below node in AST + # If a block is given then yields matching block node to the block! def find_all_blocks(node, block_name) return if node.nil? - node.each_descendant(:block).select { |block_node| block_name == block_node.method_name } + blocks = node.each_descendant(:block).select { |block_node| block_name == block_node.method_name } + return blocks unless block_given? + blocks.each do |block_node| + offending_node(block_node) + yield block_node + end end # Returns a method definition node with method_name diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 748b662c4..536f5e2ec 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -58,6 +58,23 @@ module RuboCop end end end + + class Miscellaneous < FormulaCop + def audit_formula(_node, _class_node, _parent_class_node, body_node) + # FileUtils is included in Formula + # encfs modifies a file with this name, so check for some leading characters + find_instance_method_call(body_node, "FileUtils", nil) do |method_node| + problem "Don't need 'FileUtils.' before #{method_node.method_name}" + end + + # Check for long inreplace block vars + find_all_blocks(body_node, :inreplace) do |node| + block_arg = node.arguments.children.first + next unless block_arg.source.size>1 + problem "\"inreplace do |s|\" is preferred over \"|#{block_arg.source}|\"." + end + end + end end end end -- cgit v1.2.3 From 3edae73cd90cc9e6233718bfb48c5cc075aa0f36 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Wed, 2 Aug 2017 23:49:51 +0530 Subject: audit: Add tests for audit rules ported from line_problems method to rubocops --- Library/Homebrew/test/dev-cmd/audit_spec.rb | 22 ---- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 151 +++++++++++++++++++++++ 2 files changed, 151 insertions(+), 22 deletions(-) diff --git a/Library/Homebrew/test/dev-cmd/audit_spec.rb b/Library/Homebrew/test/dev-cmd/audit_spec.rb index f2d8a8e7c..037865fdf 100644 --- a/Library/Homebrew/test/dev-cmd/audit_spec.rb +++ b/Library/Homebrew/test/dev-cmd/audit_spec.rb @@ -263,28 +263,6 @@ describe FormulaAuditor do expect(fa.problems.shift) .to eq('Use pkgshare instead of (share/"foolibc++")') end - - specify "no space in class inheritance" do - fa = formula_auditor "foo", <<-EOS.undent - class Foo do |s|\" is preferred over \"|longvar|\".", + severity: :convention, + line: 4, + column: 2, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + end +end -- cgit v1.2.3 From b8f811cca669e9e20fb6e8a8ac8d44f0b8761f5f Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Fri, 4 Aug 2017 01:18:00 +0530 Subject: audit: Port rules from line_problems to rubocop part 3 --- Library/Homebrew/dev-cmd/audit.rb | 47 -------------------- Library/Homebrew/rubocops/extend/formula_cop.rb | 22 ++++++---- Library/Homebrew/rubocops/lines_cop.rb | 57 +++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 55 deletions(-) diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index cd5528cf5..80b9824aa 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -866,10 +866,6 @@ class FormulaAuditor 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 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)}\"" @@ -883,14 +879,6 @@ class FormulaAuditor problem "Use ENV instead of invoking '#{Regexp.last_match(1)}' to modify the environment" 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['"]/ problem "Use 'build.head?' instead of inspecting 'version'" end @@ -931,12 +919,6 @@ class FormulaAuditor problem "Use build instead of ARGV to check options" 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") problem "Use MacOS.version instead of MACOS_VERSION" end @@ -950,11 +932,6 @@ class FormulaAuditor problem "\"#{$&}\" is deprecated, use a comparison to MacOS.version instead" 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$/ problem "`depends_on` can take requirement classes instead of instances" end @@ -993,30 +970,6 @@ class FormulaAuditor problem "Use `assert_match` instead of `assert ...include?`" 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 problem "`#{Regexp.last_match(1)}` in formulae is deprecated" if line =~ /(env :(std|userpaths))/ diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index f8864538a..991551585 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -3,12 +3,13 @@ require "parser/current" module RuboCop module Cop class FormulaCop < Cop + attr_accessor :file_path @registry = Cop.registry # This method is called by RuboCop and is the main entry point def on_class(node) - file_path = processed_source.buffer.name - return unless file_path_allowed?(file_path) + @file_path = processed_source.buffer.name + return unless file_path_allowed? return unless formula_class?(node) return unless respond_to?(:audit_formula) class_node, parent_class_node, @body = *node @@ -99,8 +100,7 @@ module RuboCop def find_method_with_args(node, method_name, *args) methods = find_every_method_call_by_name(node, method_name) methods.each do |method| - next unless parameters_passed?(method, *args) - yield method + yield method if parameters_passed?(method, *args) end end @@ -111,7 +111,7 @@ module RuboCop def find_instance_method_call(node, instance, method_name) methods = find_every_method_call_by_name(node, method_name) 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 @offensive_node = method yield method @@ -400,6 +400,12 @@ module RuboCop method_name(component_node) if component_node.def_type? 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) add_offense(@offensive_node, @offense_source_range, msg) end @@ -411,11 +417,11 @@ module RuboCop class_node && string_content(class_node) == "Formula" end - def file_path_allowed?(file_path) + def file_path_allowed? paths_to_exclude = [%r{/Library/Homebrew/compat/}, %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 - file_path !~ Regexp.union(paths_to_exclude) + 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) end end end diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 536f5e2ec..7bf9e6056 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -73,7 +73,64 @@ module RuboCop next unless block_arg.source.size>1 problem "\"inreplace do |s|\" is preferred over \"|#{block_arg.source}|\"." 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 + + # 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 -- cgit v1.2.3 From d9c81901c3a7f6ed112a99e9067d78fb9a2c3293 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Sat, 5 Aug 2017 14:58:09 +0530 Subject: audit: Add tests for rubocop methods in line_cop.rb --- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 269 +++++++++++++++++++++++ 1 file changed, 269 insertions(+) diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 122f8a364..293a415a5 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -200,5 +200,274 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with invalid rebuild" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + bottle do + rebuild 0 + sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra + end + end + EOS + + expected_offenses = [{ message: "'rebuild 0' should be removed", + severity: :convention, + line: 5, + column: 4, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with OS.linux? check" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + bottle do + if OS.linux? + nil + end + sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra + end + end + EOS + + expected_offenses = [{ message: "Don't use OS.linux?; Homebrew/core only supports macOS", + severity: :convention, + line: 5, + column: 7, + source: source }] + + inspect_source(cop, source, "/homebrew-core/") + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with fails_with :llvm" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + bottle do + sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra + end + fails_with :llvm do + build 2335 + cause "foo" + end + end + EOS + + expected_offenses = [{ message: "'fails_with :llvm' is now a no-op so should be removed", + severity: :convention, + line: 7, + column: 2, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with def test" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + + def test + assert_equals "1", "1" + end + end + EOS + + expected_offenses = [{ message: "Use new-style test definitions (test do)", + severity: :convention, + line: 5, + column: 2, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with def options" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + + def options + [["--bar", "desc"]] + end + end + EOS + + expected_offenses = [{ message: "Use new-style option definitions", + severity: :convention, + line: 5, + column: 2, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with deprecated skip_clean call" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + skip_clean :all + end + EOS + + expected_offenses = [{ message: "`skip_clean :all` is deprecated; brew no longer strips symbols\n" \ + "\tPass explicit paths to prevent Homebrew from removing empty folders.", + severity: :convention, + line: 4, + column: 2, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with build.universal?" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + if build.universal? + "foo" + end + end + EOS + + expected_offenses = [{ message: "macOS has been 64-bit only so build.universal? is deprecated.", + severity: :convention, + line: 4, + column: 5, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with ENV.universal_binary" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + if build? + ENV.universal_binary + end + end + EOS + + expected_offenses = [{ message: "macOS has been 64-bit only since 10.6 so ENV.universal_binary is deprecated.", + severity: :convention, + line: 5, + column: 5, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with ENV.universal_binary" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + if build? + ENV.x11 + end + end + EOS + + expected_offenses = [{ message: 'Use "depends_on :x11" instead of "ENV.x11"', + severity: :convention, + line: 5, + column: 5, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with ruby-macho alternatives" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + system "install_name_tool", "-id" + end + EOS + + expected_offenses = [{ message: 'Use ruby-macho instead of calling "install_name_tool"', + severity: :convention, + line: 4, + column: 10, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with npm install without language::Node args" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + system "npm", "install" + end + EOS + + expected_offenses = [{ message: "Use Language::Node for npm install args", + severity: :convention, + line: 4, + column: 17, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end end -- cgit v1.2.3 From a92e1eda27d732e0de75592d8fb52e93bb5e0d33 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 7 Aug 2017 14:08:22 +0530 Subject: audit: Port rules from line_problems to rubocop part 4(WIP) --- Library/Homebrew/dev-cmd/audit.rb | 23 ------------------- Library/Homebrew/rubocops/lines_cop.rb | 41 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 80b9824aa..db99656cb 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -927,15 +927,6 @@ class FormulaAuditor problem "Use MacOS.full_version instead of MACOS_FULL_VERSION" end - cats = %w[leopard snow_leopard lion mountain_lion].join("|") - if line =~ /MacOS\.(?:#{cats})\?/ - problem "\"#{$&}\" is deprecated, use a comparison to MacOS.version instead" - end - - if line =~ /depends_on [A-Z][\w:]+\.new$/ - problem "`depends_on` can take requirement classes instead of instances" - end - if line =~ /^def (\w+).*$/ problem "Define method #{Regexp.last_match(1).inspect} in the class body, not at the top-level" end @@ -956,20 +947,6 @@ class FormulaAuditor conditional_dep_problems(Regexp.last_match(1), Regexp.last_match(2), $&) end - if line =~ /(Dir\[("[^\*{},]+")\])/ - problem "#{Regexp.last_match(1)} is unnecessary; just use #{Regexp.last_match(2)}" - end - - if line =~ /system (["'](#{FILEUTILS_METHODS})["' ])/o - system = Regexp.last_match(1) - method = Regexp.last_match(2) - problem "Use the `#{method}` Ruby method instead of `system #{system}`" - end - - if line =~ /assert [^!]+\.include?/ - problem "Use `assert_match` instead of `assert ...include?`" - end - return unless @strict problem "`#{Regexp.last_match(1)}` in formulae is deprecated" if line =~ /(env :(std|userpaths))/ diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 7bf9e6056..338a3256a 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -1,3 +1,4 @@ +require 'FileUtils' require_relative "./extend/formula_cop" module RuboCop @@ -123,6 +124,37 @@ module RuboCop find_instance_method_call(body_node, "ENV", :x11) do problem 'Use "depends_on :x11" instead of "ENV.x11"' end + + find_every_method_call_by_name(body_node, :assert).each do |m| + if method_called?(m, :include?) && !method_called?(m, :!) + problem "Use `assert_match` instead of `assert ...include?`" + end + end + + find_every_method_call_by_name(body_node, :depends_on).each do |m| + next unless method_called?(m, :new) + problem "`depends_on` can take requirement classes instead of instances" + end + + os = [:leopard?, :snow_leopard?, :lion?, :mountain_lion?] + os.each do |version| + find_instance_method_call(body_node, :MacOS, version) do |m| + problem "\"#{m.source}\" is deprecated, use a comparison to MacOS.version instead" + end + end + + dirPattern(body_node) do |m| + next unless m =~ /\[("[^\*{},]+")\]/ + problem "Dir(#{Regexp.last_match(1)}) is unnecessary; just use #{Regexp.last_match(1)}" + end + + fileUtils_methods= FileUtils.singleton_methods(false).map { |m| Regexp.escape(m) }.join "|" + find_method_with_args(body_node, :system, /fileUtils_methods/) do |m| + method = string_content(@offensive_node) + problem "Use the `#{method}` Ruby method instead of `#{m.source}`" + end + + end # This is Pattern Matching method for AST @@ -131,7 +163,16 @@ module RuboCop def_node_search :languageNode?, <<-PATTERN (const (const nil :Language) :Node) PATTERN + + def_node_search :dirPattern, <<-PATTERN + (send (const nil :Dir) :[] (str $_)) + PATTERN end end end end + +# Strict rules ported early +# find_method_with_args(@processed_source.ast, :require, "formula") do |m| +# problem "#{m.source} is now unnecessary" +# end -- cgit v1.2.3 From 4295a4ca788644475f702ddbae3bc592624f7ce4 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Thu, 10 Aug 2017 19:57:53 +0530 Subject: audit: Port rules from line_problems to rubocop part 4(WIP-2) --- Library/.rubocop.yml | 4 + Library/Homebrew/dev-cmd/audit.rb | 87 ----------------- Library/Homebrew/rubocops/extend/formula_cop.rb | 25 ++++- Library/Homebrew/rubocops/lines_cop.rb | 125 ++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 90 deletions(-) diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml index cb065a1a4..a2e3cc9c9 100644 --- a/Library/.rubocop.yml +++ b/Library/.rubocop.yml @@ -118,6 +118,10 @@ Style/Documentation: Style/Encoding: Enabled: true +# use spaces for indentation; detect tabs +Style/Tab: + Enabled: true + # dashes in filenames are typical Style/FileName: Regex: !ruby/regexp /^[\w\@\-\+\.]+(\.rb)?$/ diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index db99656cb..4195cdf2b 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -849,23 +849,8 @@ class FormulaAuditor problem "#{Regexp.last_match(2)} modules should be vendored rather than use deprecated `depends_on \"#{Regexp.last_match(1)}\" => :#{Regexp.last_match(2)}#{Regexp.last_match(3)}`" end - if line =~ /depends_on\s+['"](.+)['"]\s+=>\s+(.*)/ - dep = Regexp.last_match(1) - Regexp.last_match(2).split(" ").map do |o| - break if ["if", "unless"].include?(o) - next unless o =~ /^\[?['"](.*)['"]/ - problem "Dependency #{dep} should not use option #{Regexp.last_match(1)}" - end - end - - if line =~ /if\s+ARGV\.include\?\s+'--(HEAD|devel)'/ - problem "Use \"if build.#{Regexp.last_match(1).downcase}?\" instead" - end - problem "Use separate make calls" if line.include?("make && make") - problem "Use spaces instead of tabs for indentation" if line =~ /^[ ]*\t/ - # Avoid hard-coding compilers 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)}\"" @@ -879,74 +864,14 @@ class FormulaAuditor problem "Use ENV instead of invoking '#{Regexp.last_match(1)}' to modify the environment" end - if line =~ /version == ['"]HEAD['"]/ - problem "Use 'build.head?' instead of inspecting 'version'" - end - - if line =~ /build\.include\?[\s\(]+['"]\-\-(.*)['"]/ - problem "Reference '#{Regexp.last_match(1)}' without dashes" - end - - if line =~ /build\.include\?[\s\(]+['"]with(out)?-(.*)['"]/ - problem "Use build.with#{Regexp.last_match(1)}? \"#{Regexp.last_match(2)}\" instead of build.include? 'with#{Regexp.last_match(1)}-#{Regexp.last_match(2)}'" - end - - if line =~ /build\.with\?[\s\(]+['"]-?-?with-(.*)['"]/ - problem "Don't duplicate 'with': Use `build.with? \"#{Regexp.last_match(1)}\"` to check for \"--with-#{Regexp.last_match(1)}\"" - end - - if line =~ /build\.without\?[\s\(]+['"]-?-?without-(.*)['"]/ - problem "Don't duplicate 'without': Use `build.without? \"#{Regexp.last_match(1)}\"` to check for \"--without-#{Regexp.last_match(1)}\"" - end - - if line =~ /unless build\.with\?(.*)/ - problem "Use if build.without?#{Regexp.last_match(1)} instead of unless build.with?#{Regexp.last_match(1)}" - end - - if line =~ /unless build\.without\?(.*)/ - problem "Use if build.with?#{Regexp.last_match(1)} instead of unless build.without?#{Regexp.last_match(1)}" - end - - if line =~ /(not\s|!)\s*build\.with?\?/ - problem "Don't negate 'build.with?': use 'build.without?'" - end - - if line =~ /(not\s|!)\s*build\.without?\?/ - problem "Don't negate 'build.without?': use 'build.with?'" - end - if line =~ /ARGV\.(?!(debug\?|verbose\?|value[\(\s]))/ problem "Use build instead of ARGV to check options" end - if line.include?("MACOS_VERSION") - problem "Use MacOS.version instead of MACOS_VERSION" - end - - if line.include?("MACOS_FULL_VERSION") - problem "Use MacOS.full_version instead of MACOS_FULL_VERSION" - end - - if line =~ /^def (\w+).*$/ - problem "Define method #{Regexp.last_match(1).inspect} in the class body, not at the top-level" - end - - if line.include?("ENV.fortran") && !formula.requirements.map(&:class).include?(FortranRequirement) - problem "Use `depends_on :fortran` instead of `ENV.fortran`" - end - if line =~ /JAVA_HOME/i && !formula.requirements.map(&:class).include?(JavaRequirement) problem "Use `depends_on :java` to set JAVA_HOME" end - if line =~ /depends_on :(.+) (if.+|unless.+)$/ - conditional_dep_problems(Regexp.last_match(1).to_sym, Regexp.last_match(2), $&) - end - - if line =~ /depends_on ['"](.+)['"] (if.+|unless.+)$/ - conditional_dep_problems(Regexp.last_match(1), Regexp.last_match(2), $&) - end - return unless @strict problem "`#{Regexp.last_match(1)}` in formulae is deprecated" if line =~ /(env :(std|userpaths))/ @@ -993,18 +918,6 @@ class FormulaAuditor EOS end - def conditional_dep_problems(dep, condition, line) - quoted_dep = quote_dep(dep) - dep = Regexp.escape(dep.to_s) - - case condition - when /if build\.include\? ['"]with-#{dep}['"]$/, /if build\.with\? ['"]#{dep}['"]$/ - problem %Q(Replace #{line.inspect} with "depends_on #{quoted_dep} => :optional") - when /unless build\.include\? ['"]without-#{dep}['"]$/, /unless build\.without\? ['"]#{dep}['"]$/ - problem %Q(Replace #{line.inspect} with "depends_on #{quoted_dep} => :recommended") - end - end - def quote_dep(dep) dep.is_a?(Symbol) ? dep.inspect : "'#{dep}'" end diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index 991551585..08c9e6eb8 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -55,6 +55,7 @@ module RuboCop # Returns all string nodes among the descendants of given node def find_strings(node) return [] if node.nil? + return node if node.str_type? node.each_descendant(:str) end @@ -100,7 +101,9 @@ module RuboCop def find_method_with_args(node, method_name, *args) methods = find_every_method_call_by_name(node, method_name) methods.each do |method| - yield method if parameters_passed?(method, *args) + next unless parameters_passed?(method, *args) + return true unless block_given? + yield method end end @@ -114,6 +117,7 @@ module RuboCop next unless method.receiver && (method.receiver.const_name == instance || method.receiver.method_name == instance) @offense_source_range = method.source_range @offensive_node = method + return true unless block_given? yield method end end @@ -165,6 +169,20 @@ module RuboCop type_match && name_match end + # Find CONSTANTs in the source + # if block given, yield matching nodes + def find_const(node, const_name) + return if node.nil? + node.each_child_node(:const) do |const_node| + next if 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 + nil + end + # To compare node with appropriate Ruby variable def node_equals?(node, var) node == Parser::CurrentRuby.parse(var.inspect) @@ -204,11 +222,12 @@ module RuboCop end # Returns a method definition node with method_name - def find_method_def(node, method_name) + # Returns first method def if method_name is nil + def find_method_def(node, method_name = nil) return if node.nil? node.each_child_node(:def) do |def_node| def_method_name = method_name(def_node) - next unless method_name == def_method_name + next unless method_name == def_method_name || method_name.nil? @offensive_node = def_node @offense_source_range = def_node.source_range return def_node diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 338a3256a..4c357f6ab 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -88,6 +88,59 @@ module RuboCop end end + find_every_method_call_by_name(body_node, :depends_on).each do |m| + next unless modifier?(m) + dep, option = hash_dep(m) + next if dep.nil? || option.nil? + problem "Dependency #{string_content(dep)} should not use option #{string_content(option)}" + end + + find_instance_method_call(body_node, :version, :==) do |m| + next unless parameters_passed?(m, "HEAD") + problem "Use 'build.head?' instead of inspecting 'version'" + end + + find_instance_method_call(body_node, :ENV, :fortran) do + next if depends_on?(:fortran) + problem "Use `depends_on :fortran` instead of `ENV.fortran`" + end + + find_instance_method_call(body_node, :ARGV, :include?) do |m| + param = parameters(m).first + next unless match = regex_match_group(param, %r{--(HEAD|devel)}) + problem "Use \"if build.#{match[1].downcase}?\" instead" + end + + find_const(body_node, :MACOS_VERSION) do + problem "Use MacOS.version instead of MACOS_VERSION" + end + + find_const(body_node, :MACOS_FULL_VERSION) do + problem "Use MacOS.full_version instead of MACOS_FULL_VERSION" + end + + dependency(body_node) do |m| + # handle symbols and shit: WIP + next unless modifier?(m.parent) + dep = parameters(m).first + condition = m.parent.condition + if (condition.if? && condition.method_name == :include? && parameters_passed(condition, /with-#{string_content(dep)}$/))|| + (condition.if? && condition.method_name == :with? && parameters_passed?(condition, /#{string_content(dep)}$/)) + problem "Replace #{m.parent.source} with #{dep.source} => :optional" + end + if (condition.unless? && condition.method_name == :include? && parameters_passed?(condition, /without-#{string_content(dep)}$/))|| + (condition.unless? && condition.method_name == :without? && parameters_passed?(condition, /#{string_content(dep)}$/)) + problem "Replace #{m.parent.source} with #{dep.source} => :recommended" + end + end + + find_every_method_call_by_name(body_node, :depends_on).each do |m| + next unless modifier?(m.parent) + dep = parameters(m).first + next if dep.hash_type? + condition = m.parent.node_parts + 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 @@ -154,9 +207,81 @@ module RuboCop problem "Use the `#{method}` Ruby method instead of `#{m.source}`" end + if find_method_def(@processed_source.ast) + problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level" + end + + find_instance_method_call(body_node, :build, :without?) do |m| + next unless unless_modifier?(m.parent) + correct = m.source.gsub("out?", "?").gsub("unless", "if") + problem "Use #{correct} instead of unless #{m.source}" + end + + find_instance_method_call(body_node, :build, :with?) do |m| + next unless unless_modifier?(m.parent) + correct = m.source.gsub("?", "out?").gsub("unless", "if") + problem "Use #{correct} instead of unless #{m.source}" + end + + find_instance_method_call(body_node, :build, :with?) do |m| + next unless negation?(m) + problem "Don't negate 'build.with?': use 'build.without?'" + end + + find_instance_method_call(body_node, :build, :without?) do |m| + next unless negation?(m) + problem "Don't negate 'build.without?': use 'build.with?'" + end + + find_instance_method_call(body_node, :build, :without?) do |m| + arg = parameters(m).first + next unless match = regex_match_group(arg, %r{-?-?without-(.*)}) + problem "Don't duplicate 'without': Use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\"" + end + + find_instance_method_call(body_node, :build, :with?) do |m| + arg = parameters(m).first + next unless match = regex_match_group(arg, %r{-?-?with-(.*)}) + problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\"" + end + find_instance_method_call(body_node, :build, :include?) do |m| + arg = parameters(m).first + next unless match = regex_match_group(arg, %r{with(out)?-(.*)}) + problem "Use build.with#{match[1]}? \"#{match[2]}\" instead of build.include? 'with#{match[1]}-#{match[2]}'" + end + + find_instance_method_call(body_node, :build, :include?) do |m| + arg = parameters(m).first + next unless match = regex_match_group(arg, %r{\-\-(.*)}) + problem "Reference '#{match[1]}' without dashes" + end + + end + + def unless_modifier?(node) + node.modifier_form? && node.unless? end + def modifier?(node) + node.modifier_form? + end + + def_node_search :condition, <<-EOS.undent + (send (send nil :build) $_ $({str sym} _)) + EOS + + def_node_search :dependency, <<-EOS.undent + (send nil :depends_on ({str sym} _)) + EOS + + # Match depends_on with hash as argument + def_node_search :hash_dep, <<-EOS.undent + {$(hash (pair $(str _) $(str _))) + $(hash (pair $(str _) (array $(str _) ...)))} + EOS + + def_node_matcher :negation?, '(send ... :!)' # 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 -- cgit v1.2.3 From 087c1ca8d660f5604f9e9f31e3c4c18cb98d91bd Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Sat, 12 Aug 2017 20:50:43 +0530 Subject: audit: Port rules from line_problems to rubocop part 4(WIP-3) --- Library/Homebrew/dev-cmd/audit.rb | 42 --------------------- Library/Homebrew/rubocops/lines_cop.rb | 68 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 42 deletions(-) diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 4195cdf2b..f8236e6a6 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -824,50 +824,8 @@ class FormulaAuditor problem "\"(#{Regexp.last_match(1)}...#{Regexp.last_match(2)})\" should be \"(#{Regexp.last_match(3).downcase}+...)\"" end - if line =~ /((man)\s*\+\s*(['"])(man[1-8])(['"]))/ - problem "\"#{Regexp.last_match(1)}\" should be \"#{Regexp.last_match(4)}\"" - end - - # Prefer formula path shortcuts in strings - if line =~ %r[(\#\{prefix\}/(bin|include|libexec|lib|sbin|share|Frameworks))] - problem "\"#{Regexp.last_match(1)}\" should be \"\#{#{Regexp.last_match(2).downcase}}\"" - end - - if line =~ %r[((\#\{prefix\}/share/man/|\#\{man\}/)(man[1-8]))] - problem "\"#{Regexp.last_match(1)}\" should be \"\#{#{Regexp.last_match(3)}}\"" - end - - if line =~ %r[((\#\{share\}/(man)))[/'"]] - problem "\"#{Regexp.last_match(1)}\" should be \"\#{#{Regexp.last_match(3)}}\"" - end - - if line =~ %r[(\#\{prefix\}/share/(info|man))] - problem "\"#{Regexp.last_match(1)}\" should be \"\#{#{Regexp.last_match(2)}}\"" - end - - if line =~ /depends_on\s+['"](.+)['"]\s+=>\s+:(lua|perl|python|ruby)(\d*)/ - problem "#{Regexp.last_match(2)} modules should be vendored rather than use deprecated `depends_on \"#{Regexp.last_match(1)}\" => :#{Regexp.last_match(2)}#{Regexp.last_match(3)}`" - end - problem "Use separate make calls" if line.include?("make && make") - # Avoid hard-coding compilers - 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)}\"" - end - - if line =~ %r{(system|ENV\[.+\]\s?=)\s?['"](/usr/bin/)?((g|llvm-g|clang)\+\+)['" ]} - problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{Regexp.last_match(3)}\"" - end - - if line =~ /system\s+['"](env|export)(\s+|['"])/ - problem "Use ENV instead of invoking '#{Regexp.last_match(1)}' to modify the environment" - end - - if line =~ /ARGV\.(?!(debug\?|verbose\?|value[\(\s]))/ - problem "Use build instead of ARGV to check options" - end - if line =~ /JAVA_HOME/i && !formula.requirements.map(&:class).include?(JavaRequirement) problem "Use `depends_on :java` to set JAVA_HOME" end diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 4c357f6ab..32d05fb22 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -88,6 +88,66 @@ module RuboCop end end + [:debug?, :verbose?, :value].each do |m| + find_instance_method_call(body_node, :ARGV, m) do + problem "Use build instead of ARGV to check options" + end + end + + find_instance_method_call(body_node, :man, :+) do |m| + next unless match = regex_match_group(parameters(m).first, %r{man[1-8]}) + problem "\"#{m.source}\" should be \"#{match[1]}\"" + end + + # Avoid hard-coding compilers + find_every_method_call_by_name(body_node, :system).each do |m| + param = parameters(m).first + if match = regex_match_group(param, %r{(/usr/bin/)?(gcc|llvm-gcc|clang)\s?}) + problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[3]}\"" + elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?}) + problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[3]}\"" + end + end + + find_instance_method_call(body_node, :ENV, :[]=) do |m| + param = parameters(m)[1] + if match = regex_match_group(param, %r{(/usr/bin/)?(gcc|llvm-gcc|clang)\s?}) + problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[3]}\"" + elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?}) + problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[3]}\"" + end + end + + # Prefer formula path shortcuts in strings + formula_path_strings(body_node, :prefix) do |p| + next unless match = regex_match_group(p, %r{(/(man))[/'"]}) + problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[3]}}\"" + end + + formula_path_strings(body_node, :share) do |p| + if match = regex_match_group(p, %r{/(bin|include|libexec|lib|sbin|share|Frameworks)}i) + problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[1].downcase}}\"" + end + if match = regex_match_group(p, %r{((/share/man/|\#\{man\}/)(man[1-8]))}) + problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[3]}}\"" + end + if match = regex_match_group(p, %r{(/share/(info|man))}) + problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2]}}\"" + end + end + + find_every_method_call_by_name(body_node, :depends_on) do |m| + key, value = destructure_hash(paramters(m).first) + next unless key.str_type? + next unless match = regex_match_group(value, %r{(lua|perl|python|ruby)(\d*)}) + problem "#{match[1]} modules should be vendored rather than use deprecated #{m.source}`" + end + + find_every_method_call_by_name(body_node, :system).each do |m| + next unless match = regex_match_group(parameters(m).first, %r{(env|export)(\s+)?}) + problem "Use ENV instead of invoking '#{match[1]}' to modify the environment" + end + find_every_method_call_by_name(body_node, :depends_on).each do |m| next unless modifier?(m) dep, option = hash_dep(m) @@ -281,6 +341,14 @@ module RuboCop $(hash (pair $(str _) (array $(str _) ...)))} EOS + def_node_search :destructure_hash, <<-EOS.undent + (hash (pair $_ $_)) + EOS + + def_node_matcher :formula_path_strings, <<-EOS.undent + (dstr (begin (send nil %1)) $(str _ )) + EOS + def_node_matcher :negation?, '(send ... :!)' # This is Pattern Matching method for AST # Takes the AST node as argument and yields matching node if block given -- cgit v1.2.3 From 686fc514cfd7ddd18484c37b177dc2b8298d129b Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Sat, 12 Aug 2017 23:28:08 +0530 Subject: Add tests for assert match and depends_on instance audit rules --- Library/Homebrew/rubocops/lines_cop.rb | 360 +++++++++++------------ Library/Homebrew/test/rubocops/lines_cop_spec.rb | 68 +++++ 2 files changed, 248 insertions(+), 180 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 32d05fb22..8d4b99825 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -88,118 +88,118 @@ module RuboCop end end - [:debug?, :verbose?, :value].each do |m| - find_instance_method_call(body_node, :ARGV, m) do - problem "Use build instead of ARGV to check options" - end - end - - find_instance_method_call(body_node, :man, :+) do |m| - next unless match = regex_match_group(parameters(m).first, %r{man[1-8]}) - problem "\"#{m.source}\" should be \"#{match[1]}\"" - end - - # Avoid hard-coding compilers - find_every_method_call_by_name(body_node, :system).each do |m| - param = parameters(m).first - if match = regex_match_group(param, %r{(/usr/bin/)?(gcc|llvm-gcc|clang)\s?}) - problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[3]}\"" - elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?}) - problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[3]}\"" - end - end - - find_instance_method_call(body_node, :ENV, :[]=) do |m| - param = parameters(m)[1] - if match = regex_match_group(param, %r{(/usr/bin/)?(gcc|llvm-gcc|clang)\s?}) - problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[3]}\"" - elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?}) - problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[3]}\"" - end - end - - # Prefer formula path shortcuts in strings - formula_path_strings(body_node, :prefix) do |p| - next unless match = regex_match_group(p, %r{(/(man))[/'"]}) - problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[3]}}\"" - end - - formula_path_strings(body_node, :share) do |p| - if match = regex_match_group(p, %r{/(bin|include|libexec|lib|sbin|share|Frameworks)}i) - problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[1].downcase}}\"" - end - if match = regex_match_group(p, %r{((/share/man/|\#\{man\}/)(man[1-8]))}) - problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[3]}}\"" - end - if match = regex_match_group(p, %r{(/share/(info|man))}) - problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2]}}\"" - end - end - - find_every_method_call_by_name(body_node, :depends_on) do |m| - key, value = destructure_hash(paramters(m).first) - next unless key.str_type? - next unless match = regex_match_group(value, %r{(lua|perl|python|ruby)(\d*)}) - problem "#{match[1]} modules should be vendored rather than use deprecated #{m.source}`" - end - - find_every_method_call_by_name(body_node, :system).each do |m| - next unless match = regex_match_group(parameters(m).first, %r{(env|export)(\s+)?}) - problem "Use ENV instead of invoking '#{match[1]}' to modify the environment" - end - - find_every_method_call_by_name(body_node, :depends_on).each do |m| - next unless modifier?(m) - dep, option = hash_dep(m) - next if dep.nil? || option.nil? - problem "Dependency #{string_content(dep)} should not use option #{string_content(option)}" - end - - find_instance_method_call(body_node, :version, :==) do |m| - next unless parameters_passed?(m, "HEAD") - problem "Use 'build.head?' instead of inspecting 'version'" - end - - find_instance_method_call(body_node, :ENV, :fortran) do - next if depends_on?(:fortran) - problem "Use `depends_on :fortran` instead of `ENV.fortran`" - end - - find_instance_method_call(body_node, :ARGV, :include?) do |m| - param = parameters(m).first - next unless match = regex_match_group(param, %r{--(HEAD|devel)}) - problem "Use \"if build.#{match[1].downcase}?\" instead" - end - - find_const(body_node, :MACOS_VERSION) do - problem "Use MacOS.version instead of MACOS_VERSION" - end - - find_const(body_node, :MACOS_FULL_VERSION) do - problem "Use MacOS.full_version instead of MACOS_FULL_VERSION" - end - - dependency(body_node) do |m| - # handle symbols and shit: WIP - next unless modifier?(m.parent) - dep = parameters(m).first - condition = m.parent.condition - if (condition.if? && condition.method_name == :include? && parameters_passed(condition, /with-#{string_content(dep)}$/))|| - (condition.if? && condition.method_name == :with? && parameters_passed?(condition, /#{string_content(dep)}$/)) - problem "Replace #{m.parent.source} with #{dep.source} => :optional" - end - if (condition.unless? && condition.method_name == :include? && parameters_passed?(condition, /without-#{string_content(dep)}$/))|| - (condition.unless? && condition.method_name == :without? && parameters_passed?(condition, /#{string_content(dep)}$/)) - problem "Replace #{m.parent.source} with #{dep.source} => :recommended" - end - end - - find_every_method_call_by_name(body_node, :depends_on).each do |m| - next unless modifier?(m.parent) - dep = parameters(m).first - next if dep.hash_type? - condition = m.parent.node_parts - end + # [:debug?, :verbose?, :value].each do |m| + # find_instance_method_call(body_node, :ARGV, m) do + # problem "Use build instead of ARGV to check options" + # end + # end + # + # find_instance_method_call(body_node, :man, :+) do |m| + # next unless match = regex_match_group(parameters(m).first, %r{man[1-8]}) + # problem "\"#{m.source}\" should be \"#{match[1]}\"" + # end + # + # # Avoid hard-coding compilers + # find_every_method_call_by_name(body_node, :system).each do |m| + # param = parameters(m).first + # if match = regex_match_group(param, %r{(/usr/bin/)?(gcc|llvm-gcc|clang)\s?}) + # problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[3]}\"" + # elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?}) + # problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[3]}\"" + # end + # end + # + # find_instance_method_call(body_node, :ENV, :[]=) do |m| + # param = parameters(m)[1] + # if match = regex_match_group(param, %r{(/usr/bin/)?(gcc|llvm-gcc|clang)\s?}) + # problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[3]}\"" + # elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?}) + # problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[3]}\"" + # end + # end + # + # # Prefer formula path shortcuts in strings + # formula_path_strings(body_node, :prefix) do |p| + # next unless match = regex_match_group(p, %r{(/(man))[/'"]}) + # problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[3]}}\"" + # end + # + # formula_path_strings(body_node, :share) do |p| + # if match = regex_match_group(p, %r{/(bin|include|libexec|lib|sbin|share|Frameworks)}i) + # problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[1].downcase}}\"" + # end + # if match = regex_match_group(p, %r{((/share/man/|\#\{man\}/)(man[1-8]))}) + # problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[3]}}\"" + # end + # if match = regex_match_group(p, %r{(/share/(info|man))}) + # problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2]}}\"" + # end + # end + # + # find_every_method_call_by_name(body_node, :depends_on) do |m| + # key, value = destructure_hash(paramters(m).first) + # next unless key.str_type? + # next unless match = regex_match_group(value, %r{(lua|perl|python|ruby)(\d*)}) + # problem "#{match[1]} modules should be vendored rather than use deprecated #{m.source}`" + # end + # + # find_every_method_call_by_name(body_node, :system).each do |m| + # next unless match = regex_match_group(parameters(m).first, %r{(env|export)(\s+)?}) + # problem "Use ENV instead of invoking '#{match[1]}' to modify the environment" + # end + # + # find_every_method_call_by_name(body_node, :depends_on).each do |m| + # next unless modifier?(m) + # dep, option = hash_dep(m) + # next if dep.nil? || option.nil? + # problem "Dependency #{string_content(dep)} should not use option #{string_content(option)}" + # end + # + # find_instance_method_call(body_node, :version, :==) do |m| + # next unless parameters_passed?(m, "HEAD") + # problem "Use 'build.head?' instead of inspecting 'version'" + # end + # + # find_instance_method_call(body_node, :ENV, :fortran) do + # next if depends_on?(:fortran) + # problem "Use `depends_on :fortran` instead of `ENV.fortran`" + # end + # + # find_instance_method_call(body_node, :ARGV, :include?) do |m| + # param = parameters(m).first + # next unless match = regex_match_group(param, %r{--(HEAD|devel)}) + # problem "Use \"if build.#{match[1].downcase}?\" instead" + # end + # + # find_const(body_node, :MACOS_VERSION) do + # problem "Use MacOS.version instead of MACOS_VERSION" + # end + # + # find_const(body_node, :MACOS_FULL_VERSION) do + # problem "Use MacOS.full_version instead of MACOS_FULL_VERSION" + # end + # + # dependency(body_node) do |m| + # # handle symbols and shit: WIP + # next unless modifier?(m.parent) + # dep = parameters(m).first + # condition = m.parent.condition + # if (condition.if? && condition.method_name == :include? && parameters_passed(condition, /with-#{string_content(dep)}$/))|| + # (condition.if? && condition.method_name == :with? && parameters_passed?(condition, /#{string_content(dep)}$/)) + # problem "Replace #{m.parent.source} with #{dep.source} => :optional" + # end + # if (condition.unless? && condition.method_name == :include? && parameters_passed?(condition, /without-#{string_content(dep)}$/))|| + # (condition.unless? && condition.method_name == :without? && parameters_passed?(condition, /#{string_content(dep)}$/)) + # problem "Replace #{m.parent.source} with #{dep.source} => :recommended" + # end + # end + # + # find_every_method_call_by_name(body_node, :depends_on).each do |m| + # next unless modifier?(m.parent) + # dep = parameters(m).first + # next if dep.hash_type? + # condition = m.parent.node_parts + # end find_method_with_args(body_node, :fails_with, :llvm) do problem "'fails_with :llvm' is now a no-op so should be removed" @@ -248,74 +248,74 @@ module RuboCop next unless method_called?(m, :new) problem "`depends_on` can take requirement classes instead of instances" end - - os = [:leopard?, :snow_leopard?, :lion?, :mountain_lion?] - os.each do |version| - find_instance_method_call(body_node, :MacOS, version) do |m| - problem "\"#{m.source}\" is deprecated, use a comparison to MacOS.version instead" - end - end - - dirPattern(body_node) do |m| - next unless m =~ /\[("[^\*{},]+")\]/ - problem "Dir(#{Regexp.last_match(1)}) is unnecessary; just use #{Regexp.last_match(1)}" - end - - fileUtils_methods= FileUtils.singleton_methods(false).map { |m| Regexp.escape(m) }.join "|" - find_method_with_args(body_node, :system, /fileUtils_methods/) do |m| - method = string_content(@offensive_node) - problem "Use the `#{method}` Ruby method instead of `#{m.source}`" - end - - if find_method_def(@processed_source.ast) - problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level" - end - - find_instance_method_call(body_node, :build, :without?) do |m| - next unless unless_modifier?(m.parent) - correct = m.source.gsub("out?", "?").gsub("unless", "if") - problem "Use #{correct} instead of unless #{m.source}" - end - - find_instance_method_call(body_node, :build, :with?) do |m| - next unless unless_modifier?(m.parent) - correct = m.source.gsub("?", "out?").gsub("unless", "if") - problem "Use #{correct} instead of unless #{m.source}" - end - - find_instance_method_call(body_node, :build, :with?) do |m| - next unless negation?(m) - problem "Don't negate 'build.with?': use 'build.without?'" - end - - find_instance_method_call(body_node, :build, :without?) do |m| - next unless negation?(m) - problem "Don't negate 'build.without?': use 'build.with?'" - end - - find_instance_method_call(body_node, :build, :without?) do |m| - arg = parameters(m).first - next unless match = regex_match_group(arg, %r{-?-?without-(.*)}) - problem "Don't duplicate 'without': Use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\"" - end - - find_instance_method_call(body_node, :build, :with?) do |m| - arg = parameters(m).first - next unless match = regex_match_group(arg, %r{-?-?with-(.*)}) - problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\"" - end - - find_instance_method_call(body_node, :build, :include?) do |m| - arg = parameters(m).first - next unless match = regex_match_group(arg, %r{with(out)?-(.*)}) - problem "Use build.with#{match[1]}? \"#{match[2]}\" instead of build.include? 'with#{match[1]}-#{match[2]}'" - end - - find_instance_method_call(body_node, :build, :include?) do |m| - arg = parameters(m).first - next unless match = regex_match_group(arg, %r{\-\-(.*)}) - problem "Reference '#{match[1]}' without dashes" - end + # + # os = [:leopard?, :snow_leopard?, :lion?, :mountain_lion?] + # os.each do |version| + # find_instance_method_call(body_node, :MacOS, version) do |m| + # problem "\"#{m.source}\" is deprecated, use a comparison to MacOS.version instead" + # end + # end + # + # dirPattern(body_node) do |m| + # next unless m =~ /\[("[^\*{},]+")\]/ + # problem "Dir(#{Regexp.last_match(1)}) is unnecessary; just use #{Regexp.last_match(1)}" + # end + # + # fileUtils_methods= FileUtils.singleton_methods(false).map { |m| Regexp.escape(m) }.join "|" + # find_method_with_args(body_node, :system, /fileUtils_methods/) do |m| + # method = string_content(@offensive_node) + # problem "Use the `#{method}` Ruby method instead of `#{m.source}`" + # end + # + # if find_method_def(@processed_source.ast) + # problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level" + # end + # + # find_instance_method_call(body_node, :build, :without?) do |m| + # next unless unless_modifier?(m.parent) + # correct = m.source.gsub("out?", "?").gsub("unless", "if") + # problem "Use #{correct} instead of unless #{m.source}" + # end + # + # find_instance_method_call(body_node, :build, :with?) do |m| + # next unless unless_modifier?(m.parent) + # correct = m.source.gsub("?", "out?").gsub("unless", "if") + # problem "Use #{correct} instead of unless #{m.source}" + # end + # + # find_instance_method_call(body_node, :build, :with?) do |m| + # next unless negation?(m) + # problem "Don't negate 'build.with?': use 'build.without?'" + # end + # + # find_instance_method_call(body_node, :build, :without?) do |m| + # next unless negation?(m) + # problem "Don't negate 'build.without?': use 'build.with?'" + # end + # + # find_instance_method_call(body_node, :build, :without?) do |m| + # arg = parameters(m).first + # next unless match = regex_match_group(arg, %r{-?-?without-(.*)}) + # problem "Don't duplicate 'without': Use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\"" + # end + # + # find_instance_method_call(body_node, :build, :with?) do |m| + # arg = parameters(m).first + # next unless match = regex_match_group(arg, %r{-?-?with-(.*)}) + # problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\"" + # end + # + # find_instance_method_call(body_node, :build, :include?) do |m| + # arg = parameters(m).first + # next unless match = regex_match_group(arg, %r{with(out)?-(.*)}) + # problem "Use build.with#{match[1]}? \"#{match[2]}\" instead of build.include? 'with#{match[1]}-#{match[2]}'" + # end + # + # find_instance_method_call(body_node, :build, :include?) do |m| + # arg = parameters(m).first + # next unless match = regex_match_group(arg, %r{\-\-(.*)}) + # problem "Reference '#{match[1]}' without dashes" + # end end diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 293a415a5..aca9a7209 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -50,6 +50,12 @@ describe RuboCop::Cop::FormulaAudit::Lines do end end end + def expect_offense(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 describe RuboCop::Cop::FormulaAudit::ClassInheritance do @@ -77,6 +83,12 @@ describe RuboCop::Cop::FormulaAudit::ClassInheritance do end end end + def expect_offense(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 describe RuboCop::Cop::FormulaAudit::Comments do @@ -149,6 +161,12 @@ describe RuboCop::Cop::FormulaAudit::Comments do end end end + def expect_offense(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 describe RuboCop::Cop::FormulaAudit::Miscellaneous do @@ -469,5 +487,55 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with assert include" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + assert File.read("inbox").include?("Sample message 1") + end + EOS + + expected_offenses = [{ message: "Use `assert_match` instead of `assert ...include?`", + severity: :convention, + line: 4, + column: 9, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "depends_on with an instance as an argument" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + depends_on FOO::BAR.new + end + EOS + + expected_offenses = [{ message: "`depends_on` can take requirement classes instead of instances", + severity: :convention, + line: 4, + column: 13, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + end + def expect_offense(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 -- cgit v1.2.3 From 77105b809a83583e3da5726105dc9cd913112913 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Sun, 13 Aug 2017 14:50:29 +0530 Subject: Add tests for macOS check --- Library/Homebrew/rubocops/lines_cop.rb | 14 +++++++------- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 8d4b99825..604de5af9 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -248,13 +248,13 @@ module RuboCop next unless method_called?(m, :new) problem "`depends_on` can take requirement classes instead of instances" end - # - # os = [:leopard?, :snow_leopard?, :lion?, :mountain_lion?] - # os.each do |version| - # find_instance_method_call(body_node, :MacOS, version) do |m| - # problem "\"#{m.source}\" is deprecated, use a comparison to MacOS.version instead" - # end - # end + + os = [:leopard?, :snow_leopard?, :lion?, :mountain_lion?] + os.each do |version| + find_instance_method_call(body_node, "MacOS", version) do |m| + problem "\"#{m.source}\" is deprecated, use a comparison to MacOS.version instead" + end + end # # dirPattern(body_node) do |m| # next unless m =~ /\[("[^\*{},]+")\]/ diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index aca9a7209..69caee80c 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -527,6 +527,27 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do inspect_source(cop, source) + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + it "with old style OS check" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + depends_on :foo if MacOS.snow_leopard? + end + EOS + + expected_offenses = [{ message: "\"MacOS.snow_leopard?\" is deprecated, use a comparison to MacOS.version instead", + severity: :convention, + line: 4, + column: 21, + source: source }] + + inspect_source(cop, source) + expected_offenses.zip(cop.offenses).each do |expected, actual| expect_offense(expected, actual) end -- cgit v1.2.3 From a73c29fef21ccb7f45243500f04f1ed9965fdf38 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 00:02:44 +0530 Subject: add tests for non glob dirs audit --- Library/Homebrew/rubocops/lines_cop.rb | 13 ++++++++----- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 604de5af9..7a0e08ba2 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -255,11 +255,14 @@ module RuboCop problem "\"#{m.source}\" is deprecated, use a comparison to MacOS.version instead" end end - # - # dirPattern(body_node) do |m| - # next unless m =~ /\[("[^\*{},]+")\]/ - # problem "Dir(#{Regexp.last_match(1)}) is unnecessary; just use #{Regexp.last_match(1)}" - # end + + find_instance_method_call(body_node, "Dir", :[]) do |m| + path = parameters(m).first + next if !path.str_type? + next unless match = regex_match_group(path, /^[^\*{},]+$/) + problem "Dir([\"#{string_content(path)}\"]) is unnecessary; just use \"#{match[0]}\"" + end + # # fileUtils_methods= FileUtils.singleton_methods(false).map { |m| Regexp.escape(m) }.join "|" # find_method_with_args(body_node, :system, /fileUtils_methods/) do |m| diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 69caee80c..203f8a7d9 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -552,6 +552,29 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with non glob DIR" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + rm_rf Dir["src/{llvm,test,librustdoc,etc/snapshot.pyc}"] + rm_rf Dir["src/snapshot.pyc"] + end + EOS + + expected_offenses = [{ message: "Dir([\"src/snapshot.pyc\"]) is unnecessary; just use \"src/snapshot.pyc\"", + severity: :convention, + line: 5, + column: 13, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 7dfe09ccae5b1a8309326e5a5cb3172fbcd795d3 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 01:09:06 +0530 Subject: Add tests for fileUtils call in system --- Library/Homebrew/rubocops/lines_cop.rb | 15 ++++++++------- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 7a0e08ba2..1b7a1935e 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -263,13 +263,14 @@ module RuboCop problem "Dir([\"#{string_content(path)}\"]) is unnecessary; just use \"#{match[0]}\"" end - # - # fileUtils_methods= FileUtils.singleton_methods(false).map { |m| Regexp.escape(m) }.join "|" - # find_method_with_args(body_node, :system, /fileUtils_methods/) do |m| - # method = string_content(@offensive_node) - # problem "Use the `#{method}` Ruby method instead of `#{m.source}`" - # end - # + + fileUtils_methods= Regexp.new(FileUtils.singleton_methods(false).map { |m| Regexp.escape(m) }.join "|") + find_every_method_call_by_name(body_node, :system).each do |m| + param = parameters(m).first + next unless match = regex_match_group(param, fileUtils_methods) + problem "Use the `#{match}` Ruby method instead of `#{m.source}`" + end + # if find_method_def(@processed_source.ast) # problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level" # end diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 203f8a7d9..1af5d2e72 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -571,6 +571,27 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do inspect_source(cop, source) + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + it "with system call to fileUtils Method" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + system "mkdir", "foo" + end + EOS + + expected_offenses = [{ message: "Use the `mkdir` Ruby method instead of `system \"mkdir\", \"foo\"`", + severity: :convention, + line: 4, + column: 10, + source: source }] + + inspect_source(cop, source) + expected_offenses.zip(cop.offenses).each do |expected, actual| expect_offense(expected, actual) end -- cgit v1.2.3 From 6dad9d8b44e22f2729a2db95a1c2d14b3e84d477 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 01:25:44 +0530 Subject: Add test for top level method def --- Library/Homebrew/rubocops/extend/formula_cop.rb | 1 + Library/Homebrew/rubocops/lines_cop.rb | 6 +++--- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index 08c9e6eb8..cb404046c 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -232,6 +232,7 @@ module RuboCop @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 diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 1b7a1935e..22df46205 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -271,9 +271,9 @@ module RuboCop problem "Use the `#{match}` Ruby method instead of `#{m.source}`" end - # if find_method_def(@processed_source.ast) - # problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level" - # end + if find_method_def(@processed_source.ast) + problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level" + end # # find_instance_method_call(body_node, :build, :without?) do |m| # next unless unless_modifier?(m.parent) diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 1af5d2e72..00543f545 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -592,6 +592,29 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do inspect_source(cop, source) + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + it "with a top-level function def " do + source = <<-EOS.undent + def test + nil + end + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + end + EOS + + expected_offenses = [{ message: "Define method test in the class body, not at the top-level", + severity: :convention, + line: 1, + column: 0, + source: source }] + + inspect_source(cop, source) + expected_offenses.zip(cop.offenses).each do |expected, actual| expect_offense(expected, actual) end -- cgit v1.2.3 From f968776e8460d7b6a0a3199d9c92c945cda0738d Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 01:52:48 +0530 Subject: Add tests for unless build.without? --- Library/Homebrew/rubocops/lines_cop.rb | 14 +++++++------- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 22df46205..6c79e1fca 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -274,13 +274,13 @@ module RuboCop if find_method_def(@processed_source.ast) problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level" end - # - # find_instance_method_call(body_node, :build, :without?) do |m| - # next unless unless_modifier?(m.parent) - # correct = m.source.gsub("out?", "?").gsub("unless", "if") - # problem "Use #{correct} instead of unless #{m.source}" - # end - # + + find_instance_method_call(body_node, :build, :without?) do |m| + next unless unless_modifier?(m.parent) + correct = m.source.gsub("out?", "?") + problem "Use if #{correct} instead of unless #{m.source}" + end + # find_instance_method_call(body_node, :build, :with?) do |m| # next unless unless_modifier?(m.parent) # correct = m.source.gsub("?", "out?").gsub("unless", "if") diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 00543f545..352dc8219 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -619,6 +619,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with unless build.without?" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def post_install + return unless build.without? "bar" + end + end + EOS + + expected_offenses = [{ message: 'Use if build.with? "bar" instead of unless build.without? "bar"', + severity: :convention, + line: 5, + column: 18, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From ec2b0df10e62152529386cf2a696f9aaece405ea Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 01:55:47 +0530 Subject: Add tests for unless build.with? --- Library/Homebrew/rubocops/lines_cop.rb | 12 ++++++------ Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 6c79e1fca..2b146b79e 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -281,12 +281,12 @@ module RuboCop problem "Use if #{correct} instead of unless #{m.source}" end - # find_instance_method_call(body_node, :build, :with?) do |m| - # next unless unless_modifier?(m.parent) - # correct = m.source.gsub("?", "out?").gsub("unless", "if") - # problem "Use #{correct} instead of unless #{m.source}" - # end - # + find_instance_method_call(body_node, :build, :with?) do |m| + next unless unless_modifier?(m.parent) + correct = m.source.gsub("?", "out?") + problem "Use if #{correct} instead of unless #{m.source}" + end + # find_instance_method_call(body_node, :build, :with?) do |m| # next unless negation?(m) # problem "Don't negate 'build.with?': use 'build.without?'" diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 352dc8219..dda1b96e6 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -643,6 +643,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with unless build.with?" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def post_install + return unless build.with? "bar" + end + end + EOS + + expected_offenses = [{ message: 'Use if build.without? "bar" instead of unless build.with? "bar"', + severity: :convention, + line: 5, + column: 18, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From e14fedd1b35480ea3707689db044140d18662b9c Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 02:14:20 +0530 Subject: Add test for negated build.with? --- Library/Homebrew/rubocops/extend/formula_cop.rb | 8 ++++++-- Library/Homebrew/rubocops/lines_cop.rb | 11 ++++++----- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index cb404046c..94952d1f5 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -252,11 +252,15 @@ module RuboCop end # Check if method_name is called among the direct children nodes in the given node + # Check if the node itself is the method def method_called?(node, method_name) + if node.send_type? && node.method_name == method_name + offending_node(node) + return true + end node.each_child_node(:send) do |call_node| next unless call_node.method_name == method_name - @offensive_node = call_node - @offense_source_range = call_node.source_range + offending_node(call_node) return true end false diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 2b146b79e..4c82b42cf 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -287,11 +287,11 @@ module RuboCop problem "Use if #{correct} instead of unless #{m.source}" end - # find_instance_method_call(body_node, :build, :with?) do |m| - # next unless negation?(m) - # problem "Don't negate 'build.with?': use 'build.without?'" - # end - # + find_instance_method_call(body_node, :build, :with?) do |m| + next unless method_called?(m.parent, :!) + problem "Don't negate 'build.with?': use 'build.without?'" + end + # find_instance_method_call(body_node, :build, :without?) do |m| # next unless negation?(m) # problem "Don't negate 'build.without?': use 'build.with?'" @@ -324,6 +324,7 @@ module RuboCop end def unless_modifier?(node) + return false unless node.if_type? node.modifier_form? && node.unless? end diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index dda1b96e6..8e3f42adf 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -667,6 +667,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with negated build.with?" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def post_install + return if !build.with? "bar" + end + end + EOS + + expected_offenses = [{ message: "Don't negate 'build.with?': use 'build.without?'", + severity: :convention, + line: 5, + column: 14, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 3efba57cd936f1e53b72a9e66561d594fcf37d65 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 02:18:46 +0530 Subject: Add negated? method to formula cop and add tests for negated build.without? --- Library/Homebrew/rubocops/extend/formula_cop.rb | 5 +++++ Library/Homebrew/rubocops/lines_cop.rb | 12 ++++++------ Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index 94952d1f5..862dabfda 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -297,6 +297,11 @@ module RuboCop true end + # Check if negation is present in the given node + def negated?(node) + method_called?(node, :!) + end + # Return all the caveats' string nodes in an array def caveats_strings find_strings(find_method_def(@body, :caveats)) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 4c82b42cf..6c0c3ec73 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -288,15 +288,15 @@ module RuboCop end find_instance_method_call(body_node, :build, :with?) do |m| - next unless method_called?(m.parent, :!) + next unless negated?(m.parent) problem "Don't negate 'build.with?': use 'build.without?'" end - # find_instance_method_call(body_node, :build, :without?) do |m| - # next unless negation?(m) - # problem "Don't negate 'build.without?': use 'build.with?'" - # end - # + find_instance_method_call(body_node, :build, :without?) do |m| + next unless negated?(m.parent) + problem "Don't negate 'build.without?': use 'build.with?'" + end + # find_instance_method_call(body_node, :build, :without?) do |m| # arg = parameters(m).first # next unless match = regex_match_group(arg, %r{-?-?without-(.*)}) diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 8e3f42adf..e00834963 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -691,6 +691,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with negated build.with?" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def post_install + return if !build.without? "bar" + end + end + EOS + + expected_offenses = [{ message: "Don't negate 'build.without?': use 'build.with?'", + severity: :convention, + line: 5, + column: 14, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 02a1406a2e4c2d0506861248eb767d99f5ce4515 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 02:32:29 +0530 Subject: add test for build.without --without-foo --- Library/Homebrew/rubocops/lines_cop.rb | 12 ++++++------ Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 6c0c3ec73..d6dba9061 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -297,12 +297,12 @@ module RuboCop problem "Don't negate 'build.without?': use 'build.with?'" end - # find_instance_method_call(body_node, :build, :without?) do |m| - # arg = parameters(m).first - # next unless match = regex_match_group(arg, %r{-?-?without-(.*)}) - # problem "Don't duplicate 'without': Use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\"" - # end - # + find_instance_method_call(body_node, :build, :without?) do |m| + arg = parameters(m).first + next unless match = regex_match_group(arg, %r{-?-?without-(.*)}) + problem "Don't duplicate 'without': Use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\"" + end + # find_instance_method_call(body_node, :build, :with?) do |m| # arg = parameters(m).first # next unless match = regex_match_group(arg, %r{-?-?with-(.*)}) diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index e00834963..0c225a5b6 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -715,6 +715,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with negated build.with?" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def post_install + return if build.without? "--without-bar" + end + end + EOS + + expected_offenses = [{ message: "Don't duplicate 'without': Use `build.without? \"bar\"` to check for \"--without-bar\"", + severity: :convention, + line: 5, + column: 30, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 5a7cbb762f1a9e715ae03e82eb6cb8ef4ac4a0bb Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 02:43:54 +0530 Subject: add test for build.with? "--with-foo" --- Library/Homebrew/rubocops/lines_cop.rb | 12 +++++------ Library/Homebrew/test/rubocops/lines_cop_spec.rb | 26 +++++++++++++++++++++++- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index d6dba9061..5ed9acc93 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -303,12 +303,12 @@ module RuboCop problem "Don't duplicate 'without': Use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\"" end - # find_instance_method_call(body_node, :build, :with?) do |m| - # arg = parameters(m).first - # next unless match = regex_match_group(arg, %r{-?-?with-(.*)}) - # problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\"" - # end - # + find_instance_method_call(body_node, :build, :with?) do |m| + arg = parameters(m).first + next unless match = regex_match_group(arg, %r{-?-?with-(.*)}) + problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\"" + end + # find_instance_method_call(body_node, :build, :include?) do |m| # arg = parameters(m).first # next unless match = regex_match_group(arg, %r{with(out)?-(.*)}) diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 0c225a5b6..273014cf1 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -716,7 +716,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with negated build.with?" do + it "with duplicated build.without?" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -739,6 +739,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with duplicated build.with?" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def post_install + return if build.with? "--with-bar" + end + end + EOS + + expected_offenses = [{ message: "Don't duplicate 'with': Use `build.with? \"bar\"` to check for \"--with-bar\"", + severity: :convention, + line: 5, + column: 27, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 3ff8be1216388817dda2b4bb95aeaa5c3d3d5a6b Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 02:47:29 +0530 Subject: add test for build.include? --- Library/Homebrew/rubocops/lines_cop.rb | 10 +++++----- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 5ed9acc93..b6567466a 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -309,11 +309,11 @@ module RuboCop problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\"" end - # find_instance_method_call(body_node, :build, :include?) do |m| - # arg = parameters(m).first - # next unless match = regex_match_group(arg, %r{with(out)?-(.*)}) - # problem "Use build.with#{match[1]}? \"#{match[2]}\" instead of build.include? 'with#{match[1]}-#{match[2]}'" - # end + find_instance_method_call(body_node, :build, :include?) do |m| + arg = parameters(m).first + next unless match = regex_match_group(arg, %r{with(out)?-(.*)}) + problem "Use build.with#{match[1]}? \"#{match[2]}\" instead of build.include? 'with#{match[1]}-#{match[2]}'" + end # # find_instance_method_call(body_node, :build, :include?) do |m| # arg = parameters(m).first diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 273014cf1..36c6272b3 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -763,6 +763,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with build.include?" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def post_install + return if build.include? "without-bar" + end + end + EOS + + expected_offenses = [{ message: "Use build.without? \"bar\" instead of build.include? 'without-bar'", + severity: :convention, + line: 5, + column: 30, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From dc4d10ff6a59ce0da1bfc7bc06dd819c442813ab Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 02:49:52 +0530 Subject: add test for build.include? having dashed args --- Library/Homebrew/rubocops/lines_cop.rb | 12 ++++++------ Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index b6567466a..dac523424 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -314,12 +314,12 @@ module RuboCop next unless match = regex_match_group(arg, %r{with(out)?-(.*)}) problem "Use build.with#{match[1]}? \"#{match[2]}\" instead of build.include? 'with#{match[1]}-#{match[2]}'" end - # - # find_instance_method_call(body_node, :build, :include?) do |m| - # arg = parameters(m).first - # next unless match = regex_match_group(arg, %r{\-\-(.*)}) - # problem "Reference '#{match[1]}' without dashes" - # end + + find_instance_method_call(body_node, :build, :include?) do |m| + arg = parameters(m).first + next unless match = regex_match_group(arg, %r{\-\-(.*)}) + problem "Reference '#{match[1]}' without dashes" + end end diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 36c6272b3..288ca8f8f 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -787,6 +787,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with build.include? with dashed args" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def post_install + return if build.include? "--bar" + end + end + EOS + + expected_offenses = [{ message: "Reference 'bar' without dashes", + severity: :convention, + line: 5, + column: 30, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 76f4eccdceb5b3fb4e88b56e077234a6a3e56b08 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 15:22:44 +0530 Subject: add test for using ARGV to check options --- Library/Homebrew/rubocops/lines_cop.rb | 11 +++++------ Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index dac523424..6a6f34821 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -88,11 +88,11 @@ module RuboCop end end - # [:debug?, :verbose?, :value].each do |m| - # find_instance_method_call(body_node, :ARGV, m) do - # problem "Use build instead of ARGV to check options" - # end - # end + [:debug?, :verbose?, :value].each do |m| + find_instance_method_call(body_node, "ARGV", m) do + problem "Use build instead of ARGV to check options" + end + end # # find_instance_method_call(body_node, :man, :+) do |m| # next unless match = regex_match_group(parameters(m).first, %r{man[1-8]}) @@ -320,7 +320,6 @@ module RuboCop next unless match = regex_match_group(arg, %r{\-\-(.*)}) problem "Reference '#{match[1]}' without dashes" end - end def unless_modifier?(node) diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 288ca8f8f..b5ff3d1f4 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -811,6 +811,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with using ARGV to check options" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def test + verbose = ARGV.verbose? + end + end + EOS + + expected_offenses = [{ message: "Use build instead of ARGV to check options", + severity: :convention, + line: 5, + column: 14, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From af5cd1a1da0e1b87696ae72b8a5f1c174e83e94e Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 15:41:03 +0530 Subject: add tests for man+'man[1-8]' --- Library/Homebrew/rubocops/lines_cop.rb | 12 ++++++------ Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 6a6f34821..cf1ac68c3 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -93,12 +93,12 @@ module RuboCop problem "Use build instead of ARGV to check options" end end - # - # find_instance_method_call(body_node, :man, :+) do |m| - # next unless match = regex_match_group(parameters(m).first, %r{man[1-8]}) - # problem "\"#{m.source}\" should be \"#{match[1]}\"" - # end - # + + find_instance_method_call(body_node, :man, :+) do |m| + next unless match = regex_match_group(parameters(m).first, %r{man[1-8]}) + problem "\"#{m.source}\" should be \"#{match[0]}\"" + end + # # Avoid hard-coding compilers # find_every_method_call_by_name(body_node, :system).each do |m| # param = parameters(m).first diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index b5ff3d1f4..c0cd754b3 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -835,6 +835,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with man+ " do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def test + man1.install man+"man8" => "faad.1" + end + end + EOS + + expected_offenses = [{ message: "\"man+\"man8\"\" should be \"man8\"", + severity: :convention, + line: 5, + column: 22, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 77468fdae36ee58580a643d8bc0fdd9f8b6e61c3 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 19:58:39 +0530 Subject: add tests for hard coded compilers in system calls --- Library/Homebrew/rubocops/lines_cop.rb | 18 ++++----- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 48 ++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index cf1ac68c3..4d2d63cce 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -99,15 +99,15 @@ module RuboCop problem "\"#{m.source}\" should be \"#{match[0]}\"" end - # # Avoid hard-coding compilers - # find_every_method_call_by_name(body_node, :system).each do |m| - # param = parameters(m).first - # if match = regex_match_group(param, %r{(/usr/bin/)?(gcc|llvm-gcc|clang)\s?}) - # problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[3]}\"" - # elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?}) - # problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[3]}\"" - # end - # end + # Avoid hard-coding compilers + find_every_method_call_by_name(body_node, :system).each do |m| + param = parameters(m).first + if match = regex_match_group(param, %r{(/usr/bin/)?(gcc|llvm-gcc|clang)\s?}) + problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[2]}\"" + elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?}) + problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[2]}\"" + end + end # # find_instance_method_call(body_node, :ENV, :[]=) do |m| # param = parameters(m)[1] diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index c0cd754b3..7e901f0e2 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -859,6 +859,54 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with hardcoded compiler 1 " do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def test + system "/usr/bin/gcc", "foo" + end + end + EOS + + expected_offenses = [{ message: "Use \"\#{ENV.cc}\" instead of hard-coding \"gcc\"", + severity: :convention, + line: 5, + column: 12, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with hardcoded compiler 2 " do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def test + system "/usr/bin/g++", "-o", "foo", "foo.cc" + end + end + EOS + + expected_offenses = [{ message: "Use \"\#{ENV.cxx}\" instead of hard-coding \"g++\"", + severity: :convention, + line: 5, + column: 12, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 65ae6bacd8c92d718b259f7efd50fc3fe9f0838b Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 20:10:45 +0530 Subject: add tests for hardcoded compilers in ENV --- Library/Homebrew/rubocops/lines_cop.rb | 20 ++++----- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 56 ++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 4d2d63cce..919b21243 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -108,16 +108,16 @@ module RuboCop problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[2]}\"" end end - # - # find_instance_method_call(body_node, :ENV, :[]=) do |m| - # param = parameters(m)[1] - # if match = regex_match_group(param, %r{(/usr/bin/)?(gcc|llvm-gcc|clang)\s?}) - # problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[3]}\"" - # elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?}) - # problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[3]}\"" - # end - # end - # + + find_instance_method_call(body_node, "ENV", :[]=) do |m| + param = parameters(m)[1] + if match = regex_match_group(param, %r{(/usr/bin/)?(gcc|llvm-gcc|clang)\s?}) + problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[2]}\"" + elsif match = regex_match_group(param, %r{(/usr/bin/)?((g|llvm-g|clang)\+\+)\s?}) + problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[2]}\"" + end + end + # # Prefer formula path shortcuts in strings # formula_path_strings(body_node, :prefix) do |p| # next unless match = regex_match_group(p, %r{(/(man))[/'"]}) diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 7e901f0e2..afe65e9ac 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -817,7 +817,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - def test + def install verbose = ARGV.verbose? end end @@ -841,7 +841,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - def test + def install man1.install man+"man8" => "faad.1" end end @@ -865,7 +865,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - def test + def install system "/usr/bin/gcc", "foo" end end @@ -889,7 +889,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - def test + def install system "/usr/bin/g++", "-o", "foo", "foo.cc" end end @@ -907,6 +907,54 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with hardcoded compiler 3 " do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def install + ENV["COMPILER_PATH"] = "/usr/bin/llvm-g++" + end + end + EOS + + expected_offenses = [{ message: "Use \"\#{ENV.cxx}\" instead of hard-coding \"llvm-g++\"", + severity: :convention, + line: 5, + column: 28, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with hardcoded compiler 4 " do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def install + ENV["COMPILER_PATH"] = "/usr/bin/gcc" + end + end + EOS + + expected_offenses = [{ message: "Use \"\#{ENV.cc}\" instead of hard-coding \"gcc\"", + severity: :convention, + line: 5, + column: 28, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 9c9c280c8aeb97a6ec8956242727208d80247826 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 21:34:01 +0530 Subject: add tests for formula path string 1 --- Library/Homebrew/rubocops/lines_cop.rb | 38 ++++++++++++------------ Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 +++++++++++++++ 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 919b21243..49eff510d 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -118,24 +118,24 @@ module RuboCop end end - # # Prefer formula path shortcuts in strings - # formula_path_strings(body_node, :prefix) do |p| - # next unless match = regex_match_group(p, %r{(/(man))[/'"]}) - # problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[3]}}\"" - # end - # - # formula_path_strings(body_node, :share) do |p| - # if match = regex_match_group(p, %r{/(bin|include|libexec|lib|sbin|share|Frameworks)}i) - # problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[1].downcase}}\"" - # end - # if match = regex_match_group(p, %r{((/share/man/|\#\{man\}/)(man[1-8]))}) - # problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[3]}}\"" - # end - # if match = regex_match_group(p, %r{(/share/(info|man))}) - # problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2]}}\"" - # end - # end - # + # Prefer formula path shortcuts in strings + formula_path_strings(body_node, :share) do |p| + next unless match = regex_match_group(p, %r{(/(man))/?}) + problem "\"\#\{share}#{match[1]}\" should be \"\#{#{match[2]}}\"" + end + + formula_path_strings(body_node, :share) do |p| + if match = regex_match_group(p, %r{/(bin|include|libexec|lib|sbin|share|Frameworks)}i) + problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[1].downcase}}\"" + end + if match = regex_match_group(p, %r{((/share/man/|\#\{man\}/)(man[1-8]))}) + problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[3]}}\"" + end + if match = regex_match_group(p, %r{(/share/(info|man))}) + problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2]}}\"" + end + end + # find_every_method_call_by_name(body_node, :depends_on) do |m| # key, value = destructure_hash(paramters(m).first) # next unless key.str_type? @@ -349,7 +349,7 @@ module RuboCop (hash (pair $_ $_)) EOS - def_node_matcher :formula_path_strings, <<-EOS.undent + def_node_search :formula_path_strings, <<-EOS.undent (dstr (begin (send nil %1)) $(str _ )) EOS diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index afe65e9ac..63ae88dd9 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -955,6 +955,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with formula path shortcut long form" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def install + mv "\#{share}/man", share + end + end + EOS + + expected_offenses = [{ message: "\"\#\{share}/man\" should be \"\#{man}\"", + severity: :convention, + line: 5, + column: 17, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 063cbe7acdb0af0a4cd9bd35f29f89bc0d638d4a Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 22:44:28 +0530 Subject: add tests for formula path shortucut 3 --- Library/Homebrew/rubocops/lines_cop.rb | 15 ++--- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 72 ++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 49eff510d..d3640c9ef 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -124,15 +124,15 @@ module RuboCop problem "\"\#\{share}#{match[1]}\" should be \"\#{#{match[2]}}\"" end - formula_path_strings(body_node, :share) do |p| - if match = regex_match_group(p, %r{/(bin|include|libexec|lib|sbin|share|Frameworks)}i) - problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[1].downcase}}\"" + formula_path_strings(body_node, :prefix) do |p| + if match = regex_match_group(p, %r{(/share/(info|man))$}) + problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2]}}\"" end - if match = regex_match_group(p, %r{((/share/man/|\#\{man\}/)(man[1-8]))}) + if match = regex_match_group(p, %r{((/share/man/)(man[1-8]))}) problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[3]}}\"" end - if match = regex_match_group(p, %r{(/share/(info|man))}) - problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2]}}\"" + if match = regex_match_group(p, %r{(/(bin|include|libexec|lib|sbin|share|Frameworks))}i) + problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2].downcase}}\"" end end @@ -350,7 +350,8 @@ module RuboCop EOS def_node_search :formula_path_strings, <<-EOS.undent - (dstr (begin (send nil %1)) $(str _ )) + {(dstr (begin (send nil %1)) $(str _ )) + (dstr _ (begin (send nil %1)) $(str _ ))} EOS def_node_matcher :negation?, '(send ... :!)' diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 63ae88dd9..1d25c4721 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -979,6 +979,78 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do expect_offense(expected, actual) end end + + it "with formula path shortcut long form 1" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def install + mv "\#{prefix}/libexec", share + end + end + EOS + + expected_offenses = [{ message: "\"\#\{prefix}/libexec\" should be \"\#{libexec}\"", + severity: :convention, + line: 5, + column: 18, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with formula path shortcut long form 2" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def install + system "./configure", "--INFODIR=\#{prefix}/share/info" + end + end + EOS + + expected_offenses = [{ message: "\"\#\{prefix}/share/info\" should be \"\#{info}\"", + severity: :convention, + line: 5, + column: 47, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + it "with formula path shortcut long form 3" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + def install + system "./configure", "--MANDIR=\#{prefix}/share/man/man8" + end + end + EOS + + expected_offenses = [{ message: "\"\#\{prefix}/share/man/man8\" should be \"\#{man8}\"", + severity: :convention, + line: 5, + column: 46, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 64a929184a45f530a49af7b047d5b6605b50b1f8 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 23:05:00 +0530 Subject: add tests for vendored deps --- Library/Homebrew/rubocops/lines_cop.rb | 17 ++++++++--------- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index d3640c9ef..6520018ac 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -135,14 +135,13 @@ module RuboCop problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2].downcase}}\"" end end + find_every_method_call_by_name(body_node, :depends_on).each do |m| + key, value = destructure_hash(parameters(m).first) + next if (key.nil? || value.nil?) + next unless match = regex_match_group(value, %r{(lua|perl|python|ruby)(\d*)}) + problem "#{match[1]} modules should be vendored rather than use deprecated #{m.source}`" + end - # find_every_method_call_by_name(body_node, :depends_on) do |m| - # key, value = destructure_hash(paramters(m).first) - # next unless key.str_type? - # next unless match = regex_match_group(value, %r{(lua|perl|python|ruby)(\d*)}) - # problem "#{match[1]} modules should be vendored rather than use deprecated #{m.source}`" - # end - # # find_every_method_call_by_name(body_node, :system).each do |m| # next unless match = regex_match_group(parameters(m).first, %r{(env|export)(\s+)?}) # problem "Use ENV instead of invoking '#{match[1]}' to modify the environment" @@ -345,8 +344,8 @@ module RuboCop $(hash (pair $(str _) (array $(str _) ...)))} EOS - def_node_search :destructure_hash, <<-EOS.undent - (hash (pair $_ $_)) + def_node_matcher :destructure_hash, <<-EOS.undent + (hash (pair $(str _) $(sym _))) EOS def_node_search :formula_path_strings, <<-EOS.undent diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 1d25c4721..f3626cdce 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -1051,6 +1051,28 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end + it "with dependecies which have to vendored" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + depends_on "lpeg" => :lua51 + end + EOS + + expected_offenses = [{ message: "lua modules should be vendored rather than use deprecated depends_on \"lpeg\" => :lua51`", + severity: :convention, + line: 4, + column: 24, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From d2a7314f538f919e9b09e4b27c1f86b7d3d2eda2 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Mon, 14 Aug 2017 23:32:06 +0530 Subject: add test for env mod through system call --- Library/Homebrew/rubocops/lines_cop.rb | 11 ++++++----- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 6520018ac..e20fa9f8b 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -135,6 +135,7 @@ module RuboCop problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2].downcase}}\"" end end + find_every_method_call_by_name(body_node, :depends_on).each do |m| key, value = destructure_hash(parameters(m).first) next if (key.nil? || value.nil?) @@ -142,11 +143,11 @@ module RuboCop problem "#{match[1]} modules should be vendored rather than use deprecated #{m.source}`" end - # find_every_method_call_by_name(body_node, :system).each do |m| - # next unless match = regex_match_group(parameters(m).first, %r{(env|export)(\s+)?}) - # problem "Use ENV instead of invoking '#{match[1]}' to modify the environment" - # end - # + find_every_method_call_by_name(body_node, :system).each do |m| + next unless match = regex_match_group(parameters(m).first, %r{(env|export)(\s+)?}) + problem "Use ENV instead of invoking '#{match[1]}' to modify the environment" + end + # find_every_method_call_by_name(body_node, :depends_on).each do |m| # next unless modifier?(m) # dep, option = hash_dep(m) diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index f3626cdce..be2b63c47 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -1073,6 +1073,28 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end + it "with setting env manually" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + system "export", "var=value" + end + EOS + + expected_offenses = [{ message: "Use ENV instead of invoking 'export' to modify the environment", + severity: :convention, + line: 4, + column: 10, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From cfc423e1839442f605072db14aac42f6f5fa6174 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Tue, 15 Aug 2017 00:05:50 +0530 Subject: add tests for dependencies --- Library/Homebrew/rubocops/lines_cop.rb | 23 +++++++++++++---------- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index e20fa9f8b..0c465f9f5 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -148,13 +148,15 @@ module RuboCop problem "Use ENV instead of invoking '#{match[1]}' to modify the environment" end - # find_every_method_call_by_name(body_node, :depends_on).each do |m| - # next unless modifier?(m) - # dep, option = hash_dep(m) - # next if dep.nil? || option.nil? - # problem "Dependency #{string_content(dep)} should not use option #{string_content(option)}" - # end - # + find_every_method_call_by_name(body_node, :depends_on).each do |m| + next if modifier?(m.parent) + param = parameters(m).first + dep, option = hash_dep(param) + next if dep.nil? || option.nil? + offending_node(param) + problem "Dependency #{string_content(dep)} should not use option #{string_content(option)}" + end + # find_instance_method_call(body_node, :version, :==) do |m| # next unless parameters_passed?(m, "HEAD") # problem "Use 'build.head?' instead of inspecting 'version'" @@ -328,6 +330,7 @@ module RuboCop end def modifier?(node) + return false unless node.if_type? node.modifier_form? end @@ -340,9 +343,9 @@ module RuboCop EOS # Match depends_on with hash as argument - def_node_search :hash_dep, <<-EOS.undent - {$(hash (pair $(str _) $(str _))) - $(hash (pair $(str _) (array $(str _) ...)))} + def_node_matcher :hash_dep, <<-EOS.undent + {(hash (pair $(str _) $(str _))) + (hash (pair $(str _) (array $(str _) ...)))} EOS def_node_matcher :destructure_hash, <<-EOS.undent diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index be2b63c47..1273ef9c9 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -1095,6 +1095,28 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end + it "with dependencies with invalid options" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + depends_on "foo" => "with-bar" + end + EOS + + expected_offenses = [{ message: "Dependency foo should not use option with-bar", + severity: :convention, + line: 4, + column: 13, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 5744cd9066bbdfc4db5332a202ddb962d5359ee5 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Tue, 15 Aug 2017 00:29:58 +0530 Subject: add test for inspecting version --- Library/Homebrew/rubocops/lines_cop.rb | 10 +++++----- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 0c465f9f5..324fe487a 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -157,11 +157,11 @@ module RuboCop problem "Dependency #{string_content(dep)} should not use option #{string_content(option)}" end - # find_instance_method_call(body_node, :version, :==) do |m| - # next unless parameters_passed?(m, "HEAD") - # problem "Use 'build.head?' instead of inspecting 'version'" - # end - # + find_instance_method_call(body_node, :version, :==) do |m| + next unless parameters_passed?(m, "HEAD") + problem "Use 'build.head?' instead of inspecting 'version'" + end + # find_instance_method_call(body_node, :ENV, :fortran) do # next if depends_on?(:fortran) # problem "Use `depends_on :fortran` instead of `ENV.fortran`" diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 1273ef9c9..f24a6b09d 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -1117,6 +1117,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end + it "with inspecting version" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + if version == "HEAD" + foo() + end + end + EOS + + expected_offenses = [{ message: "Use 'build.head?' instead of inspecting 'version'", + severity: :convention, + line: 4, + column: 5, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 3fc6cc1a3a4b8f1b7ca42dc0a7dd7cf8fad91b18 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Tue, 15 Aug 2017 00:32:34 +0530 Subject: add test for ENV.fortran --- Library/Homebrew/rubocops/lines_cop.rb | 10 +++++----- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 324fe487a..7ee1833a1 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -162,11 +162,11 @@ module RuboCop problem "Use 'build.head?' instead of inspecting 'version'" end - # find_instance_method_call(body_node, :ENV, :fortran) do - # next if depends_on?(:fortran) - # problem "Use `depends_on :fortran` instead of `ENV.fortran`" - # end - # + find_instance_method_call(body_node, "ENV", :fortran) do + next if depends_on?(:fortran) + problem "Use `depends_on :fortran` instead of `ENV.fortran`" + end + # find_instance_method_call(body_node, :ARGV, :include?) do |m| # param = parameters(m).first # next unless match = regex_match_group(param, %r{--(HEAD|devel)}) diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index f24a6b09d..1b23cca83 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -1141,6 +1141,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end + it "with ENV.fortran" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + test do + ENV.fortran + end + end + EOS + + expected_offenses = [{ message: "Use `depends_on :fortran` instead of `ENV.fortran`", + severity: :convention, + line: 5, + column: 4, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From 2f94d5f499bca6bbab238bb6536f05195b358159 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Tue, 15 Aug 2017 00:36:37 +0530 Subject: add test for ARGV.include? --- Library/Homebrew/rubocops/lines_cop.rb | 12 ++++++------ Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 7ee1833a1..0ba3c6bc5 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -167,12 +167,12 @@ module RuboCop problem "Use `depends_on :fortran` instead of `ENV.fortran`" end - # find_instance_method_call(body_node, :ARGV, :include?) do |m| - # param = parameters(m).first - # next unless match = regex_match_group(param, %r{--(HEAD|devel)}) - # problem "Use \"if build.#{match[1].downcase}?\" instead" - # end - # + find_instance_method_call(body_node, "ARGV", :include?) do |m| + param = parameters(m).first + next unless match = regex_match_group(param, %r{--(HEAD|devel)}) + problem "Use \"if build.#{match[1].downcase}?\" instead" + end + # find_const(body_node, :MACOS_VERSION) do # problem "Use MacOS.version instead of MACOS_VERSION" # end diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 1b23cca83..44f22df62 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -1165,6 +1165,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end + it "with ARGV.include? (--HEAD)" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + test do + head = ARGV.include? "--HEAD" + end + end + EOS + + expected_offenses = [{ message: "Use \"if build.head?\" instead", + severity: :convention, + line: 5, + column: 26, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From efabd4b5c2beadecf3282dbe730b1b6f779571e0 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Tue, 15 Aug 2017 00:42:56 +0530 Subject: Add tests for MACOS version consts usage --- Library/Homebrew/rubocops/extend/formula_cop.rb | 4 ++-- Library/Homebrew/rubocops/lines_cop.rb | 16 ++++++++-------- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 24 ++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index 862dabfda..76c7e43e9 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -173,8 +173,8 @@ module RuboCop # if block given, yield matching nodes def find_const(node, const_name) return if node.nil? - node.each_child_node(:const) do |const_node| - next if const_node.const_name != const_name + node.each_descendant(:const) do |const_node| + 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? diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 0ba3c6bc5..e5ccc09e9 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -173,14 +173,14 @@ module RuboCop problem "Use \"if build.#{match[1].downcase}?\" instead" end - # find_const(body_node, :MACOS_VERSION) do - # problem "Use MacOS.version instead of MACOS_VERSION" - # end - # - # find_const(body_node, :MACOS_FULL_VERSION) do - # problem "Use MacOS.full_version instead of MACOS_FULL_VERSION" - # end - # + find_const(body_node, "MACOS_VERSION") do + problem "Use MacOS.version instead of MACOS_VERSION" + end + + find_const(body_node, "MACOS_FULL_VERSION") do + problem "Use MacOS.full_version instead of MACOS_FULL_VERSION" + end + # dependency(body_node) do |m| # # handle symbols and shit: WIP # next unless modifier?(m.parent) diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index 44f22df62..b069148f9 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -1189,6 +1189,30 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end + it "with MACOS_VERSION const" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + test do + version = MACOS_VERSION + end + end + EOS + + expected_offenses = [{ message: "Use MacOS.version instead of MACOS_VERSION", + severity: :convention, + line: 5, + column: 14, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From afdd0e2437426ec85ff86e5b7562d3a6a69ba3e5 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Tue, 15 Aug 2017 16:09:32 +0530 Subject: add tests for condition dependencies --- Library/Homebrew/rubocops/lines_cop.rb | 51 ++++++++---------- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 66 ++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 30 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index e5ccc09e9..ef199fb6e 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -181,27 +181,22 @@ module RuboCop problem "Use MacOS.full_version instead of MACOS_FULL_VERSION" end - # dependency(body_node) do |m| - # # handle symbols and shit: WIP - # next unless modifier?(m.parent) - # dep = parameters(m).first - # condition = m.parent.condition - # if (condition.if? && condition.method_name == :include? && parameters_passed(condition, /with-#{string_content(dep)}$/))|| - # (condition.if? && condition.method_name == :with? && parameters_passed?(condition, /#{string_content(dep)}$/)) - # problem "Replace #{m.parent.source} with #{dep.source} => :optional" - # end - # if (condition.unless? && condition.method_name == :include? && parameters_passed?(condition, /without-#{string_content(dep)}$/))|| - # (condition.unless? && condition.method_name == :without? && parameters_passed?(condition, /#{string_content(dep)}$/)) - # problem "Replace #{m.parent.source} with #{dep.source} => :recommended" - # end - # end - # - # find_every_method_call_by_name(body_node, :depends_on).each do |m| - # next unless modifier?(m.parent) - # dep = parameters(m).first - # next if dep.hash_type? - # condition = m.parent.node_parts - # end + conditional_dependencies(body_node) do |node, method, param, dep_node| + dep = string_content(dep_node) + if node.if? + if (method == :include? && regex_match_group(param, /with-#{dep}$/)) || + (method == :with? && regex_match_group(param, /#{dep}$/)) + offending_node(dep_node.parent) + problem "Replace #{node.source} with #{dep_node.parent.source} => :optional" + end + elsif node.unless? + if (method == :include? && regex_match_group(param, /without-#{dep}$/)) || + (method == :without? && regex_match_group(param, /#{dep}$/)) + offending_node(dep_node.parent) + problem "Replace #{node.source} with #{dep_node.parent.source} => :recommended" + end + 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" @@ -334,12 +329,12 @@ module RuboCop node.modifier_form? end - def_node_search :condition, <<-EOS.undent - (send (send nil :build) $_ $({str sym} _)) - EOS + def_node_search :conditional_dependencies, <<-EOS.undent + {$(if (send (send nil :build) ${:include? :with? :without?} $(str _)) + (send nil :depends_on $({str sym} _)) nil) - def_node_search :dependency, <<-EOS.undent - (send nil :depends_on ({str sym} _)) + $(if (send (send nil :build) ${:include? :with? :without?} $(str _)) nil + (send nil :depends_on $({str sym} _)))} EOS # Match depends_on with hash as argument @@ -357,7 +352,6 @@ module RuboCop (dstr _ (begin (send nil %1)) $(str _ ))} EOS - def_node_matcher :negation?, '(send ... :!)' # 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 @@ -365,9 +359,6 @@ module RuboCop (const (const nil :Language) :Node) PATTERN - def_node_search :dirPattern, <<-PATTERN - (send (const nil :Dir) :[] (str $_)) - PATTERN end end end diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index b069148f9..6f1f8a48c 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -1213,6 +1213,72 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end + it "with if conditional dep" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + depends_on "foo" if build.with? "with-foo" + end + EOS + + expected_offenses = [{ message: 'Replace depends_on "foo" if build.with? "with-foo" with depends_on "foo" => :optional', + severity: :convention, + line: 4, + column: 2, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with unless conditional dep and symbol" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + depends_on :foo unless build.without? "foo" + end + EOS + + expected_offenses = [{ message: 'Replace depends_on :foo unless build.without? "foo" with depends_on :foo => :recommended', + severity: :convention, + line: 4, + column: 2, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "with unless conditional dep with build.include?" do + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + depends_on :foo unless build.include? "without-foo" + end + EOS + + expected_offenses = [{ message: 'Replace depends_on :foo unless build.include? "without-foo" with depends_on :foo => :recommended', + severity: :convention, + line: 4, + column: 2, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + end def expect_offense(expected, actual) expect(actual.message).to eq(expected[:message]) -- cgit v1.2.3 From ee35d6586791be65b9cfbb976394c9191625aaee Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Sat, 21 Oct 2017 12:50:49 +0530 Subject: lines_cop: Refactor to multiple cops and fix style violations --- Library/Homebrew/rubocops/lines_cop.rb | 164 ++-- Library/Homebrew/test/rubocops/lines_cop_spec.rb | 1044 +++++++++++----------- 2 files changed, 612 insertions(+), 596 deletions(-) diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index 0491845b5..7e434d755 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -54,6 +54,87 @@ module RuboCop end end + class AssertStatements < FormulaCop + def audit_formula(_node, _class_node, _parent_class_node, body_node) + find_every_method_call_by_name(body_node, :assert).each do |method| + if method_called_ever?(method, :include?) && !method_called_ever?(method, :!) + problem "Use `assert_match` instead of `assert ...include?`" + end + + if method_called_ever?(method, :exist?) && !method_called_ever?(method, :!) + problem "Use `assert_predicate , :exist?` instead of `#{method.source}`" + end + + if method_called_ever?(method, :exist?) && method_called_ever?(method, :!) + problem "Use `refute_predicate , :exist?` instead of `#{method.source}`" + end + + if method_called_ever?(method, :executable?) && !method_called_ever?(method, :!) + problem "Use `assert_predicate , :executable?` instead of `#{method.source}`" + end + end + end + end + + class OptionDeclarations < FormulaCop + def audit_formula(_node, _class_node, _parent_class_node, body_node) + if find_method_def(body_node, :options) + problem "Use new-style option definitions" + end + + find_instance_method_call(body_node, :build, :without?) do |method| + next unless unless_modifier?(method.parent) + correct = method.source.gsub("out?", "?") + problem "Use if #{correct} instead of unless #{method.source}" + end + + find_instance_method_call(body_node, :build, :with?) do |method| + next unless unless_modifier?(method.parent) + correct = method.source.gsub("?", "out?") + problem "Use if #{correct} instead of unless #{method.source}" + end + + find_instance_method_call(body_node, :build, :with?) do |method| + next unless negated?(method.parent) + problem "Don't negate 'build.with?': use 'build.without?'" + end + + find_instance_method_call(body_node, :build, :without?) do |method| + next unless negated?(method.parent) + problem "Don't negate 'build.without?': use 'build.with?'" + end + + find_instance_method_call(body_node, :build, :without?) do |method| + arg = parameters(method).first + next unless match = regex_match_group(arg, /-?-?without-(.*)/) + problem "Don't duplicate 'without': Use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\"" + end + + find_instance_method_call(body_node, :build, :with?) do |method| + arg = parameters(method).first + next unless match = regex_match_group(arg, /-?-?with-(.*)/) + problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\"" + end + + find_instance_method_call(body_node, :build, :include?) do |method| + arg = parameters(method).first + next unless match = regex_match_group(arg, /with(out)?-(.*)/) + problem "Use build.with#{match[1]}? \"#{match[2]}\" instead of build.include? 'with#{match[1]}-#{match[2]}'" + end + + find_instance_method_call(body_node, :build, :include?) do |method| + arg = parameters(method).first + next unless match = regex_match_group(arg, /\-\-(.*)/) + problem "Reference '#{match[1]}' without dashes" + end + end + + def unless_modifier?(node) + return false unless node.if_type? + node.modifier_form? && node.unless? + end + end + class Miscellaneous < FormulaCop def audit_formula(_node, _class_node, _parent_class_node, body_node) # FileUtils is included in Formula @@ -115,7 +196,7 @@ module RuboCop # Prefer formula path shortcuts in strings formula_path_strings(body_node, :share) do |p| next unless match = regex_match_group(p, %r{(/(man))/?}) - problem "\"\#\{share}#{match[1]}\" should be \"\#{#{match[2]}}\"" + problem "\"\#{share}#{match[1]}\" should be \"\#{#{match[2]}}\"" end formula_path_strings(body_node, :prefix) do |p| @@ -215,10 +296,6 @@ module RuboCop 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 <<-EOS.undent.chomp `skip_clean :all` is deprecated; brew no longer strips symbols @@ -226,6 +303,10 @@ module RuboCop EOS end + if find_method_def(@processed_source.ast) + problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level" + end + find_instance_method_call(body_node, :build, :universal?) do next if @formula_name == "wine" problem "macOS has been 64-bit only since 10.6 so build.universal? is deprecated." @@ -239,24 +320,6 @@ module RuboCop problem 'Use "depends_on :x11" instead of "ENV.x11"' end - find_every_method_call_by_name(body_node, :assert).each do |method| - if method_called_ever?(method, :include?) && !method_called_ever?(method, :!) - problem "Use `assert_match` instead of `assert ...include?`" - end - - if method_called_ever?(method, :exist?) && !method_called_ever?(method, :!) - problem "Use `assert_predicate , :exist?` instead of `#{method.source}`" - end - - if method_called_ever?(method, :exist?) && method_called_ever?(method, :!) - problem "Use `refute_predicate , :exist?` instead of `#{method.source}`" - end - - if method_called_ever?(method, :executable?) && !method_called_ever?(method, :!) - problem "Use `assert_predicate , :executable?` instead of `#{method.source}`" - end - end - find_every_method_call_by_name(body_node, :depends_on).each do |method| next unless method_called?(method, :new) problem "`depends_on` can take requirement classes instead of instances" @@ -282,61 +345,6 @@ module RuboCop next unless match = regex_match_group(param, fileutils_methods) problem "Use the `#{match}` Ruby method instead of `#{method.source}`" end - - if find_method_def(@processed_source.ast) - problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level" - end - - find_instance_method_call(body_node, :build, :without?) do |method| - next unless unless_modifier?(method.parent) - correct = method.source.gsub("out?", "?") - problem "Use if #{correct} instead of unless #{method.source}" - end - - find_instance_method_call(body_node, :build, :with?) do |method| - next unless unless_modifier?(method.parent) - correct = method.source.gsub("?", "out?") - problem "Use if #{correct} instead of unless #{method.source}" - end - - find_instance_method_call(body_node, :build, :with?) do |method| - next unless negated?(method.parent) - problem "Don't negate 'build.with?': use 'build.without?'" - end - - find_instance_method_call(body_node, :build, :without?) do |method| - next unless negated?(method.parent) - problem "Don't negate 'build.without?': use 'build.with?'" - end - - find_instance_method_call(body_node, :build, :without?) do |method| - arg = parameters(method).first - next unless match = regex_match_group(arg, /-?-?without-(.*)/) - problem "Don't duplicate 'without': Use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\"" - end - - find_instance_method_call(body_node, :build, :with?) do |method| - arg = parameters(method).first - next unless match = regex_match_group(arg, /-?-?with-(.*)/) - problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\"" - end - - find_instance_method_call(body_node, :build, :include?) do |method| - arg = parameters(method).first - next unless match = regex_match_group(arg, /with(out)?-(.*)/) - problem "Use build.with#{match[1]}? \"#{match[2]}\" instead of build.include? 'with#{match[1]}-#{match[2]}'" - end - - find_instance_method_call(body_node, :build, :include?) do |method| - arg = parameters(method).first - next unless match = regex_match_group(arg, /\-\-(.*)/) - problem "Reference '#{match[1]}' without dashes" - end - end - - def unless_modifier?(node) - return false unless node.if_type? - node.modifier_form? && node.unless? end def modifier?(node) diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index df4085721..9705e8278 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -7,7 +7,7 @@ describe RuboCop::Cop::FormulaAudit::Lines do subject(:cop) { described_class.new } context "When auditing lines" do - it "with correctable deprecated dependencies" do + it "correctable deprecated dependencies usage" do formulae = [{ "dependency" => :automake, "correct" => "automake", @@ -36,11 +36,11 @@ describe RuboCop::Cop::FormulaAudit::Lines do else offense = ":#{formula["dependency"]} is deprecated" end - expected_offenses = [{ message: offense, - severity: :convention, - line: 3, - column: 2, - source: source }] + expected_offenses = [{ message: offense, + severity: :convention, + line: 3, + column: 2, + source: source }] inspect_source(source) @@ -56,7 +56,7 @@ describe RuboCop::Cop::FormulaAudit::ClassInheritance do subject(:cop) { described_class.new } context "When auditing lines" do - it "with no space in class inheritance" do + it "inconsistent space in class inheritance" do source = <<-EOS.undent class Foo do |s|\" is preferred over \"|longvar|\".", - severity: :convention, - line: 4, - column: 2, - source: source }] + expected_offenses = [{ message: 'Use `assert_predicate , :exist?` instead of `assert File.exist? "default.ini"`', + severity: :convention, + line: 4, + column: 9, + source: source }] - inspect_source(source) + inspect_source(source) - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) end + end - it "with invalid rebuild" do - source = <<-EOS.undent + it "assert ...exist? with a negation" do + source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - bottle do - rebuild 0 - sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra - end + assert !File.exist?("default.ini") end - EOS + EOS - expected_offenses = [{ message: "'rebuild 0' should be removed", - severity: :convention, - line: 5, - column: 4, - source: source }] + expected_offenses = [{ message: 'Use `refute_predicate , :exist?` instead of `assert !File.exist?("default.ini")`', + severity: :convention, + line: 4, + column: 9, + source: source }] - inspect_source(source) + inspect_source(source) - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) end + end - it "with OS.linux? check" do - source = <<-EOS.undent + it "assert ...executable? without a negation" do + source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - bottle do - if OS.linux? - nil - end - sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra - end + assert File.executable? f end - EOS + EOS - expected_offenses = [{ message: "Don't use OS.linux?; Homebrew/core only supports macOS", - severity: :convention, - line: 5, - column: 7, - source: source }] + expected_offenses = [{ message: "Use `assert_predicate , :executable?` instead of `assert File.executable? f`", + severity: :convention, + line: 4, + column: 9, + source: source }] - inspect_source(source, "/homebrew-core/") + inspect_source(source) - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) end + end +end - it "with fails_with :llvm" do - source = <<-EOS.undent +describe RuboCop::Cop::FormulaAudit::OptionDeclarations do + subject(:cop) { described_class.new } + + it "unless build.without? conditional" do + source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - bottle do - sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra - end - fails_with :llvm do - build 2335 - cause "foo" + def post_install + return unless build.without? "bar" end end - EOS + EOS - expected_offenses = [{ message: "'fails_with :llvm' is now a no-op so should be removed", - severity: :convention, - line: 7, - column: 2, - source: source }] + expected_offenses = [{ message: 'Use if build.with? "bar" instead of unless build.without? "bar"', + severity: :convention, + line: 5, + column: 18, + source: source }] - inspect_source(source) + inspect_source(source) - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) end + end - it "with def test" do - source = <<-EOS.undent + it "unless build.with? conditional" do + source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - - def test - assert_equals "1", "1" + def post_install + return unless build.with? "bar" end end - EOS + EOS - expected_offenses = [{ message: "Use new-style test definitions (test do)", - severity: :convention, - line: 5, - column: 2, - source: source }] + expected_offenses = [{ message: 'Use if build.without? "bar" instead of unless build.with? "bar"', + severity: :convention, + line: 5, + column: 18, + source: source }] - inspect_source(source) + inspect_source(source) - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) end + end - it "with def options" do - source = <<-EOS.undent + it "negated build.with? conditional" do + source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - - def options - [["--bar", "desc"]] + def post_install + return if !build.with? "bar" end end - EOS + EOS - expected_offenses = [{ message: "Use new-style option definitions", - severity: :convention, - line: 5, - column: 2, - source: source }] + expected_offenses = [{ message: "Don't negate 'build.with?': use 'build.without?'", + severity: :convention, + line: 5, + column: 14, + source: source }] - inspect_source(source) + inspect_source(source) - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) end + end - it "with deprecated skip_clean call" do - source = <<-EOS.undent + it "negated build.without? conditional" do + source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - skip_clean :all + def post_install + return if !build.without? "bar" + end end - EOS + EOS - expected_offenses = [{ message: <<-EOS.undent.chomp, - `skip_clean :all` is deprecated; brew no longer strips symbols - Pass explicit paths to prevent Homebrew from removing empty folders. - EOS - severity: :convention, - line: 4, - column: 2, - source: source }] + expected_offenses = [{ message: "Don't negate 'build.without?': use 'build.with?'", + severity: :convention, + line: 5, + column: 14, + source: source }] - inspect_source(source) + inspect_source(source) - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) end + end - it "with build.universal?" do - source = <<-EOS.undent + it "unnecessary build.without? conditional" do + source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - if build.universal? - "foo" + def post_install + return if build.without? "--without-bar" end end - EOS + EOS - expected_offenses = [{ message: "macOS has been 64-bit only since 10.6 so build.universal? is deprecated.", - severity: :convention, - line: 4, - column: 5, - source: source }] + expected_offenses = [{ message: "Don't duplicate 'without': Use `build.without? \"bar\"` to check for \"--without-bar\"", + severity: :convention, + line: 5, + column: 30, + source: source }] - inspect_source(source) + inspect_source(source) - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) end + end - it "with build.universal? exempted formula" do - source = <<-EOS.undent - class Wine < Formula + it "unnecessary build.with? conditional" do + source = <<-EOS.undent + class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - if build.universal? - "foo" + def post_install + return if build.with? "--with-bar" end end - EOS + EOS - inspect_source(source, "/homebrew-core/Formula/wine.rb") - expect(cop.offenses).to eq([]) + expected_offenses = [{ message: "Don't duplicate 'with': Use `build.with? \"bar\"` to check for \"--with-bar\"", + severity: :convention, + line: 5, + column: 27, + source: source }] + + inspect_source(source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) end + end - it "with ENV.universal_binary" do - source = <<-EOS.undent + it "build.include? conditional" do + source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - if build? - ENV.universal_binary + def post_install + return if build.include? "without-bar" end end - EOS + EOS - expected_offenses = [{ message: "macOS has been 64-bit only since 10.6 so ENV.universal_binary is deprecated.", - severity: :convention, - line: 5, - column: 5, - source: source }] + expected_offenses = [{ message: "Use build.without? \"bar\" instead of build.include? 'without-bar'", + severity: :convention, + line: 5, + column: 30, + source: source }] - inspect_source(source) + inspect_source(source) - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) end + end - it "with ENV.universal_binary 2" do - source = <<-EOS.undent + it "build.include? with dashed args conditional" do + source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - if build? - ENV.x11 + def post_install + return if build.include? "--bar" end end - EOS + EOS - expected_offenses = [{ message: 'Use "depends_on :x11" instead of "ENV.x11"', - severity: :convention, - line: 5, - column: 5, - source: source }] + expected_offenses = [{ message: "Reference 'bar' without dashes", + severity: :convention, + line: 5, + column: 30, + source: source }] - inspect_source(source) + inspect_source(source) - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) end + end - it "with ruby-macho alternatives" do - source = <<-EOS.undent + it "def options usage" do + source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - system "install_name_tool", "-id" + + def options + [["--bar", "desc"]] + end end - EOS + EOS - expected_offenses = [{ message: 'Use ruby-macho instead of calling "install_name_tool"', - severity: :convention, - line: 4, - column: 10, - source: source }] + expected_offenses = [{ message: "Use new-style option definitions", + severity: :convention, + line: 5, + column: 2, + source: source }] - inspect_source(source) + inspect_source(source) - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) end + end +end - it "with ruby-macho alternatives audit exempted formula" do - source = <<-EOS.undent - class Cctools < Formula - desc "foo" - url 'http://example.com/foo-1.0.tgz' - system "install_name_tool", "-id" - end - EOS - - inspect_source(source, "/homebrew-core/Formula/cctools.rb") - expect(cop.offenses).to eq([]) - end +describe RuboCop::Cop::FormulaAudit::Miscellaneous do + subject(:cop) { described_class.new } - it "with npm install without language::Node args" do + context "When auditing formula" do + it "FileUtils usage" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - system "npm", "install" + FileUtils.mv "hello" end EOS - expected_offenses = [{ message: "Use Language::Node for npm install args", - severity: :convention, - line: 4, - column: 2, - source: source }] + expected_offenses = [{ message: "Don't need 'FileUtils.' before mv", + severity: :convention, + line: 4, + column: 2, + source: source }] inspect_source(source) @@ -500,33 +490,22 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with npm install without language::Node args in kibana" do - source = <<-EOS.undent - class KibanaAT44 < Formula - desc "foo" - url 'http://example.com/foo-1.0.tgz' - system "npm", "install" - end - EOS - - inspect_source(source, "/homebrew-core/Formula/kibana@4.4.rb") - expect(cop.offenses).to eq([]) - end - - it "with assert include" do + it "long inreplace block vars" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - assert File.read("inbox").include?("Sample message 1") + inreplace "foo" do |longvar| + somerandomCall(longvar) + end end EOS - expected_offenses = [{ message: "Use `assert_match` instead of `assert ...include?`", - severity: :convention, - line: 4, - column: 9, - source: source }] + expected_offenses = [{ message: "\"inreplace do |s|\" is preferred over \"|longvar|\".", + severity: :convention, + line: 4, + column: 2, + source: source }] inspect_source(source) @@ -535,20 +514,23 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "assert ...exist? without a negation" do + it "invalid rebuild statement" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - assert File.exist? "default.ini" + bottle do + rebuild 0 + sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra + end end EOS - expected_offenses = [{ message: 'Use `assert_predicate , :exist?` instead of `assert File.exist? "default.ini"`', - severity: :convention, - line: 4, - column: 9, - source: source }] + expected_offenses = [{ message: "'rebuild 0' should be removed", + severity: :convention, + line: 5, + column: 4, + source: source }] inspect_source(source) @@ -557,42 +539,53 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "assert ...exist? with a negation" do + it "OS.linux? check" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - assert !File.exist?("default.ini") + bottle do + if OS.linux? + nil + end + sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra + end end EOS - expected_offenses = [{ message: 'Use `refute_predicate , :exist?` instead of `assert !File.exist?("default.ini")`', - severity: :convention, - line: 4, - column: 9, - source: source }] + expected_offenses = [{ message: "Don't use OS.linux?; Homebrew/core only supports macOS", + severity: :convention, + line: 5, + column: 7, + source: source }] - inspect_source(source) + inspect_source(source, "/homebrew-core/") expected_offenses.zip(cop.offenses).each do |expected, actual| expect_offense(expected, actual) end end - it "assert ...executable? without a negation" do + it "fails_with :llvm block" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - assert File.executable? f + bottle do + sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra + end + fails_with :llvm do + build 2335 + cause "foo" + end end EOS - expected_offenses = [{ message: "Use `assert_predicate , :executable?` instead of `assert File.executable? f`", - severity: :convention, - line: 4, - column: 9, - source: source }] + expected_offenses = [{ message: "'fails_with :llvm' is now a no-op so should be removed", + severity: :convention, + line: 7, + column: 2, + source: source }] inspect_source(source) @@ -601,20 +594,23 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "depends_on with an instance as an argument" do + it "def test deprecated usage" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - depends_on FOO::BAR.new + + def test + assert_equals "1", "1" + end end EOS - expected_offenses = [{ message: "`depends_on` can take requirement classes instead of instances", - severity: :convention, - line: 4, - column: 13, - source: source }] + expected_offenses = [{ message: "Use new-style test definitions (test do)", + severity: :convention, + line: 5, + column: 2, + source: source }] inspect_source(source) @@ -623,20 +619,23 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with old style OS check" do + it "deprecated skip_clean call" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - depends_on :foo if MacOS.snow_leopard? + skip_clean :all end EOS - expected_offenses = [{ message: "\"MacOS.snow_leopard?\" is deprecated, use a comparison to MacOS.version instead", - severity: :convention, - line: 4, - column: 21, - source: source }] + expected_offenses = [{ message: <<-EOS.undent.chomp, + `skip_clean :all` is deprecated; brew no longer strips symbols + Pass explicit paths to prevent Homebrew from removing empty folders. + EOS + severity: :convention, + line: 4, + column: 2, + source: source }] inspect_source(source) @@ -645,21 +644,22 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with non glob DIR" do + it "build.universal? deprecated usage" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - rm_rf Dir["src/{llvm,test,librustdoc,etc/snapshot.pyc}"] - rm_rf Dir["src/snapshot.pyc"] + if build.universal? + "foo" + end end EOS - expected_offenses = [{ message: "Dir([\"src/snapshot.pyc\"]) is unnecessary; just use \"src/snapshot.pyc\"", - severity: :convention, - line: 5, - column: 13, - source: source }] + expected_offenses = [{ message: "macOS has been 64-bit only since 10.6 so build.universal? is deprecated.", + severity: :convention, + line: 4, + column: 5, + source: source }] inspect_source(source) @@ -668,44 +668,37 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with system call to fileUtils Method" do + it "build.universal? deprecation exempted formula" do source = <<-EOS.undent - class Foo < Formula + class Wine < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - system "mkdir", "foo" + if build.universal? + "foo" + end end EOS - expected_offenses = [{ message: "Use the `mkdir` Ruby method instead of `system \"mkdir\", \"foo\"`", - severity: :convention, - line: 4, - column: 10, - source: source }] - - inspect_source(source) - - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end + inspect_source(source, "/homebrew-core/Formula/wine.rb") + expect(cop.offenses).to eq([]) end - it "with a top-level function def " do + it "deprecated ENV.universal_binary usage" do source = <<-EOS.undent - def test - nil - end class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' + if build? + ENV.universal_binary + end end EOS - expected_offenses = [{ message: "Define method test in the class body, not at the top-level", - severity: :convention, - line: 1, - column: 0, - source: source }] + expected_offenses = [{ message: "macOS has been 64-bit only since 10.6 so ENV.universal_binary is deprecated.", + severity: :convention, + line: 5, + column: 5, + source: source }] inspect_source(source) @@ -714,22 +707,22 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with unless build.without?" do + it "deprecated ENV.x11 usage" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - def post_install - return unless build.without? "bar" + if build? + ENV.x11 end end EOS - expected_offenses = [{ message: 'Use if build.with? "bar" instead of unless build.without? "bar"', - severity: :convention, - line: 5, - column: 18, - source: source }] + expected_offenses = [{ message: 'Use "depends_on :x11" instead of "ENV.x11"', + severity: :convention, + line: 5, + column: 5, + source: source }] inspect_source(source) @@ -738,22 +731,20 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with unless build.with?" do + it "ruby-macho alternative to install_name_tool usage" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - def post_install - return unless build.with? "bar" - end + system "install_name_tool", "-id" end EOS - expected_offenses = [{ message: 'Use if build.without? "bar" instead of unless build.with? "bar"', - severity: :convention, - line: 5, - column: 18, - source: source }] + expected_offenses = [{ message: 'Use ruby-macho instead of calling "install_name_tool"', + severity: :convention, + line: 4, + column: 10, + source: source }] inspect_source(source) @@ -762,22 +753,33 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with negated build.with?" do + it "ruby-macho alternatives audit exempted formula" do + source = <<-EOS.undent + class Cctools < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + system "install_name_tool", "-id" + end + EOS + + inspect_source(source, "/homebrew-core/Formula/cctools.rb") + expect(cop.offenses).to eq([]) + end + + it "npm install without language::Node args" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - def post_install - return if !build.with? "bar" - end + system "npm", "install" end EOS - expected_offenses = [{ message: "Don't negate 'build.with?': use 'build.without?'", - severity: :convention, - line: 5, - column: 14, - source: source }] + expected_offenses = [{ message: "Use Language::Node for npm install args", + severity: :convention, + line: 4, + column: 2, + source: source }] inspect_source(source) @@ -786,22 +788,33 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with negated build.with?" do + it "npm install without language::Node args in kibana(exempted formula)" do + source = <<-EOS.undent + class KibanaAT44 < Formula + desc "foo" + url 'http://example.com/foo-1.0.tgz' + system "npm", "install" + end + EOS + + inspect_source(source, "/homebrew-core/Formula/kibana@4.4.rb") + expect(cop.offenses).to eq([]) + end + + it "depends_on with an instance as argument" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - def post_install - return if !build.without? "bar" - end + depends_on FOO::BAR.new end EOS - expected_offenses = [{ message: "Don't negate 'build.without?': use 'build.with?'", - severity: :convention, - line: 5, - column: 14, - source: source }] + expected_offenses = [{ message: "`depends_on` can take requirement classes instead of instances", + severity: :convention, + line: 4, + column: 13, + source: source }] inspect_source(source) @@ -810,22 +823,20 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with duplicated build.without?" do + it "old style OS check" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - def post_install - return if build.without? "--without-bar" - end + depends_on :foo if MacOS.snow_leopard? end EOS - expected_offenses = [{ message: "Don't duplicate 'without': Use `build.without? \"bar\"` to check for \"--without-bar\"", - severity: :convention, - line: 5, - column: 30, - source: source }] + expected_offenses = [{ message: "\"MacOS.snow_leopard?\" is deprecated, use a comparison to MacOS.version instead", + severity: :convention, + line: 4, + column: 21, + source: source }] inspect_source(source) @@ -834,22 +845,21 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with duplicated build.with?" do + it "non glob DIR usage" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - def post_install - return if build.with? "--with-bar" - end + rm_rf Dir["src/{llvm,test,librustdoc,etc/snapshot.pyc}"] + rm_rf Dir["src/snapshot.pyc"] end EOS - expected_offenses = [{ message: "Don't duplicate 'with': Use `build.with? \"bar\"` to check for \"--with-bar\"", - severity: :convention, - line: 5, - column: 27, - source: source }] + expected_offenses = [{ message: 'Dir(["src/snapshot.pyc"]) is unnecessary; just use "src/snapshot.pyc"', + severity: :convention, + line: 5, + column: 13, + source: source }] inspect_source(source) @@ -858,22 +868,20 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with build.include?" do + it "system call to fileUtils Method" do source = <<-EOS.undent class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - def post_install - return if build.include? "without-bar" - end + system "mkdir", "foo" end EOS - expected_offenses = [{ message: "Use build.without? \"bar\" instead of build.include? 'without-bar'", - severity: :convention, - line: 5, - column: 30, - source: source }] + expected_offenses = [{ message: 'Use the `mkdir` Ruby method instead of `system "mkdir", "foo"`', + severity: :convention, + line: 4, + column: 10, + source: source }] inspect_source(source) @@ -882,22 +890,22 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with build.include? with dashed args" do + it "top-level function def outside class body" do source = <<-EOS.undent + def test + nil + end class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - def post_install - return if build.include? "--bar" - end end EOS - expected_offenses = [{ message: "Reference 'bar' without dashes", - severity: :convention, - line: 5, - column: 30, - source: source }] + expected_offenses = [{ message: "Define method test in the class body, not at the top-level", + severity: :convention, + line: 1, + column: 0, + source: source }] inspect_source(source) @@ -906,7 +914,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with using ARGV to check options" do + it "Using ARGV to check options" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -917,11 +925,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "Use build instead of ARGV to check options", - severity: :convention, - line: 5, - column: 14, - source: source }] + expected_offenses = [{ message: "Use build instead of ARGV to check options", + severity: :convention, + line: 5, + column: 14, + source: source }] inspect_source(source) @@ -930,7 +938,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with man+ " do + it 'man+"man8" usage' do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -941,11 +949,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "\"man+\"man8\"\" should be \"man8\"", - severity: :convention, - line: 5, - column: 22, - source: source }] + expected_offenses = [{ message: '"man+"man8"" should be "man8"', + severity: :convention, + line: 5, + column: 22, + source: source }] inspect_source(source) @@ -954,7 +962,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with hardcoded compiler 1 " do + it "hardcoded gcc compiler" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -965,11 +973,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "Use \"\#{ENV.cc}\" instead of hard-coding \"gcc\"", - severity: :convention, - line: 5, - column: 12, - source: source }] + expected_offenses = [{ message: "Use \"\#{ENV.cc}\" instead of hard-coding \"gcc\"", + severity: :convention, + line: 5, + column: 12, + source: source }] inspect_source(source) @@ -978,7 +986,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with hardcoded compiler 2 " do + it "hardcoded g++ compiler" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -989,11 +997,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "Use \"\#{ENV.cxx}\" instead of hard-coding \"g++\"", - severity: :convention, - line: 5, - column: 12, - source: source }] + expected_offenses = [{ message: "Use \"\#{ENV.cxx}\" instead of hard-coding \"g++\"", + severity: :convention, + line: 5, + column: 12, + source: source }] inspect_source(source) @@ -1002,7 +1010,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with hardcoded compiler 3 " do + it "hardcoded llvm-g++ compiler" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1013,11 +1021,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "Use \"\#{ENV.cxx}\" instead of hard-coding \"llvm-g++\"", - severity: :convention, - line: 5, - column: 28, - source: source }] + expected_offenses = [{ message: "Use \"\#{ENV.cxx}\" instead of hard-coding \"llvm-g++\"", + severity: :convention, + line: 5, + column: 28, + source: source }] inspect_source(source) @@ -1026,7 +1034,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with hardcoded compiler 4 " do + it "hardcoded gcc compiler" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1037,11 +1045,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "Use \"\#{ENV.cc}\" instead of hard-coding \"gcc\"", - severity: :convention, - line: 5, - column: 28, - source: source }] + expected_offenses = [{ message: "Use \"\#{ENV.cc}\" instead of hard-coding \"gcc\"", + severity: :convention, + line: 5, + column: 28, + source: source }] inspect_source(source) @@ -1050,7 +1058,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with formula path shortcut long form" do + it "formula path shortcut : man" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1061,11 +1069,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "\"\#\{share}/man\" should be \"\#{man}\"", - severity: :convention, - line: 5, - column: 17, - source: source }] + expected_offenses = [{ message: '"#{share}/man" should be "#{man}"', + severity: :convention, + line: 5, + column: 17, + source: source }] inspect_source(source) @@ -1074,7 +1082,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with formula path shortcut long form 1" do + it "formula path shortcut : libexec" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1085,11 +1093,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "\"\#\{prefix}/libexec\" should be \"\#{libexec}\"", - severity: :convention, - line: 5, - column: 18, - source: source }] + expected_offenses = [{ message: "\"\#\{prefix}/libexec\" should be \"\#{libexec}\"", + severity: :convention, + line: 5, + column: 18, + source: source }] inspect_source(source) @@ -1098,7 +1106,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with formula path shortcut long form 2" do + it "formula path shortcut : info" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1109,11 +1117,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "\"\#\{prefix}/share/info\" should be \"\#{info}\"", - severity: :convention, - line: 5, - column: 47, - source: source }] + expected_offenses = [{ message: "\"\#\{prefix}/share/info\" should be \"\#{info}\"", + severity: :convention, + line: 5, + column: 47, + source: source }] inspect_source(source) @@ -1122,7 +1130,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with formula path shortcut long form 3" do + it "formula path shortcut : man8" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1133,11 +1141,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "\"\#\{prefix}/share/man/man8\" should be \"\#{man8}\"", - severity: :convention, - line: 5, - column: 46, - source: source }] + expected_offenses = [{ message: "\"\#\{prefix}/share/man/man8\" should be \"\#{man8}\"", + severity: :convention, + line: 5, + column: 46, + source: source }] inspect_source(source) @@ -1146,7 +1154,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with dependecies which have to vendored" do + it "dependecies which have to vendored" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1155,11 +1163,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "lua modules should be vendored rather than use deprecated depends_on \"lpeg\" => :lua51`", - severity: :convention, - line: 4, - column: 24, - source: source }] + expected_offenses = [{ message: "lua modules should be vendored rather than use deprecated depends_on \"lpeg\" => :lua51`", + severity: :convention, + line: 4, + column: 24, + source: source }] inspect_source(source) @@ -1168,7 +1176,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with setting env manually" do + it "manually setting env" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1177,11 +1185,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "Use ENV instead of invoking 'export' to modify the environment", - severity: :convention, - line: 4, - column: 10, - source: source }] + expected_offenses = [{ message: "Use ENV instead of invoking 'export' to modify the environment", + severity: :convention, + line: 4, + column: 10, + source: source }] inspect_source(source) @@ -1190,7 +1198,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with dependencies with invalid options" do + it "dependencies with invalid options" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1199,11 +1207,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "Dependency foo should not use option with-bar", - severity: :convention, - line: 4, - column: 13, - source: source }] + expected_offenses = [{ message: "Dependency foo should not use option with-bar", + severity: :convention, + line: 4, + column: 13, + source: source }] inspect_source(source) @@ -1212,7 +1220,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with inspecting version" do + it "inspecting version manually" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1223,11 +1231,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "Use 'build.head?' instead of inspecting 'version'", - severity: :convention, - line: 4, - column: 5, - source: source }] + expected_offenses = [{ message: "Use 'build.head?' instead of inspecting 'version'", + severity: :convention, + line: 4, + column: 5, + source: source }] inspect_source(source) @@ -1236,7 +1244,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with ENV.fortran" do + it "deprecated ENV.fortran usage" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1247,11 +1255,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "Use `depends_on :fortran` instead of `ENV.fortran`", - severity: :convention, - line: 5, - column: 4, - source: source }] + expected_offenses = [{ message: "Use `depends_on :fortran` instead of `ENV.fortran`", + severity: :convention, + line: 5, + column: 4, + source: source }] inspect_source(source) @@ -1260,7 +1268,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with ARGV.include? (--HEAD)" do + it "deprecated ARGV.include? (--HEAD) usage" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1271,11 +1279,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "Use \"if build.head?\" instead", - severity: :convention, - line: 5, - column: 26, - source: source }] + expected_offenses = [{ message: 'Use "if build.head?" instead', + severity: :convention, + line: 5, + column: 26, + source: source }] inspect_source(source) @@ -1284,7 +1292,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with MACOS_VERSION const" do + it "deprecated MACOS_VERSION const usage" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1295,11 +1303,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: "Use MacOS.version instead of MACOS_VERSION", - severity: :convention, - line: 5, - column: 14, - source: source }] + expected_offenses = [{ message: "Use MacOS.version instead of MACOS_VERSION", + severity: :convention, + line: 5, + column: 14, + source: source }] inspect_source(source) @@ -1308,7 +1316,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with if conditional dep" do + it "deprecated if build.with? conditional dependency" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1317,11 +1325,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: 'Replace depends_on "foo" if build.with? "with-foo" with depends_on "foo" => :optional', - severity: :convention, - line: 4, - column: 2, - source: source }] + expected_offenses = [{ message: 'Replace depends_on "foo" if build.with? "with-foo" with depends_on "foo" => :optional', + severity: :convention, + line: 4, + column: 2, + source: source }] inspect_source(source) @@ -1330,7 +1338,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with unless conditional dep and symbol" do + it "unless conditional dependency with build.without?" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1339,11 +1347,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: 'Replace depends_on :foo unless build.without? "foo" with depends_on :foo => :recommended', - severity: :convention, - line: 4, - column: 2, - source: source }] + expected_offenses = [{ message: 'Replace depends_on :foo unless build.without? "foo" with depends_on :foo => :recommended', + severity: :convention, + line: 4, + column: 2, + source: source }] inspect_source(source) @@ -1352,7 +1360,7 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end end - it "with unless conditional dep with build.include?" do + it "unless conditional dependency with build.include?" do source = <<-EOS.undent class Foo < Formula desc "foo" @@ -1361,11 +1369,11 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end EOS - expected_offenses = [{ message: 'Replace depends_on :foo unless build.include? "without-foo" with depends_on :foo => :recommended', - severity: :convention, - line: 4, - column: 2, - source: source }] + expected_offenses = [{ message: 'Replace depends_on :foo unless build.include? "without-foo" with depends_on :foo => :recommended', + severity: :convention, + line: 4, + column: 2, + source: source }] inspect_source(source) -- cgit v1.2.3