diff options
| -rw-r--r-- | Library/.rubocop.yml | 3 | ||||
| -rw-r--r-- | Library/Homebrew/dev-cmd/audit.rb | 9 | ||||
| -rw-r--r-- | Library/Homebrew/rubocops.rb | 1 | ||||
| -rw-r--r-- | Library/Homebrew/rubocops/conflicts_cop.rb | 27 | ||||
| -rw-r--r-- | Library/Homebrew/rubocops/extend/formula_cop.rb | 10 | ||||
| -rw-r--r-- | Library/Homebrew/test/rubocops/conflicts_cop_spec.rb | 47 | 
6 files changed, 88 insertions, 9 deletions
diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml index dbff189ef..6bfb669fd 100644 --- a/Library/.rubocop.yml +++ b/Library/.rubocop.yml @@ -18,6 +18,9 @@ FormulaAudit/Checksum:  FormulaAudit/ChecksumCase:    Enabled: true +FormulaAudit/Conflicts: +  Enabled: true +  FormulaAuditStrict/BottleBlock:    Enabled: true diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index ff6b17b45..3bbfa461a 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -519,15 +519,6 @@ class FormulaAuditor          problem "Ambiguous conflicting formula #{c.name.inspect}."        end      end - -    versioned_conflicts_whitelist = %w[node@ bash-completion@].freeze - -    return unless formula.conflicts.any? && formula.versioned_formula? -    return if formula.name.start_with?(*versioned_conflicts_whitelist) -    problem <<-EOS -      Versioned formulae should not use `conflicts_with`. -      Use `keg_only :versioned_formula` instead. -    EOS    end    def audit_keg_only_style diff --git a/Library/Homebrew/rubocops.rb b/Library/Homebrew/rubocops.rb index e27f91867..81ea2fcf2 100644 --- a/Library/Homebrew/rubocops.rb +++ b/Library/Homebrew/rubocops.rb @@ -7,3 +7,4 @@ require_relative "./rubocops/text_cop"  require_relative "./rubocops/caveats_cop"  require_relative "./rubocops/checksum_cop"  require_relative "./rubocops/legacy_patches_cop" +require_relative "./rubocops/conflicts_cop" diff --git a/Library/Homebrew/rubocops/conflicts_cop.rb b/Library/Homebrew/rubocops/conflicts_cop.rb new file mode 100644 index 000000000..c1b801559 --- /dev/null +++ b/Library/Homebrew/rubocops/conflicts_cop.rb @@ -0,0 +1,27 @@ +require_relative "./extend/formula_cop" +require_relative "../extend/string" + +module RuboCop +  module Cop +    module FormulaAudit +      # This cop audits versioned Formulae for `conflicts_with` +      class Conflicts < FormulaCop +        MSG = <<-EOS.undent +          Versioned formulae should not use `conflicts_with`. +          Use `keg_only :versioned_formula` instead. +        EOS + +        WHITELIST = %w[ +          node@ +          bash-completion@ +        ].freeze + +        def audit_formula(_node, _class_node, _parent_class_node, body) +          return unless versioned_formula? +          problem MSG if !formula_file_name.start_with?(*WHITELIST) && +                         method_called_ever?(body, :conflicts_with) +        end +      end +    end +  end +end diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index 439fde6a5..ddfb507d2 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -344,6 +344,16 @@ module RuboCop          end        end +      # Returns true if the formula is versioned +      def versioned_formula? +        formula_file_name.include?("@") || @formula_name.match(/AT\d+/) +      end + +      # Returns filename of the formula without the extension +      def formula_file_name +        File.basename(processed_source.buffer.name, ".rb") +      end +        # Returns printable component name        def format_component(component_node)          return component_node.method_name if component_node.send_type? || component_node.block_type? diff --git a/Library/Homebrew/test/rubocops/conflicts_cop_spec.rb b/Library/Homebrew/test/rubocops/conflicts_cop_spec.rb new file mode 100644 index 000000000..c3175509a --- /dev/null +++ b/Library/Homebrew/test/rubocops/conflicts_cop_spec.rb @@ -0,0 +1,47 @@ +require "rubocop" +require "rubocop/rspec/support" +require_relative "../../extend/string" +require_relative "../../rubocops/conflicts_cop" + +describe RuboCop::Cop::FormulaAudit::Conflicts do +  subject(:cop) { described_class.new } + +  context "When auditing formula for conflicts with" do +    it "multiple conflicts_with" do +      source = <<-EOS.undent +        class FooAT20 < Formula +          url 'http://example.com/foo-2.0.tgz' +          conflicts_with "mysql", "mariadb", "percona-server", +                           :because => "both install plugins" +        end +      EOS + +      msg = <<-EOS.undent +            Versioned formulae should not use `conflicts_with`. +            Use `keg_only :versioned_formula` instead. +      EOS +      expected_offenses = [{  message: msg, +                              severity: :convention, +                              line: 3, +                              column: 2, +                              source: source }] + +      inspect_source(cop, source) + +      expected_offenses.zip(cop.offenses).each do |expected, actual| +        expect_offense(expected, actual) +      end +    end + +    it "no conflicts_with" do +      source = <<-EOS.undent +        class FooAT20 < Formula +          url 'http://example.com/foo-2.0.tgz' +          desc 'Bar' +        end +      EOS +      inspect_source(cop, source) +      expect(cop.offenses).to eq([]) +    end +  end +end  | 
