rubocop 0.73.0 → 0.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/bin/console +1 -0
- data/config/default.yml +332 -295
- data/lib/rubocop.rb +46 -30
- data/lib/rubocop/ast/builder.rb +1 -0
- data/lib/rubocop/ast/node.rb +6 -8
- data/lib/rubocop/ast/node/block_node.rb +2 -0
- data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +1 -12
- data/lib/rubocop/ast/node/return_node.rb +24 -0
- data/lib/rubocop/cli.rb +11 -227
- data/lib/rubocop/cli/command.rb +21 -0
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +105 -0
- data/lib/rubocop/cli/command/base.rb +33 -0
- data/lib/rubocop/cli/command/execute_runner.rb +76 -0
- data/lib/rubocop/cli/command/init_dotfile.rb +45 -0
- data/lib/rubocop/cli/command/show_cops.rb +73 -0
- data/lib/rubocop/cli/command/version.rb +17 -0
- data/lib/rubocop/cli/environment.rb +21 -0
- data/lib/rubocop/comment_config.rb +5 -4
- data/lib/rubocop/config.rb +28 -537
- data/lib/rubocop/config_loader.rb +21 -3
- data/lib/rubocop/config_loader_resolver.rb +4 -3
- data/lib/rubocop/config_obsoletion.rb +275 -0
- data/lib/rubocop/config_validator.rb +246 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
- data/lib/rubocop/cop/commissioner.rb +15 -7
- data/lib/rubocop/cop/cop.rb +33 -9
- data/lib/rubocop/cop/corrector.rb +8 -7
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +43 -17
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/space_corrector.rb +1 -2
- data/lib/rubocop/cop/generator.rb +3 -3
- data/lib/rubocop/cop/generator/configuration_injector.rb +9 -4
- data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +59 -0
- data/lib/rubocop/cop/layout/{align_arguments.rb → argument_alignment.rb} +1 -1
- data/lib/rubocop/cop/layout/{align_array.rb → array_alignment.rb} +1 -1
- data/lib/rubocop/cop/layout/{indent_assignment.rb → assignment_indentation.rb} +11 -2
- data/lib/rubocop/cop/layout/block_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/comment_indentation.rb +10 -13
- data/lib/rubocop/cop/layout/empty_comment.rb +7 -16
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +22 -7
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -2
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +2 -2
- data/lib/rubocop/cop/layout/end_of_line.rb +8 -3
- data/lib/rubocop/cop/layout/extra_spacing.rb +15 -60
- data/lib/rubocop/cop/layout/{indent_first_argument.rb → first_argument_indentation.rb} +12 -10
- data/lib/rubocop/cop/layout/{indent_first_array_element.rb → first_array_element_indentation.rb} +4 -4
- data/lib/rubocop/cop/layout/{indent_first_hash_element.rb → first_hash_element_indentation.rb} +4 -4
- data/lib/rubocop/cop/layout/{indent_first_parameter.rb → first_parameter_indentation.rb} +3 -3
- data/lib/rubocop/cop/layout/{align_hash.rb → hash_alignment.rb} +8 -4
- data/lib/rubocop/cop/layout/{indent_heredoc.rb → heredoc_indentation.rb} +2 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +19 -5
- data/lib/rubocop/cop/layout/{leading_blank_lines.rb → leading_empty_lines.rb} +1 -1
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +24 -2
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/{align_parameters.rb → parameter_alignment.rb} +1 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -0
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +5 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -0
- data/lib/rubocop/cop/layout/space_around_operators.rb +43 -24
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -7
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +8 -5
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +7 -0
- data/lib/rubocop/cop/layout/space_inside_parens.rb +6 -6
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +24 -40
- data/lib/rubocop/cop/layout/{trailing_blank_lines.rb → trailing_empty_lines.rb} +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +18 -2
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +17 -4
- data/lib/rubocop/cop/lint/debugger.rb +1 -3
- data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +1 -1
- data/lib/rubocop/cop/lint/{duplicated_key.rb → duplicate_hash_key.rb} +1 -1
- data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +61 -4
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +10 -36
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +2 -2
- data/lib/rubocop/cop/lint/{multiple_compare.rb → multiple_comparison.rb} +1 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/{unneeded_cop_disable_directive.rb → redundant_cop_disable_directive.rb} +24 -24
- data/lib/rubocop/cop/lint/{unneeded_cop_enable_directive.rb → redundant_cop_enable_directive.rb} +6 -8
- data/lib/rubocop/cop/lint/{unneeded_require_statement.rb → redundant_require_statement.rb} +1 -1
- data/lib/rubocop/cop/lint/{unneeded_splat_expansion.rb → redundant_splat_expansion.rb} +12 -7
- data/lib/rubocop/cop/lint/{string_conversion_in_interpolation.rb → redundant_string_coercion.rb} +7 -7
- data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +5 -6
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +91 -0
- data/lib/rubocop/cop/lint/{handle_exceptions.rb → suppressed_exception.rb} +1 -1
- data/lib/rubocop/cop/lint/unused_block_argument.rb +22 -6
- data/lib/rubocop/cop/lint/unused_method_argument.rb +23 -5
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -23
- data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +7 -26
- data/lib/rubocop/cop/message_annotator.rb +16 -7
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/line_length.rb +48 -42
- data/lib/rubocop/cop/metrics/method_length.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +23 -6
- data/lib/rubocop/cop/migration/department_name.rb +44 -0
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/{hash_alignment.rb → hash_alignment_styles.rb} +1 -1
- data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
- data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
- data/lib/rubocop/cop/mixin/nil_methods.rb +4 -4
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +5 -2
- data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
- data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -6
- data/lib/rubocop/cop/naming/{uncommunicative_block_param_name.rb → block_parameter_name.rb} +3 -3
- data/lib/rubocop/cop/naming/file_name.rb +12 -5
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -5
- data/lib/rubocop/cop/naming/method_name.rb +12 -1
- data/lib/rubocop/cop/naming/{uncommunicative_method_param_name.rb → method_parameter_name.rb} +3 -3
- data/lib/rubocop/cop/naming/predicate_name.rb +6 -6
- data/lib/rubocop/cop/naming/variable_name.rb +1 -0
- data/lib/rubocop/cop/offense.rb +18 -7
- data/lib/rubocop/cop/registry.rb +22 -1
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
- data/lib/rubocop/cop/style/alias.rb +1 -1
- data/lib/rubocop/cop/style/array_join.rb +1 -1
- data/lib/rubocop/cop/style/attr.rb +2 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +35 -16
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
- data/lib/rubocop/cop/style/comment_annotation.rb +5 -5
- data/lib/rubocop/cop/style/commented_keyword.rb +16 -30
- data/lib/rubocop/cop/style/conditional_assignment.rb +5 -7
- data/lib/rubocop/cop/style/constant_visibility.rb +13 -2
- data/lib/rubocop/cop/style/copyright.rb +11 -7
- data/lib/rubocop/cop/style/documentation_method.rb +44 -0
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +10 -4
- data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
- data/lib/rubocop/cop/style/empty_literal.rb +2 -2
- data/lib/rubocop/cop/style/empty_method.rb +5 -5
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
- data/lib/rubocop/cop/style/even_odd.rb +1 -1
- data/lib/rubocop/cop/style/expand_path_arguments.rb +1 -1
- data/lib/rubocop/cop/style/format_string.rb +10 -7
- data/lib/rubocop/cop/style/format_string_token.rb +19 -68
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +28 -33
- data/lib/rubocop/cop/style/guard_clause.rb +39 -10
- data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
- data/lib/rubocop/cop/style/if_unless_modifier.rb +58 -15
- data/lib/rubocop/cop/style/infinite_loop.rb +5 -4
- data/lib/rubocop/cop/style/inverse_methods.rb +19 -13
- data/lib/rubocop/cop/style/ip_addresses.rb +4 -4
- data/lib/rubocop/cop/style/lambda.rb +0 -2
- data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -10
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -25
- data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -9
- data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
- data/lib/rubocop/cop/style/mixin_usage.rb +11 -1
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +1 -1
- data/lib/rubocop/cop/style/nested_modifier.rb +22 -4
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +5 -5
- data/lib/rubocop/cop/style/next.rb +5 -5
- data/lib/rubocop/cop/style/non_nil_check.rb +21 -9
- data/lib/rubocop/cop/style/numeric_literals.rb +7 -3
- data/lib/rubocop/cop/style/option_hash.rb +3 -3
- data/lib/rubocop/cop/style/or_assignment.rb +6 -1
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +14 -0
- data/lib/rubocop/cop/style/{unneeded_capital_w.rb → redundant_capital_w.rb} +1 -1
- data/lib/rubocop/cop/style/{unneeded_condition.rb → redundant_condition.rb} +3 -3
- data/lib/rubocop/cop/style/{unneeded_interpolation.rb → redundant_interpolation.rb} +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +16 -7
- data/lib/rubocop/cop/style/{unneeded_percent_q.rb → redundant_percent_q.rb} +1 -1
- data/lib/rubocop/cop/style/redundant_return.rb +39 -29
- data/lib/rubocop/cop/style/redundant_self.rb +18 -1
- data/lib/rubocop/cop/style/{unneeded_sort.rb → redundant_sort.rb} +5 -5
- data/lib/rubocop/cop/style/rescue_modifier.rb +24 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +23 -3
- data/lib/rubocop/cop/style/semicolon.rb +13 -2
- data/lib/rubocop/cop/style/single_line_methods.rb +8 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +5 -7
- data/lib/rubocop/cop/style/ternary_parentheses.rb +19 -0
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
- data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
- data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
- data/lib/rubocop/cop/team.rb +5 -0
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/utils/format_string.rb +120 -0
- data/lib/rubocop/cop/variable_force.rb +7 -5
- data/lib/rubocop/cop/variable_force/variable.rb +15 -2
- data/lib/rubocop/core_ext/string.rb +0 -24
- data/lib/rubocop/formatter/clang_style_formatter.rb +9 -6
- data/lib/rubocop/formatter/emacs_style_formatter.rb +22 -9
- data/lib/rubocop/formatter/file_list_formatter.rb +1 -1
- data/lib/rubocop/formatter/formatter_set.rb +16 -15
- data/lib/rubocop/formatter/pacman_formatter.rb +80 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +16 -4
- data/lib/rubocop/formatter/tap_formatter.rb +18 -7
- data/lib/rubocop/magic_comment.rb +4 -0
- data/lib/rubocop/node_pattern.rb +3 -1
- data/lib/rubocop/options.rb +17 -22
- data/lib/rubocop/path_util.rb +1 -1
- data/lib/rubocop/processed_source.rb +5 -1
- data/lib/rubocop/rake_task.rb +1 -0
- data/lib/rubocop/result_cache.rb +22 -8
- data/lib/rubocop/rspec/expect_offense.rb +4 -1
- data/lib/rubocop/runner.rb +55 -32
- data/lib/rubocop/target_finder.rb +12 -6
- data/lib/rubocop/version.rb +1 -1
- metadata +47 -32
- data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +0 -19
- data/lib/rubocop/cop/mixin/safe_mode.rb +0 -22
@@ -46,7 +46,7 @@ module RuboCop
|
|
46
46
|
|
47
47
|
add_missing_namespaces(path, hash)
|
48
48
|
|
49
|
-
resolver.resolve_inheritance_from_gems(hash
|
49
|
+
resolver.resolve_inheritance_from_gems(hash)
|
50
50
|
resolver.resolve_inheritance(path, hash, file, debug?)
|
51
51
|
|
52
52
|
hash.delete('inherit_from')
|
@@ -199,6 +199,8 @@ module RuboCop
|
|
199
199
|
raise(TypeError, "Malformed configuration in #{absolute_path}")
|
200
200
|
end
|
201
201
|
|
202
|
+
check_cop_config_value(hash)
|
203
|
+
|
202
204
|
hash
|
203
205
|
end
|
204
206
|
|
@@ -220,6 +222,22 @@ module RuboCop
|
|
220
222
|
end
|
221
223
|
end
|
222
224
|
|
225
|
+
def check_cop_config_value(hash, parent = nil)
|
226
|
+
hash.each do |key, value|
|
227
|
+
check_cop_config_value(value, key) if value.is_a?(Hash)
|
228
|
+
|
229
|
+
next unless %w[Enabled
|
230
|
+
Safe
|
231
|
+
SafeAutoCorrect
|
232
|
+
AutoCorrect].include?(key) && value.is_a?(String)
|
233
|
+
|
234
|
+
abort(
|
235
|
+
"Property #{Rainbow(key).yellow} of cop #{Rainbow(parent).yellow}" \
|
236
|
+
" is supposed to be a boolean and #{Rainbow(value).yellow} is not."
|
237
|
+
)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
223
241
|
# Read the specified file, or exit with a friendly, concise message on
|
224
242
|
# stderr. Care is taken to use the standard OS exit code for a "file not
|
225
243
|
# found" error.
|
@@ -240,11 +258,11 @@ module RuboCop
|
|
240
258
|
yaml_code,
|
241
259
|
permitted_classes: [Regexp, Symbol],
|
242
260
|
permitted_symbols: [],
|
243
|
-
aliases:
|
261
|
+
aliases: true,
|
244
262
|
filename: filename
|
245
263
|
)
|
246
264
|
else
|
247
|
-
YAML.safe_load(yaml_code, [Regexp, Symbol], [],
|
265
|
+
YAML.safe_load(yaml_code, [Regexp, Symbol], [], true, filename)
|
248
266
|
end
|
249
267
|
end
|
250
268
|
end
|
@@ -35,7 +35,8 @@ module RuboCop
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def resolve_inheritance_from_gems(hash
|
38
|
+
def resolve_inheritance_from_gems(hash)
|
39
|
+
gems = hash.delete('inherit_gem')
|
39
40
|
(gems || {}).each_pair do |gem_name, config_path|
|
40
41
|
if gem_name == 'rubocop'
|
41
42
|
raise ArgumentError,
|
@@ -73,7 +74,7 @@ module RuboCop
|
|
73
74
|
|
74
75
|
opts = { inherit_mode: config['inherit_mode'] || {},
|
75
76
|
unset_nil: unset_nil }
|
76
|
-
Config.new(merge(default_configuration, config, opts), config_file)
|
77
|
+
Config.new(merge(default_configuration, config, **opts), config_file)
|
77
78
|
end
|
78
79
|
|
79
80
|
# Return a recursive merge of two hashes. That is, a normal hash merge,
|
@@ -92,7 +93,7 @@ module RuboCop
|
|
92
93
|
elsif should_union?(base_hash, key, opts[:inherit_mode])
|
93
94
|
result[key] = base_hash[key] | derived_hash[key]
|
94
95
|
elsif opts[:debug]
|
95
|
-
warn_on_duplicate_setting(base_hash, derived_hash, key, opts)
|
96
|
+
warn_on_duplicate_setting(base_hash, derived_hash, key, **opts)
|
96
97
|
end
|
97
98
|
end
|
98
99
|
result
|
@@ -0,0 +1,275 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
# This class handles obsolete configuration.
|
5
|
+
class ConfigObsoletion
|
6
|
+
RENAMED_COPS = {
|
7
|
+
'Layout/AlignArguments' => 'Layout/ArgumentAlignment',
|
8
|
+
'Layout/AlignArray' => 'Layout/ArrayAlignment',
|
9
|
+
'Layout/AlignHash' => 'Layout/HashAlignment',
|
10
|
+
'Layout/AlignParameters' => 'Layout/ParameterAlignment',
|
11
|
+
'Layout/IndentArray' => 'Layout/FirstArrayElementIndentation',
|
12
|
+
'Layout/IndentAssignment' => 'Layout/AssignmentIndentation',
|
13
|
+
'Layout/IndentFirstArgument' => 'Layout/FirstArgumentIndentation',
|
14
|
+
'Layout/IndentFirstArrayElement' => 'Layout/FirstArrayElementIndentation',
|
15
|
+
'Layout/IndentFirstHashElement' => 'Layout/FirstHashElementIndentation',
|
16
|
+
'Layout/IndentFirstParameter' => 'Layout/FirstParameterIndentation',
|
17
|
+
'Layout/IndentHash' => 'Layout/FirstHashElementIndentation',
|
18
|
+
'Layout/IndentHeredoc' => 'Layout/HeredocIndentation',
|
19
|
+
'Layout/LeadingBlankLines' => 'Layout/LeadingEmptyLines',
|
20
|
+
'Layout/TrailingBlankLines' => 'Layout/TrailingEmptyLines',
|
21
|
+
'Lint/DuplicatedKey' => 'Lint/DuplicateHashKey',
|
22
|
+
'Lint/HandleExceptions' => 'Lint/SuppressedException',
|
23
|
+
'Lint/MultipleCompare' => 'Lint/MultipleComparison',
|
24
|
+
'Lint/StringConversionInInterpolation' => 'Lint/RedundantStringCoercion',
|
25
|
+
'Lint/UnneededCopDisableDirective' => 'Lint/RedundantCopDisableDirective',
|
26
|
+
'Lint/UnneededCopEnableDirective' => 'Lint/RedundantCopEnableDirective',
|
27
|
+
'Lint/UnneededRequireStatement' => 'Lint/RedundantRequireStatement',
|
28
|
+
'Lint/UnneededSplatExpansion' => 'Lint/RedundantSplatExpansion',
|
29
|
+
'Naming/UncommunicativeBlockParamName' => 'Naming/BlockParameterName',
|
30
|
+
'Naming/UncommunicativeMethodParamName' => 'Naming/MethodParameterName',
|
31
|
+
'Style/DeprecatedHashMethods' => 'Style/PreferredHashMethods',
|
32
|
+
'Style/MethodCallParentheses' => 'Style/MethodCallWithoutArgsParentheses',
|
33
|
+
'Style/OpMethod' => 'Naming/BinaryOperatorParameterName',
|
34
|
+
'Style/SingleSpaceBeforeFirstArg' => 'Layout/SpaceBeforeFirstArg',
|
35
|
+
'Style/UnneededCapitalW' => 'Style/RedundantCapitalW',
|
36
|
+
'Style/UnneededCondition' => 'Style/RedundantCondition',
|
37
|
+
'Style/UnneededInterpolation' => 'Style/RedundantInterpolation',
|
38
|
+
'Style/UnneededPercentQ' => 'Style/RedundantPercentQ',
|
39
|
+
'Style/UnneededSort' => 'Style/RedundantSort'
|
40
|
+
}.map do |old_name, new_name|
|
41
|
+
[old_name, "The `#{old_name}` cop has been renamed to `#{new_name}`."]
|
42
|
+
end
|
43
|
+
|
44
|
+
MOVED_COPS = {
|
45
|
+
'Security' => 'Lint/Eval',
|
46
|
+
'Naming' => %w[Style/ClassAndModuleCamelCase Style/ConstantName
|
47
|
+
Style/FileName Style/MethodName Style/PredicateName
|
48
|
+
Style/VariableName Style/VariableNumber
|
49
|
+
Style/AccessorMethodName Style/AsciiIdentifiers],
|
50
|
+
'Layout' => %w[Lint/BlockAlignment Lint/EndAlignment
|
51
|
+
Lint/DefEndAlignment],
|
52
|
+
'Lint' => 'Style/FlipFlop'
|
53
|
+
}.map do |new_department, old_names|
|
54
|
+
Array(old_names).map do |old_name|
|
55
|
+
[old_name, "The `#{old_name}` cop has been moved to " \
|
56
|
+
"`#{new_department}/#{old_name.split('/').last}`."]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
REMOVED_COPS = {
|
61
|
+
'Layout/SpaceAfterControlKeyword' => 'Layout/SpaceAroundKeyword',
|
62
|
+
'Layout/SpaceBeforeModifierKeyword' => 'Layout/SpaceAroundKeyword',
|
63
|
+
'Lint/RescueWithoutErrorClass' => 'Style/RescueStandardError',
|
64
|
+
'Rails/DefaultScope' => nil,
|
65
|
+
'Style/SpaceAfterControlKeyword' => 'Layout/SpaceAroundKeyword',
|
66
|
+
'Style/SpaceBeforeModifierKeyword' => 'Layout/SpaceAroundKeyword',
|
67
|
+
'Style/TrailingComma' => 'Style/TrailingCommaInArguments, ' \
|
68
|
+
'Style/TrailingCommaInArrayLiteral, and/or ' \
|
69
|
+
'Style/TrailingCommaInHashLiteral',
|
70
|
+
'Style/TrailingCommaInLiteral' => 'Style/TrailingCommaInArrayLiteral ' \
|
71
|
+
'and/or ' \
|
72
|
+
'Style/TrailingCommaInHashLiteral'
|
73
|
+
}.map do |old_name, other_cops|
|
74
|
+
if other_cops
|
75
|
+
more = ". Please use #{other_cops} instead".gsub(%r{[A-Z]\w+/\w+},
|
76
|
+
'`\&`')
|
77
|
+
end
|
78
|
+
[old_name, "The `#{old_name}` cop has been removed#{more}."]
|
79
|
+
end
|
80
|
+
|
81
|
+
REMOVED_COPS_WITH_REASON = {
|
82
|
+
'Lint/InvalidCharacterLiteral' => 'it was never being actually triggered',
|
83
|
+
'Lint/SpaceBeforeFirstArg' =>
|
84
|
+
'it was a duplicate of `Layout/SpaceBeforeFirstArg`. Please use ' \
|
85
|
+
'`Layout/SpaceBeforeFirstArg` instead'
|
86
|
+
}.map do |cop_name, reason|
|
87
|
+
[cop_name, "The `#{cop_name}` cop has been removed since #{reason}."]
|
88
|
+
end
|
89
|
+
|
90
|
+
SPLIT_COPS = {
|
91
|
+
'Style/MethodMissing' =>
|
92
|
+
'The `Style/MethodMissing` cop has been split into ' \
|
93
|
+
'`Style/MethodMissingSuper` and `Style/MissingRespondToMissing`.'
|
94
|
+
}.to_a
|
95
|
+
|
96
|
+
OBSOLETE_COPS = Hash[*(RENAMED_COPS + MOVED_COPS + REMOVED_COPS +
|
97
|
+
REMOVED_COPS_WITH_REASON + SPLIT_COPS).flatten]
|
98
|
+
|
99
|
+
OBSOLETE_PARAMETERS = [
|
100
|
+
{
|
101
|
+
cops: %w[Layout/SpaceAroundOperators Style/SpaceAroundOperators],
|
102
|
+
parameters: 'MultiSpaceAllowedForOperators',
|
103
|
+
alternative: 'If your intention was to allow extra spaces for ' \
|
104
|
+
'alignment, please use AllowForAlignment: true instead.'
|
105
|
+
},
|
106
|
+
{
|
107
|
+
cops: 'Style/Encoding',
|
108
|
+
parameters: %w[EnforcedStyle SupportedStyles
|
109
|
+
AutoCorrectEncodingComment],
|
110
|
+
alternative: 'Style/Encoding no longer supports styles. ' \
|
111
|
+
'The "never" behavior is always assumed.'
|
112
|
+
},
|
113
|
+
{
|
114
|
+
cops: 'Style/IfUnlessModifier',
|
115
|
+
parameters: 'MaxLineLength',
|
116
|
+
alternative: '`Style/IfUnlessModifier: MaxLineLength` has been ' \
|
117
|
+
'removed. Use `Metrics/LineLength: Max` instead'
|
118
|
+
},
|
119
|
+
{
|
120
|
+
cops: 'Style/WhileUntilModifier',
|
121
|
+
parameters: 'MaxLineLength',
|
122
|
+
alternative: '`Style/WhileUntilModifier: MaxLineLength` has been ' \
|
123
|
+
'removed. Use `Metrics/LineLength: Max` instead'
|
124
|
+
},
|
125
|
+
{
|
126
|
+
cops: 'AllCops',
|
127
|
+
parameters: 'RunRailsCops',
|
128
|
+
alternative: "Use the following configuration instead:\n" \
|
129
|
+
"Rails:\n Enabled: true"
|
130
|
+
},
|
131
|
+
{
|
132
|
+
cops: 'Layout/CaseIndentation',
|
133
|
+
parameters: 'IndentWhenRelativeTo',
|
134
|
+
alternative: '`IndentWhenRelativeTo` has been renamed to ' \
|
135
|
+
'`EnforcedStyle`'
|
136
|
+
},
|
137
|
+
{
|
138
|
+
cops: %w[Lint/BlockAlignment Layout/BlockAlignment Lint/EndAlignment
|
139
|
+
Layout/EndAlignment Lint/DefEndAlignment
|
140
|
+
Layout/DefEndAlignment],
|
141
|
+
parameters: 'AlignWith',
|
142
|
+
alternative: '`AlignWith` has been renamed to `EnforcedStyleAlignWith`'
|
143
|
+
},
|
144
|
+
{
|
145
|
+
cops: 'Rails/UniqBeforePluck',
|
146
|
+
parameters: 'EnforcedMode',
|
147
|
+
alternative: '`EnforcedMode` has been renamed to `EnforcedStyle`'
|
148
|
+
},
|
149
|
+
{
|
150
|
+
cops: 'Style/MethodCallWithArgsParentheses',
|
151
|
+
parameters: 'IgnoredMethodPatterns',
|
152
|
+
alternative: '`IgnoredMethodPatterns` has been renamed to ' \
|
153
|
+
'`IgnoredPatterns`'
|
154
|
+
},
|
155
|
+
{
|
156
|
+
cops: %w[Performance/Count Performance/Detect],
|
157
|
+
parameters: 'SafeMode',
|
158
|
+
alternative: '`SafeMode` has been removed. ' \
|
159
|
+
'Use `SafeAutoCorrect` instead.'
|
160
|
+
},
|
161
|
+
{
|
162
|
+
cops: 'Bundler/GemComment',
|
163
|
+
parameters: 'Whitelist',
|
164
|
+
alternative: '`Whitelist` has been renamed to `IgnoredGems`.'
|
165
|
+
},
|
166
|
+
{
|
167
|
+
cops: %w[
|
168
|
+
Lint/SafeNavigationChain Lint/SafeNavigationConsistency
|
169
|
+
Style/NestedParenthesizedCalls Style/SafeNavigation
|
170
|
+
Style/TrivialAccessors
|
171
|
+
],
|
172
|
+
parameters: 'Whitelist',
|
173
|
+
alternative: '`Whitelist` has been renamed to `AllowedMethods`.'
|
174
|
+
},
|
175
|
+
{
|
176
|
+
cops: 'Style/IpAddresses',
|
177
|
+
parameters: 'Whitelist',
|
178
|
+
alternative: '`Whitelist` has been renamed to `AllowedAddresses`.'
|
179
|
+
},
|
180
|
+
{
|
181
|
+
cops: 'Naming/HeredocDelimiterNaming',
|
182
|
+
parameters: 'Blacklist',
|
183
|
+
alternative: '`Blacklist` has been renamed to `ForbiddenDelimiters`.'
|
184
|
+
},
|
185
|
+
{
|
186
|
+
cops: 'Naming/PredicateName',
|
187
|
+
parameters: 'NamePrefixBlacklist',
|
188
|
+
alternative: '`NamePrefixBlacklist` has been renamed to ' \
|
189
|
+
'`ForbiddenPrefixes`.'
|
190
|
+
},
|
191
|
+
{
|
192
|
+
cops: 'Naming/PredicateName',
|
193
|
+
parameters: 'NameWhitelist',
|
194
|
+
alternative: '`NameWhitelist` has been renamed to ' \
|
195
|
+
'`AllowedMethods`.'
|
196
|
+
}
|
197
|
+
].freeze
|
198
|
+
|
199
|
+
OBSOLETE_ENFORCED_STYLES = [
|
200
|
+
{
|
201
|
+
cop: 'Layout/IndentationConsistency',
|
202
|
+
parameter: 'EnforcedStyle',
|
203
|
+
enforced_style: 'rails',
|
204
|
+
alternative: '`EnforcedStyle: rails` has been renamed to ' \
|
205
|
+
'`EnforcedStyle: indented_internal_methods`'
|
206
|
+
}
|
207
|
+
].freeze
|
208
|
+
|
209
|
+
def initialize(config)
|
210
|
+
@config = config
|
211
|
+
end
|
212
|
+
|
213
|
+
def reject_obsolete_cops_and_parameters
|
214
|
+
messages = [obsolete_cops, obsolete_parameters,
|
215
|
+
obsolete_enforced_style].flatten.compact
|
216
|
+
return if messages.empty?
|
217
|
+
|
218
|
+
raise ValidationError, messages.join("\n")
|
219
|
+
end
|
220
|
+
|
221
|
+
private
|
222
|
+
|
223
|
+
def obsolete_cops
|
224
|
+
OBSOLETE_COPS.map do |cop_name, message|
|
225
|
+
next unless @config.key?(cop_name) ||
|
226
|
+
@config.key?(Cop::Badge.parse(cop_name).cop_name)
|
227
|
+
|
228
|
+
message + "\n(obsolete configuration found in " \
|
229
|
+
"#{smart_loaded_path}, please update it)"
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def obsolete_enforced_style
|
234
|
+
OBSOLETE_ENFORCED_STYLES.map do |params|
|
235
|
+
obsolete_enforced_style_message(params[:cop], params[:parameter],
|
236
|
+
params[:enforced_style],
|
237
|
+
params[:alternative])
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def obsolete_enforced_style_message(cop, param, enforced_style, alternative)
|
242
|
+
style = @config[cop]&.detect { |key, _| key.start_with?(param) }
|
243
|
+
|
244
|
+
return unless style && style[1] == enforced_style
|
245
|
+
|
246
|
+
"obsolete `#{param}: #{enforced_style}` (for #{cop}) found in " \
|
247
|
+
"#{smart_loaded_path}\n#{alternative}"
|
248
|
+
end
|
249
|
+
|
250
|
+
def obsolete_parameters
|
251
|
+
OBSOLETE_PARAMETERS.map do |params|
|
252
|
+
obsolete_parameter_message(params[:cops], params[:parameters],
|
253
|
+
params[:alternative])
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def obsolete_parameter_message(cops, parameters, alternative)
|
258
|
+
Array(cops).map do |cop|
|
259
|
+
obsolete_parameters = Array(parameters).select do |param|
|
260
|
+
@config[cop]&.key?(param)
|
261
|
+
end
|
262
|
+
next if obsolete_parameters.empty?
|
263
|
+
|
264
|
+
obsolete_parameters.map do |parameter|
|
265
|
+
"obsolete parameter #{parameter} (for #{cop}) found in " \
|
266
|
+
"#{smart_loaded_path}\n#{alternative}"
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def smart_loaded_path
|
272
|
+
PathUtil.smart_path(@config.loaded_path)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
@@ -0,0 +1,246 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
# Handles validation of configuration, for example cop names, parameter
|
7
|
+
# names, and Ruby versions.
|
8
|
+
class ConfigValidator
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
COMMON_PARAMS = %w[Exclude Include Severity inherit_mode
|
12
|
+
AutoCorrect StyleGuide Details].freeze
|
13
|
+
INTERNAL_PARAMS = %w[Description StyleGuide
|
14
|
+
VersionAdded VersionChanged VersionRemoved
|
15
|
+
Reference Safe SafeAutoCorrect].freeze
|
16
|
+
|
17
|
+
# 2.3 is the oldest officially supported Ruby version.
|
18
|
+
DEFAULT_RUBY_VERSION = 2.3
|
19
|
+
KNOWN_RUBIES = [2.3, 2.4, 2.5, 2.6, 2.7].freeze
|
20
|
+
OBSOLETE_RUBIES = {
|
21
|
+
1.9 => '0.50', 2.0 => '0.50', 2.1 => '0.58', 2.2 => '0.69'
|
22
|
+
}.freeze
|
23
|
+
RUBY_VERSION_FILENAME = '.ruby-version'
|
24
|
+
|
25
|
+
def_delegators :@config,
|
26
|
+
:smart_loaded_path, :for_all_cops, :find_file_upwards,
|
27
|
+
:base_dir_for_path_parameters, :bundler_lock_file_path
|
28
|
+
|
29
|
+
def initialize(config)
|
30
|
+
@config = config
|
31
|
+
@config_obsoletion = ConfigObsoletion.new(config)
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate
|
35
|
+
# Don't validate RuboCop's own files. Avoids infinite recursion.
|
36
|
+
return if @config.internal?
|
37
|
+
|
38
|
+
valid_cop_names, invalid_cop_names = @config.keys.partition do |key|
|
39
|
+
ConfigLoader.default_configuration.key?(key)
|
40
|
+
end
|
41
|
+
|
42
|
+
@config_obsoletion.reject_obsolete_cops_and_parameters
|
43
|
+
|
44
|
+
warn_about_unrecognized_cops(invalid_cop_names)
|
45
|
+
check_target_ruby
|
46
|
+
validate_parameter_names(valid_cop_names)
|
47
|
+
validate_enforced_styles(valid_cop_names)
|
48
|
+
validate_syntax_cop
|
49
|
+
reject_mutually_exclusive_defaults
|
50
|
+
end
|
51
|
+
|
52
|
+
def target_ruby_version
|
53
|
+
@target_ruby_version ||= begin
|
54
|
+
if for_all_cops['TargetRubyVersion']
|
55
|
+
@target_ruby_version_source = :rubocop_yml
|
56
|
+
|
57
|
+
for_all_cops['TargetRubyVersion'].to_f
|
58
|
+
elsif target_ruby_version_from_version_file
|
59
|
+
@target_ruby_version_source = :ruby_version_file
|
60
|
+
|
61
|
+
target_ruby_version_from_version_file
|
62
|
+
elsif target_ruby_version_from_bundler_lock_file
|
63
|
+
@target_ruby_version_source = :bundler_lock_file
|
64
|
+
|
65
|
+
target_ruby_version_from_bundler_lock_file
|
66
|
+
else
|
67
|
+
DEFAULT_RUBY_VERSION
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def validate_section_presence(name)
|
73
|
+
return unless @config.key?(name) && @config[name].nil?
|
74
|
+
|
75
|
+
raise ValidationError,
|
76
|
+
"empty section #{name} found in #{smart_loaded_path}"
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def check_target_ruby
|
82
|
+
return if KNOWN_RUBIES.include?(target_ruby_version)
|
83
|
+
|
84
|
+
msg = if OBSOLETE_RUBIES.include?(target_ruby_version)
|
85
|
+
"RuboCop found unsupported Ruby version #{target_ruby_version} " \
|
86
|
+
"in #{target_ruby_source}. #{target_ruby_version}-compatible " \
|
87
|
+
'analysis was dropped after version ' \
|
88
|
+
"#{OBSOLETE_RUBIES[target_ruby_version]}."
|
89
|
+
else
|
90
|
+
'RuboCop found unknown Ruby version ' \
|
91
|
+
"#{target_ruby_version.inspect} in #{target_ruby_source}."
|
92
|
+
end
|
93
|
+
|
94
|
+
msg += "\nSupported versions: #{KNOWN_RUBIES.join(', ')}"
|
95
|
+
|
96
|
+
raise ValidationError, msg
|
97
|
+
end
|
98
|
+
|
99
|
+
def warn_about_unrecognized_cops(invalid_cop_names)
|
100
|
+
invalid_cop_names.each do |name|
|
101
|
+
# There could be a custom cop with this name. If so, don't warn
|
102
|
+
next if Cop::Cop.registry.contains_cop_matching?([name])
|
103
|
+
|
104
|
+
# Special case for inherit_mode, which is a directive that we keep in
|
105
|
+
# the configuration (even though it's not a cop), because it's easier
|
106
|
+
# to do so than to pass the value around to various methods.
|
107
|
+
next if name == 'inherit_mode'
|
108
|
+
|
109
|
+
warn Rainbow("Warning: unrecognized cop #{name} found in " \
|
110
|
+
"#{smart_loaded_path}").yellow
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def validate_syntax_cop
|
115
|
+
syntax_config = @config['Lint/Syntax']
|
116
|
+
default_config = ConfigLoader.default_configuration['Lint/Syntax']
|
117
|
+
|
118
|
+
return unless syntax_config &&
|
119
|
+
default_config.merge(syntax_config) != default_config
|
120
|
+
|
121
|
+
raise ValidationError,
|
122
|
+
"configuration for Syntax cop found in #{smart_loaded_path}\n" \
|
123
|
+
'It\'s not possible to disable this cop.'
|
124
|
+
end
|
125
|
+
|
126
|
+
def validate_parameter_names(valid_cop_names)
|
127
|
+
valid_cop_names.each do |name|
|
128
|
+
validate_section_presence(name)
|
129
|
+
each_invalid_parameter(name) do |param, supported_params|
|
130
|
+
warn Rainbow(<<~MESSAGE).yellow
|
131
|
+
Warning: #{name} does not support #{param} parameter.
|
132
|
+
|
133
|
+
Supported parameters are:
|
134
|
+
|
135
|
+
- #{supported_params.join("\n - ")}
|
136
|
+
MESSAGE
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def each_invalid_parameter(cop_name)
|
142
|
+
default_config = ConfigLoader.default_configuration[cop_name]
|
143
|
+
|
144
|
+
@config[cop_name].each_key do |param|
|
145
|
+
next if COMMON_PARAMS.include?(param) || default_config.key?(param)
|
146
|
+
|
147
|
+
supported_params = default_config.keys - INTERNAL_PARAMS
|
148
|
+
|
149
|
+
yield param, supported_params
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def validate_enforced_styles(valid_cop_names)
|
154
|
+
valid_cop_names.each do |name|
|
155
|
+
styles = @config[name].select { |key, _| key.start_with?('Enforced') }
|
156
|
+
|
157
|
+
styles.each do |style_name, style|
|
158
|
+
supported_key = RuboCop::Cop::Util.to_supported_styles(style_name)
|
159
|
+
valid = ConfigLoader.default_configuration[name][supported_key]
|
160
|
+
|
161
|
+
next unless valid
|
162
|
+
next if valid.include?(style)
|
163
|
+
next if validate_support_and_has_list(name, style, valid)
|
164
|
+
|
165
|
+
msg = "invalid #{style_name} '#{style}' for #{name} found in " \
|
166
|
+
"#{smart_loaded_path}\n" \
|
167
|
+
"Valid choices are: #{valid.join(', ')}"
|
168
|
+
raise ValidationError, msg
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def validate_support_and_has_list(name, formats, valid)
|
174
|
+
ConfigLoader.default_configuration[name]['AllowMultipleStyles'] &&
|
175
|
+
formats.is_a?(Array) &&
|
176
|
+
formats.all? { |format| valid.include?(format) }
|
177
|
+
end
|
178
|
+
|
179
|
+
def target_ruby_source
|
180
|
+
case @target_ruby_version_source
|
181
|
+
when :ruby_version_file
|
182
|
+
"`#{RUBY_VERSION_FILENAME}`"
|
183
|
+
when :bundler_lock_file
|
184
|
+
"`#{bundler_lock_file_path}`"
|
185
|
+
when :rubocop_yml
|
186
|
+
"`TargetRubyVersion` parameter (in #{smart_loaded_path})"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def ruby_version_file
|
191
|
+
@ruby_version_file ||=
|
192
|
+
find_file_upwards(RUBY_VERSION_FILENAME, base_dir_for_path_parameters)
|
193
|
+
end
|
194
|
+
|
195
|
+
def target_ruby_version_from_version_file
|
196
|
+
file = ruby_version_file
|
197
|
+
return unless file && File.file?(file)
|
198
|
+
|
199
|
+
@target_ruby_version_from_version_file ||=
|
200
|
+
File.read(file).match(/\A(ruby-)?(?<version>\d+\.\d+)/) do |md|
|
201
|
+
md[:version].to_f
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def target_ruby_version_from_bundler_lock_file
|
206
|
+
@target_ruby_version_from_bundler_lock_file ||=
|
207
|
+
read_ruby_version_from_bundler_lock_file
|
208
|
+
end
|
209
|
+
|
210
|
+
def read_ruby_version_from_bundler_lock_file
|
211
|
+
lock_file_path = bundler_lock_file_path
|
212
|
+
return nil unless lock_file_path
|
213
|
+
|
214
|
+
in_ruby_section = false
|
215
|
+
File.foreach(lock_file_path) do |line|
|
216
|
+
# If ruby is in Gemfile.lock or gems.lock, there should be two lines
|
217
|
+
# towards the bottom of the file that look like:
|
218
|
+
# RUBY VERSION
|
219
|
+
# ruby W.X.YpZ
|
220
|
+
# We ultimately want to match the "ruby W.X.Y.pZ" line, but there's
|
221
|
+
# extra logic to make sure we only start looking once we've seen the
|
222
|
+
# "RUBY VERSION" line.
|
223
|
+
in_ruby_section ||= line.match(/^\s*RUBY\s*VERSION\s*$/)
|
224
|
+
next unless in_ruby_section
|
225
|
+
|
226
|
+
# We currently only allow this feature to work with MRI ruby. If jruby
|
227
|
+
# (or something else) is used by the project, it's lock file will have a
|
228
|
+
# line that looks like:
|
229
|
+
# RUBY VERSION
|
230
|
+
# ruby W.X.YpZ (jruby x.x.x.x)
|
231
|
+
# The regex won't match in this situation.
|
232
|
+
result = line.match(/^\s*ruby\s+(\d+\.\d+)[p.\d]*\s*$/)
|
233
|
+
return result.captures.first.to_f if result
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def reject_mutually_exclusive_defaults
|
238
|
+
disabled_by_default = for_all_cops['DisabledByDefault']
|
239
|
+
enabled_by_default = for_all_cops['EnabledByDefault']
|
240
|
+
return unless disabled_by_default && enabled_by_default
|
241
|
+
|
242
|
+
msg = 'Cops cannot be both enabled by default and disabled by default'
|
243
|
+
raise ValidationError, msg
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|