Class: RuboCop::Cop::Style::DisableCopsWithinSourceCodeDirective
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
::RuboCop::Cop::AutoCorrector,
::RuboCop::Cop::Base,
::RuboCop::ExcludeLimit,
NodePattern::Macros,
RuboCop::AST::Sexp
|
|
|
Instance Chain:
self,
::RuboCop::Cop::Base,
::RuboCop::Cop::AutocorrectLogic,
::RuboCop::Cop::IgnoredNode,
::RuboCop::Util,
RuboCop::AST::Sexp
|
|
| Inherits: |
RuboCop::Cop::Base
|
| Defined in: | lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb |
Overview
Detects comments to enable/disable RuboCop. This is useful if you 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.
AllowedCops and DisallowedCops accept cop names and department names
alike. Listing a cop does not cover its whole department: a directive
disabling ::RuboCop::Cop::Metrics is broader than one disabling Metrics/AbcSize.
Alternatively, specific cops can be disallowed with the DisallowedCops
configuration. When DisallowedCops is set, only directives for the listed
cops (and all) will be flagged. This is useful when you want
to protect a small set of critical cops from being disabled rather than
allowlisting all other cops. AllowedCops and DisallowedCops should not
both be set at the same time; if DisallowedCops is set, it takes precedence.
AllowedDirectives names directive forms - disable, todo,
disable-next, todo-next, push, next - and exempts them from the
cop entirely. rubocop:todo is the usual candidate, since
--disable-uncorrectable generates those and they record debt rather
than a decision someone should be asked to justify.
With AllowWithReason set to true, a disable directive carrying
a -- trailing justification comment is allowed, so a team can require
every disable to be documented instead of banning them outright. Enable
directives are not checked in this mode, since they end a suppression
rather than start one.
This cop cannot be disabled via directive comments when it is explicitly
enabled with Enabled: true. This prevents users from bypassing the cop
with # rubocop:disable Style/DisableCopsWithinSourceCodeDirective.
Constant Summary
-
MSG =
# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 96'RuboCop disable/enable directives are not permitted.' -
MSG_FOR_COPS =
# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 97'RuboCop disable/enable directives for %<cops>s are not permitted.' -
MSG_MISSING_REASON =
# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 98'RuboCop disable directives without a `--` justification ' \ 'comment are not permitted.'
::RuboCop::Cop::Base - Inherited
Class Attribute Summary
::RuboCop::Cop::AutoCorrector - Extended
::RuboCop::Cop::Base - Inherited
| .gem_requirements, .lint?, | |
| .support_autocorrect? | Returns if class supports autocorrect. |
| .support_multiple_source? | Override if your cop should be called repeatedly for multiple investigations Between calls to #on_new_investigation and |
Class Method Summary
::RuboCop::Cop::Base - Inherited
| .autocorrect_incompatible_with | List of cops that should not try to autocorrect at the same time as this cop. |
| .badge | Naming. |
| .callbacks_needed, .cop_name, .department, | |
| .documentation_url | Returns a url to view this cops documentation online. |
| .exclude_from_registry | Call for abstract Cop classes. |
| .inherited, | |
| .joining_forces | Override and return the Force class(es) you need to join. |
| .match? | Returns true if the cop name or the cop namespace matches any of the given names. |
| .new, | |
| .requires_gem | Register a version requirement for the given gem name. |
| .restrict_on_send | Reserved for Commissioner. |
::RuboCop::ExcludeLimit - Extended
| exclude_limit | Sets up a configuration option to have an exclude limit tracked. |
| transform | |
Instance Attribute Summary
- #allow_with_reason? ⇒ Boolean readonly private
- #any_cops_allowed? ⇒ Boolean readonly private
::RuboCop::Cop::Base - Inherited
| #active_support_extensions_enabled?, #always_autocorrect?, #config, #config_to_allow_offenses, #config_to_allow_offenses=, #contextual_autocorrect?, | |
| #preview? | Whether the user opted in to unstable behavior, with |
| #processed_source, #project_index, #string_literals_frozen_by_default?, #target_satisfies_all_gem_version_requirements? | |
::RuboCop::Cop::AutocorrectLogic - Included
| #autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #autocorrect_with_disable_uncorrectable?, #correctable?, #disable_uncorrectable?, #safe_autocorrect?, | |
| #skipped_unsafe_correction_with_disable_uncorrectable? | Whether a correction exists but is skipped because it is unsafe in a safe autocorrect run, while |
Instance Method Summary
- #on_new_investigation
- #allowed_cops private
- #allowed_directives private
- #compute_disallowed_cops(directive_cops) private
- #directive_cops(directive) private
- #disallowed_cops_config private
- #exempt_mode?(directive) ⇒ Boolean private
- #ignored?(directive) ⇒ Boolean private
-
#listed?(names, cop) ⇒ Boolean
private
A name matches either outright or through its department, so
::RuboCop::Cop::MetricscoversMetrics/AbcSizebut not the other way round. - #offense_message(disallowed_cops) private
- #register_offense(comment, directive_cops, disallowed_cops) private
::RuboCop::Cop::Base - Inherited
| #add_global_offense | Adds an offense that has no particular location. |
| #add_offense | Adds an offense on the specified range (or node with an expression) Unless that offense is disabled for this range, a corrector will be yielded to provide the cop the opportunity to autocorrect the offense. |
| #begin_investigation | Called before any investigation. |
| #callbacks_needed | — grouped under the Commissioner heading above. |
| #cop_config | Configuration Helpers. |
| #cop_name, #excluded_file?, | |
| #external_dependency_checksum | This method should be overridden when a cop’s behavior depends on state that lives outside of these locations: |
| #inspect, | |
| #message | Gets called if no message is specified when calling |
| #name | Alias for Base#cop_name. |
| #offenses, | |
| #on_investigation_end | Called after all on_… |
| #on_new_investigation | Called before all on_… |
| #on_other_file | Called instead of all on_… |
| #parse | There should be very limited reasons for a Cop to do it’s own parsing. |
| #parser_engine, | |
| #ready | Called between investigations. |
| #relevant_file?, | |
| #target_gem_version | Returns a gems locked versions (i.e. |
| #target_rails_version, #target_ruby_version, #annotate, #apply_correction, #attempt_correction, | |
| #callback_argument | Reserved for Cop::Cop. |
| #complete_investigation | Called to complete an investigation. |
| #correct, #covering_disabled_range, #current_corrector, | |
| #current_offense_locations | Reserved for Commissioner: |
| #current_offenses, #currently_disabled_lines, #custom_severity, #default_severity, #disable_uncorrectable, #enabled_line?, | |
| #enabled_lines? | A multi-line offense is suppressed by a directive on any line of its range, not only its first line, matching the intuition that the directive is attached to the offending code. |
| #file_name_matches_any?, #find_message, #find_severity, #matches_absolute_include_pattern?, #range_for_original, #range_from_node_or_range, | |
| #reset_investigation | Actually private methods. |
| #suppression_reason | The |
| #use_corrector | |
::RuboCop::Cop::AutocorrectLogic - Included
::RuboCop::Cop::IgnoredNode - Included
Constructor Details
This class inherits a constructor from RuboCop::Cop::Base
Instance Attribute Details
#allow_with_reason? ⇒ Boolean (readonly, private)
[ GitHub ]
# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 171
def allow_with_reason? cop_config['AllowWithReason'] end
#any_cops_allowed? ⇒ Boolean (readonly, private)
[ GitHub ]
# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 185
def any_cops_allowed? allowed_cops.any? end
Instance Method Details
#allowed_cops (private)
[ GitHub ]# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 175
def allowed_cops @allowed_cops ||= Array(cop_config['AllowedCops']).to_set end
#allowed_directives (private)
[ GitHub ]# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 167
def allowed_directives @allowed_directives ||= Array(cop_config['AllowedDirectives']) end
#compute_disallowed_cops(directive_cops) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 117
def compute_disallowed_cops(directive_cops) if disallowed_cops_config.any? if directive_cops.include?('all') directive_cops else directive_cops.uniq.select { |cop| listed?(disallowed_cops_config, cop) } end else directive_cops.reject { |cop| cop != 'all' && listed?(allowed_cops, cop) } end end
#directive_cops(directive) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 152
def directive_cops(directive) match_captures = directive.match_captures match_captures && match_captures[1] ? match_captures[1].split(',').map(&:strip) : [] end
#disallowed_cops_config (private)
[ GitHub ]# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 189
def disallowed_cops_config @disallowed_cops_config ||= Array(cop_config['DisallowedCops']).to_set end
#exempt_mode?(directive) ⇒ Boolean (private)
# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 163
def exempt_mode?(directive) allowed_directives.include?(directive.mode) end
#ignored?(directive) ⇒ Boolean (private)
# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 157
def ignored?(directive) return true if exempt_mode?(directive) allow_with_reason? && (directive.reason || directive.enabled?) end
#listed?(names, cop) ⇒ Boolean (private)
A name matches either outright or through its department, so
::RuboCop::Cop::Metrics covers Metrics/AbcSize but not the other way round.
# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 181
def listed?(names, cop) names.include?(cop) || names.include?(cop.split('/').first) end
#offense_message(disallowed_cops) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 142
def (disallowed_cops) if allow_with_reason? MSG_MISSING_REASON elsif any_cops_allowed? || disallowed_cops_config.any? format(MSG_FOR_COPS, cops: "`#{disallowed_cops.join('`, `')}`") else MSG end end
#on_new_investigation
[ GitHub ]# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 101
def on_new_investigation processed_source.comments.each do |comment| directive = DirectiveComment.new(comment) next if ignored?(directive) directive_cops = directive_cops(directive) disallowed_cops = compute_disallowed_cops(directive_cops) next unless disallowed_cops.any? register_offense(comment, directive_cops, disallowed_cops) end end
#register_offense(comment, directive_cops, disallowed_cops) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb', line 129
def register_offense(comment, directive_cops, disallowed_cops) add_offense(comment, message: (disallowed_cops)) 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