Skip to content

Commit

Permalink
[Fixes #9399] Added AllowedCops configuration to `Style/DisableCops…
Browse files Browse the repository at this point in the history
…WithinSourceCodeDirective`.
  • Loading branch information
dvandersluis authored and bbatsov committed Jan 26, 2021
1 parent 1de3a9f commit 052eb8a
Showing 4 changed files with 115 additions and 18 deletions.
1 change: 1 addition & 0 deletions changelog/change_added_allowedcops_configuration_to.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#9399](https://github.com/rubocop-hq/rubocop/issues/9399): Added `AllowedCops` configuration to `Style/DisableCopsWithinSourceCodeDirective`. ([@dvandersluis][])
2 changes: 2 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
@@ -3136,6 +3136,8 @@ Style/DisableCopsWithinSourceCodeDirective:
Forbids disabling/enabling cops within source code.
Enabled: false
VersionAdded: '0.82'
VersionChanged: <<next>>
AllowedCops: []

Style/DocumentDynamicEvalDefinition:
Description: >-
58 changes: 49 additions & 9 deletions lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb
Original file line number Diff line number Diff line change
@@ -9,37 +9,77 @@ module Style
# This is useful if want to make sure that every RuboCop error gets fixed
# and not quickly disabled with a comment.
#
# Specific cops can be allowed with the `AllowedCops` configuration. Note that
# if this configuration is set, `rubocop:disable all` is still disallowed.
#
# @example
# # bad
# # rubocop:disable Metrics/AbcSize
# def f
# def foo
# end
# # rubocop:enable Metrics/AbcSize
#
# # good
# def fixed_method_name_and_no_rubocop_comments
# def foo
# end
#
# @example AllowedCops: [Metrics/AbcSize]
# # good
# # rubocop:disable Metrics/AbcSize
# def foo
# end
# # rubocop:enable Metrics/AbcSize
#
class DisableCopsWithinSourceCodeDirective < Base
extend AutoCorrector

# rubocop:enable Lint/RedundantCopDisableDirective
MSG = 'Comment to disable/enable RuboCop.'
MSG = 'Rubocop disable/enable directives are not permitted.'
MSG_FOR_COPS = 'Rubocop disable/enable directives for %<cops>s are not permitted.'

def on_new_investigation
processed_source.comments.each do |comment|
next unless rubocop_directive_comment?(comment)
directive_cops = directive_cops(comment)
disallowed_cops = directive_cops - allowed_cops

add_offense(comment) do |corrector|
corrector.replace(comment, '')
end
next unless disallowed_cops.any?

register_offense(comment, directive_cops, disallowed_cops)
end
end

private

def rubocop_directive_comment?(comment)
CommentConfig::COMMENT_DIRECTIVE_REGEXP.match?(comment.text)
def register_offense(comment, directive_cops, disallowed_cops)
message = if any_cops_allowed?
format(MSG_FOR_COPS, cops: "`#{disallowed_cops.join('`, `')}`")
else
MSG
end

add_offense(comment, message: message) do |corrector|
replacement = ''

if directive_cops.length != disallowed_cops.length
replacement = comment.text.sub(/#{Regexp.union(disallowed_cops)},?\s*/, '')
.sub(/,\s*$/, '')
end

corrector.replace(comment, replacement)
end
end

def directive_cops(comment)
match = CommentConfig::COMMENT_DIRECTIVE_REGEXP.match(comment.text)
match[2] ? match[2].split(',').map(&:strip) : []
end

def allowed_cops
Array(cop_config['AllowedCops'])
end

def any_cops_allowed?
allowed_cops.any?
end
end
end
Original file line number Diff line number Diff line change
@@ -1,31 +1,85 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Style::DisableCopsWithinSourceCodeDirective do
subject(:cop) { described_class.new }

RSpec.describe RuboCop::Cop::Style::DisableCopsWithinSourceCodeDirective, :config do
it 'registers an offense for disabled cop within source code' do
expect_offense(<<~RUBY)
def choose_move(who_to_move)# rubocop:disable Metrics/CyclomaticComplexity
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Comment to disable/enable RuboCop.
def foo # rubocop:disable Metrics/CyclomaticComplexity
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Rubocop disable/enable directives are not permitted.
end
RUBY

expect_correction(<<~RUBY)
def choose_move(who_to_move)
def foo#{trailing_whitespace}
end
RUBY
end

it 'registers an offense for enabled cop within source code' do
expect_offense(<<~RUBY)
def choose_move(who_to_move)# rubocop:enable Metrics/CyclomaticComplexity
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Comment to disable/enable RuboCop.
def foo # rubocop:enable Metrics/CyclomaticComplexity
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Rubocop disable/enable directives are not permitted.
end
RUBY

expect_correction(<<~RUBY)
def foo#{trailing_whitespace}
end
RUBY
end

it 'registers an offense for disabling all cops' do
expect_offense(<<~RUBY)
def foo # rubocop:enable all
^^^^^^^^^^^^^^^^^^^^ Rubocop disable/enable directives are not permitted.
end
RUBY

expect_correction(<<~RUBY)
def choose_move(who_to_move)
def foo#{trailing_whitespace}
end
RUBY
end

context 'with AllowedCops' do
let(:cop_config) { { 'AllowedCops' => ['Metrics/CyclomaticComplexity', 'Metrics/AbcSize'] } }

context 'when an allowed cop is disabled' do
it 'does not register an offense' do
expect_no_offenses(<<~RUBY)
def foo # rubocop:disable Metrics/CyclomaticComplexity
end
RUBY
end
end

context 'when an non-allowed cop is disabled' do
it 'registers an offense and corrects' do
expect_offense(<<~RUBY)
def foo # rubocop:disable Layout/LineLength
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Rubocop disable/enable directives for `Layout/LineLength` are not permitted.
end
RUBY

expect_correction(<<~RUBY)
def foo#{trailing_whitespace}
end
RUBY
end
end

context 'when an mix of cops are disabled' do
it 'registers an offense and corrects' do
expect_offense(<<~RUBY)
def foo # rubocop:disable Metrics/AbcSize, Layout/LineLength, Metrics/CyclomaticComplexity, Style/AndOr
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Rubocop disable/enable directives for `Layout/LineLength`, `Style/AndOr` are not permitted.
end
RUBY

expect_correction(<<~RUBY)
def foo # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
end
RUBY
end
end
end
end

0 comments on commit 052eb8a

Please sign in to comment.