Skip to content

Commit

Permalink
cop to forbid enabling or disabling cops within source code
Browse files Browse the repository at this point in the history
  • Loading branch information
egze committed Apr 1, 2020
1 parent 51de04e commit 4a097d6
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -21,6 +21,7 @@
* [#7823](https://github.com/rubocop-hq/rubocop/pull/7823): Add `IgnoredMethods` configuration in `Metrics/AbcSize`, `Metrics/CyclomaticComplexity`, and `Metrics/PerceivedComplexity` cops. ([@drenmi][])
* [#7816](https://github.com/rubocop-hq/rubocop/pull/7816): Support Ruby 2.7's numbered parameter for `Style/Lambda`. ([@koic][])
* [#7829](https://github.com/rubocop-hq/rubocop/issues/7829): Fix an error for `Style/OneLineConditional` when one of the branches contains `next` keyword. ([@koic][])
* [#7384](https://github.com/rubocop-hq/rubocop/pull/7384): Add new `Style/DisableCopsWithinSourceCodeDirective` cop. ([@egze][])

### Bug fixes

Expand Down Expand Up @@ -4424,3 +4425,4 @@
[@nikitasakov]: https://github.com/nikitasakov
[@dmolesUC]: https://github.com/dmolesUC
[@yuritomanek]: https://github.com/yuritomanek
[@egze]: https://github.com/egze
6 changes: 6 additions & 0 deletions config/default.yml
Expand Up @@ -2616,6 +2616,12 @@ Style/Dir:
Enabled: true
VersionAdded: '0.50'

Style/DisableCopsWithinSourceCodeDirective:
Description: >-
Forbids disabling/enabling cops within source code.
Enabled: false
VersionAdded: '0.75'

Style/Documentation:
Description: 'Document classes and non-namespace modules.'
Enabled: true
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop.rb
Expand Up @@ -423,6 +423,7 @@
require_relative 'rubocop/cop/style/date_time'
require_relative 'rubocop/cop/style/def_with_parentheses'
require_relative 'rubocop/cop/style/dir'
require_relative 'rubocop/cop/style/disable_cops_within_source_code_directive'
require_relative 'rubocop/cop/style/documentation_method'
require_relative 'rubocop/cop/style/documentation'
require_relative 'rubocop/cop/style/double_cop_disable_directive'
Expand Down
49 changes: 49 additions & 0 deletions lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb
@@ -0,0 +1,49 @@
# frozen_string_literal: true

# rubocop:disable Lint/RedundantCopDisableDirective

module RuboCop
module Cop
module Style
# Detects comments to enable/disable RuboCop.
# This is useful if want to make sure that every RuboCop error gets fixed
# and not quickly disabled with a comment.
#
# @example
# # bad
# # rubocop:disable Metrics/AbcSize
# def f
# end
# # rubocop:enable Metrics/AbcSize
#
# # good
# def fixed_method_name_and_no_rubocop_comments
# end
#
class DisableCopsWithinSourceCodeDirective < Cop
# rubocop:enable Lint/RedundantCopDisableDirective
MSG = 'Comment to disable/enable RuboCop.'

def investigate(processed_source)
processed_source.comments.each do |comment|
next unless rubocop_directive_comment?(comment)

add_offense(comment)
end
end

def autocorrect(comment)
lambda do |corrector|
corrector.replace(comment.loc.expression, '')
end
end

private

def rubocop_directive_comment?(comment)
comment.text =~ CommentConfig::COMMENT_DIRECTIVE_REGEXP
end
end
end
end
end
1 change: 1 addition & 0 deletions manual/cops.md
Expand Up @@ -334,6 +334,7 @@ In the following section you find all available cops:
* [Style/DateTime](cops_style.md#styledatetime)
* [Style/DefWithParentheses](cops_style.md#styledefwithparentheses)
* [Style/Dir](cops_style.md#styledir)
* [Style/DisableCopsWithinSourceCodeDirective](cops_style.md#styledisablecopswithinsourcecodedirective)
* [Style/Documentation](cops_style.md#styledocumentation)
* [Style/DocumentationMethod](cops_style.md#styledocumentationmethod)
* [Style/DoubleCopDisableDirective](cops_style.md#styledoublecopdisabledirective)
Expand Down
24 changes: 24 additions & 0 deletions manual/cops_style.md
Expand Up @@ -1334,6 +1334,30 @@ path = File.dirname(File.realpath(__FILE__))
path = __dir__
```

## Style/DisableCopsWithinSourceCodeDirective

Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
--- | --- | --- | --- | ---
Disabled | Yes | Yes | 0.75 | -

Detects comments to enable/disable RuboCop.
This is useful if want to make sure that every RuboCop error gets fixed
and not quickly disabled with a comment.

### Examples

```ruby
# bad
# rubocop:disable Metrics/AbcSize
def f
end
# rubocop:enable Metrics/AbcSize

# good
def fixed_method_name_and_no_rubocop_comments
end
```

## Style/Documentation

Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
Expand Down
@@ -0,0 +1,29 @@
# frozen_string_literal: true

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

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.
end
RUBY
expect_correction(<<~RUBY)
def choose_move(who_to_move)
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.
end
RUBY
expect_correction(<<~RUBY)
def choose_move(who_to_move)
end
RUBY
end
end

0 comments on commit 4a097d6

Please sign in to comment.