rubocop 1.5.0 → 1.7.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 +1 -1
- data/config/default.yml +52 -7
- data/config/obsoletion.yml +196 -0
- data/lib/rubocop.rb +14 -0
- data/lib/rubocop/cli/command/suggest_extensions.rb +21 -8
- data/lib/rubocop/config.rb +8 -5
- data/lib/rubocop/config_loader.rb +10 -6
- data/lib/rubocop/config_loader_resolver.rb +21 -4
- data/lib/rubocop/config_obsoletion.rb +64 -262
- data/lib/rubocop/config_obsoletion/changed_enforced_styles.rb +33 -0
- data/lib/rubocop/config_obsoletion/changed_parameter.rb +21 -0
- data/lib/rubocop/config_obsoletion/cop_rule.rb +34 -0
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +44 -0
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +44 -0
- data/lib/rubocop/config_obsoletion/removed_cop.rb +41 -0
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +34 -0
- data/lib/rubocop/config_obsoletion/rule.rb +41 -0
- data/lib/rubocop/config_obsoletion/split_cop.rb +27 -0
- data/lib/rubocop/config_validator.rb +11 -4
- data/lib/rubocop/cop/base.rb +17 -15
- data/lib/rubocop/cop/cop.rb +2 -2
- data/lib/rubocop/cop/correctors/string_literal_corrector.rb +6 -8
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +3 -2
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +145 -0
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +19 -3
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +26 -0
- data/lib/rubocop/cop/layout/line_length.rb +6 -16
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +7 -3
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -10
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +64 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +13 -10
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +59 -0
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +7 -2
- data/lib/rubocop/cop/lint/duplicate_branch.rb +64 -2
- data/lib/rubocop/cop/lint/interpolation_check.rb +7 -2
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +50 -17
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -11
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -0
- data/lib/rubocop/cop/lint/unreachable_loop.rb +17 -0
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/migration/department_name.rb +1 -1
- data/lib/rubocop/cop/mixin/string_help.rb +4 -1
- data/lib/rubocop/cop/naming/accessor_method_name.rb +15 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +59 -5
- data/lib/rubocop/cop/naming/variable_number.rb +3 -1
- data/lib/rubocop/cop/registry.rb +10 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -1
- data/lib/rubocop/cop/style/character_literal.rb +10 -11
- data/lib/rubocop/cop/style/collection_methods.rb +14 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +22 -5
- data/lib/rubocop/cop/style/float_division.rb +44 -1
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/hash_except.rb +95 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +4 -0
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +12 -2
- data/lib/rubocop/cop/style/lambda_call.rb +2 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +16 -6
- data/lib/rubocop/cop/style/method_def_parentheses.rb +7 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +26 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +3 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +13 -3
- data/lib/rubocop/cop/style/perl_backrefs.rb +86 -9
- data/lib/rubocop/cop/style/raise_args.rb +2 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +21 -2
- data/lib/rubocop/cop/style/redundant_freeze.rb +8 -4
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +24 -8
- data/lib/rubocop/cop/style/single_line_block_params.rb +30 -7
- data/lib/rubocop/cop/style/single_line_methods.rb +4 -0
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +24 -8
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -13
- data/lib/rubocop/cop/style/string_concatenation.rb +26 -1
- data/lib/rubocop/cop/style/string_literals.rb +14 -8
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +4 -3
- data/lib/rubocop/cop/style/symbol_proc.rb +5 -4
- data/lib/rubocop/cop/util.rb +3 -1
- data/lib/rubocop/ext/regexp_node.rb +31 -9
- data/lib/rubocop/ext/regexp_parser.rb +21 -3
- data/lib/rubocop/formatter/emacs_style_formatter.rb +2 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +2 -0
- data/lib/rubocop/formatter/tap_formatter.rb +2 -0
- data/lib/rubocop/lockfile.rb +40 -0
- data/lib/rubocop/options.rb +9 -9
- data/lib/rubocop/rspec/cop_helper.rb +0 -4
- data/lib/rubocop/rspec/expect_offense.rb +34 -22
- data/lib/rubocop/runner.rb +16 -1
- data/lib/rubocop/target_finder.rb +4 -2
- data/lib/rubocop/util.rb +16 -0
- data/lib/rubocop/version.rb +8 -2
- metadata +33 -5
@@ -3,7 +3,10 @@
|
|
3
3
|
module RuboCop
|
4
4
|
class CLI
|
5
5
|
module Command
|
6
|
-
#
|
6
|
+
# Suggest RuboCop extensions to install based on Gemfile dependencies.
|
7
|
+
# Only primary dependencies are evaluated, so if a dependency depends on a
|
8
|
+
# gem with an extension, it is not suggested. However, if an extension is
|
9
|
+
# a transitive dependency, it will not be suggested.
|
7
10
|
# @api private
|
8
11
|
class SuggestExtensions < Base
|
9
12
|
# Combination of short and long formatter names.
|
@@ -18,14 +21,17 @@ module RuboCop
|
|
18
21
|
puts 'Tip: Based on detected gems, the following '\
|
19
22
|
'RuboCop extension libraries might be helpful:'
|
20
23
|
|
21
|
-
extensions.each do |extension|
|
24
|
+
extensions.sort.each do |extension|
|
22
25
|
puts " * #{extension} (http://github.com/rubocop-hq/#{extension})"
|
23
26
|
end
|
24
27
|
|
25
28
|
puts
|
26
|
-
puts 'You can opt out of this message by adding the following to your config
|
29
|
+
puts 'You can opt out of this message by adding the following to your config '\
|
30
|
+
'(see https://docs.rubocop.org/rubocop/extensions.html#extension-suggestions '\
|
31
|
+
'for more options):'
|
27
32
|
puts ' AllCops:'
|
28
33
|
puts ' SuggestExtensions: false'
|
34
|
+
|
29
35
|
puts if @options[:display_time]
|
30
36
|
end
|
31
37
|
|
@@ -46,15 +52,22 @@ module RuboCop
|
|
46
52
|
end
|
47
53
|
|
48
54
|
def extensions
|
49
|
-
|
50
|
-
|
55
|
+
return [] unless lockfile.dependencies.any?
|
56
|
+
|
57
|
+
extensions = @config_store.for_pwd.for_all_cops['SuggestExtensions'] || {}
|
58
|
+
extensions.select { |_, v| (Array(v) & dependent_gems).any? }.keys - installed_gems
|
59
|
+
end
|
51
60
|
|
52
|
-
|
61
|
+
def lockfile
|
62
|
+
@lockfile ||= Lockfile.new
|
53
63
|
end
|
54
64
|
|
55
65
|
def dependent_gems
|
56
|
-
|
57
|
-
|
66
|
+
lockfile.dependencies.map(&:name)
|
67
|
+
end
|
68
|
+
|
69
|
+
def installed_gems
|
70
|
+
lockfile.gems.map(&:name)
|
58
71
|
end
|
59
72
|
|
60
73
|
def puts(*args)
|
data/lib/rubocop/config.rb
CHANGED
@@ -50,8 +50,8 @@ module RuboCop
|
|
50
50
|
self
|
51
51
|
end
|
52
52
|
|
53
|
-
def_delegators :@hash, :[], :[]=, :delete, :each, :key?, :keys, :each_key,
|
54
|
-
:fetch, :map, :merge, :to_h, :to_hash, :transform_values
|
53
|
+
def_delegators :@hash, :[], :[]=, :delete, :dig, :each, :key?, :keys, :each_key,
|
54
|
+
:fetch, :map, :merge, :replace, :to_h, :to_hash, :transform_values
|
55
55
|
def_delegators :@validator, :validate, :target_ruby_version
|
56
56
|
|
57
57
|
def to_s
|
@@ -281,6 +281,9 @@ module RuboCop
|
|
281
281
|
end
|
282
282
|
|
283
283
|
def enable_cop?(qualified_cop_name, cop_options)
|
284
|
+
# If the cop is explicitly enabled, the other checks can be skipped.
|
285
|
+
return true if cop_options['Enabled'] == true
|
286
|
+
|
284
287
|
department = department_of(qualified_cop_name)
|
285
288
|
cop_enabled = cop_options.fetch('Enabled') do
|
286
289
|
!for_all_cops['DisabledByDefault']
|
@@ -292,10 +295,10 @@ module RuboCop
|
|
292
295
|
end
|
293
296
|
|
294
297
|
def department_of(qualified_cop_name)
|
295
|
-
cop_department,
|
296
|
-
return nil if
|
298
|
+
*cop_department, _ = qualified_cop_name.split('/')
|
299
|
+
return nil if cop_department.empty?
|
297
300
|
|
298
|
-
self[cop_department]
|
301
|
+
self[cop_department.join('/')]
|
299
302
|
end
|
300
303
|
end
|
301
304
|
end
|
@@ -31,6 +31,7 @@ module RuboCop
|
|
31
31
|
|
32
32
|
def clear_options
|
33
33
|
@debug = nil
|
34
|
+
@loaded_features = []
|
34
35
|
FileFinder.root_level = nil
|
35
36
|
end
|
36
37
|
|
@@ -177,12 +178,9 @@ module RuboCop
|
|
177
178
|
@loaded_features.flatten.compact
|
178
179
|
end
|
179
180
|
|
180
|
-
private
|
181
|
-
|
182
|
-
|
183
|
-
File.absolute_path(file.is_a?(RemoteConfig) ? file.file : file)
|
184
|
-
end
|
185
|
-
|
181
|
+
# @api private
|
182
|
+
# Used to add features that were required inside a config or from
|
183
|
+
# the CLI using `--require`.
|
186
184
|
def add_loaded_features(loaded_features)
|
187
185
|
if instance_variable_defined?(:@loaded_features)
|
188
186
|
instance_variable_get(:@loaded_features) << loaded_features
|
@@ -191,6 +189,12 @@ module RuboCop
|
|
191
189
|
end
|
192
190
|
end
|
193
191
|
|
192
|
+
private
|
193
|
+
|
194
|
+
def file_path(file)
|
195
|
+
File.absolute_path(file.is_a?(RemoteConfig) ? file.file : file)
|
196
|
+
end
|
197
|
+
|
194
198
|
def find_project_dotfile(target_dir)
|
195
199
|
find_file_upwards(DOTFILE, target_dir, project_root)
|
196
200
|
end
|
@@ -20,12 +20,13 @@ module RuboCop
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
# rubocop:disable Metrics/MethodLength
|
24
|
-
def resolve_inheritance(path, hash, file, debug)
|
23
|
+
def resolve_inheritance(path, hash, file, debug) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
25
24
|
inherited_files = Array(hash['inherit_from'])
|
26
25
|
base_configs(path, inherited_files, file)
|
27
26
|
.reverse.each_with_index do |base_config, index|
|
28
27
|
override_department_setting_for_cops(base_config, hash)
|
28
|
+
override_enabled_for_disabled_departments(base_config, hash)
|
29
|
+
|
29
30
|
base_config.each do |k, v|
|
30
31
|
next unless v.is_a?(Hash)
|
31
32
|
|
@@ -39,7 +40,6 @@ module RuboCop
|
|
39
40
|
end
|
40
41
|
end
|
41
42
|
end
|
42
|
-
# rubocop:enable Metrics/MethodLength
|
43
43
|
|
44
44
|
def resolve_inheritance_from_gems(hash)
|
45
45
|
gems = hash.delete('inherit_gem')
|
@@ -75,6 +75,7 @@ module RuboCop
|
|
75
75
|
end
|
76
76
|
|
77
77
|
config = handle_disabled_by_default(config, default_configuration) if disabled_by_default
|
78
|
+
override_enabled_for_disabled_departments(default_configuration, config)
|
78
79
|
|
79
80
|
opts = { inherit_mode: config['inherit_mode'] || {},
|
80
81
|
unset_nil: unset_nil }
|
@@ -122,10 +123,26 @@ module RuboCop
|
|
122
123
|
end
|
123
124
|
end
|
124
125
|
|
126
|
+
# If a cop was previously explicitly enabled, but then superseded by the
|
127
|
+
# department being disabled, disable it.
|
128
|
+
def override_enabled_for_disabled_departments(base_hash, derived_hash)
|
129
|
+
cops_to_disable = derived_hash.each_key.with_object([]) do |key, cops|
|
130
|
+
next unless disabled?(derived_hash, key)
|
131
|
+
|
132
|
+
cops.concat(base_hash.keys.grep(Regexp.new("^#{key}/")))
|
133
|
+
end
|
134
|
+
|
135
|
+
cops_to_disable.each do |cop_name|
|
136
|
+
next unless base_hash.dig(cop_name, 'Enabled') == true
|
137
|
+
|
138
|
+
derived_hash.replace(merge({ cop_name => { 'Enabled' => false } }, derived_hash))
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
125
142
|
private
|
126
143
|
|
127
144
|
def disabled?(hash, department)
|
128
|
-
hash[department] && hash[department]['Enabled'] == false
|
145
|
+
hash[department].is_a?(Hash) && hash[department]['Enabled'] == false
|
129
146
|
end
|
130
147
|
|
131
148
|
def duplicate_setting?(base_hash, derived_hash, key, inherited_file)
|
@@ -4,233 +4,40 @@ module RuboCop
|
|
4
4
|
# This class handles obsolete configuration.
|
5
5
|
# @api private
|
6
6
|
class ConfigObsoletion
|
7
|
-
|
8
|
-
|
9
|
-
'
|
10
|
-
'
|
11
|
-
'
|
12
|
-
'
|
13
|
-
|
14
|
-
|
15
|
-
'
|
16
|
-
'
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
'Lint/StringConversionInInterpolation' => 'Lint/RedundantStringCoercion',
|
28
|
-
'Lint/UnneededCopDisableDirective' => 'Lint/RedundantCopDisableDirective',
|
29
|
-
'Lint/UnneededCopEnableDirective' => 'Lint/RedundantCopEnableDirective',
|
30
|
-
'Lint/UnneededRequireStatement' => 'Lint/RedundantRequireStatement',
|
31
|
-
'Lint/UnneededSplatExpansion' => 'Lint/RedundantSplatExpansion',
|
32
|
-
'Naming/UncommunicativeBlockParamName' => 'Naming/BlockParameterName',
|
33
|
-
'Naming/UncommunicativeMethodParamName' => 'Naming/MethodParameterName',
|
34
|
-
'Style/DeprecatedHashMethods' => 'Style/PreferredHashMethods',
|
35
|
-
'Style/MethodCallParentheses' => 'Style/MethodCallWithoutArgsParentheses',
|
36
|
-
'Style/OpMethod' => 'Naming/BinaryOperatorParameterName',
|
37
|
-
'Style/SingleSpaceBeforeFirstArg' => 'Layout/SpaceBeforeFirstArg',
|
38
|
-
'Style/UnneededCapitalW' => 'Style/RedundantCapitalW',
|
39
|
-
'Style/UnneededCondition' => 'Style/RedundantCondition',
|
40
|
-
'Style/UnneededInterpolation' => 'Style/RedundantInterpolation',
|
41
|
-
'Style/UnneededPercentQ' => 'Style/RedundantPercentQ',
|
42
|
-
'Style/UnneededSort' => 'Style/RedundantSort'
|
43
|
-
}.map do |old_name, new_name|
|
44
|
-
[old_name, "The `#{old_name}` cop has been renamed to `#{new_name}`."]
|
45
|
-
end
|
46
|
-
|
47
|
-
MOVED_COPS = {
|
48
|
-
'Security' => 'Lint/Eval',
|
49
|
-
'Naming' => %w[Style/ClassAndModuleCamelCase Style/ConstantName
|
50
|
-
Style/FileName Style/MethodName Style/PredicateName
|
51
|
-
Style/VariableName Style/VariableNumber
|
52
|
-
Style/AccessorMethodName Style/AsciiIdentifiers],
|
53
|
-
'Layout' => %w[Lint/BlockAlignment Lint/EndAlignment
|
54
|
-
Lint/DefEndAlignment Metrics/LineLength],
|
55
|
-
'Lint' => 'Style/FlipFlop'
|
56
|
-
}.map do |new_department, old_names|
|
57
|
-
Array(old_names).map do |old_name|
|
58
|
-
[old_name, "The `#{old_name}` cop has been moved to " \
|
59
|
-
"`#{new_department}/#{old_name.split('/').last}`."]
|
7
|
+
DEFAULT_RULES_FILE = File.join(ConfigLoader::RUBOCOP_HOME, 'config', 'obsoletion.yml')
|
8
|
+
COP_RULE_CLASSES = {
|
9
|
+
'renamed' => RenamedCop,
|
10
|
+
'removed' => RemovedCop,
|
11
|
+
'split' => SplitCop,
|
12
|
+
'extracted' => ExtractedCop
|
13
|
+
}.freeze
|
14
|
+
PARAMETER_RULE_CLASSES = {
|
15
|
+
'changed_parameters' => ChangedParameter,
|
16
|
+
'changed_enforced_styles' => ChangedEnforcedStyles
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
attr_reader :rules, :warnings
|
20
|
+
|
21
|
+
class << self
|
22
|
+
attr_accessor :files
|
23
|
+
|
24
|
+
def legacy_cop_names
|
25
|
+
# Used by DepartmentName#qualified_legacy_cop_name
|
26
|
+
new(Config.new).rules.select(&:cop_rule?).map(&:old_name)
|
60
27
|
end
|
61
28
|
end
|
62
29
|
|
63
|
-
|
64
|
-
|
65
|
-
'Layout/SpaceBeforeModifierKeyword' => 'Layout/SpaceAroundKeyword',
|
66
|
-
'Lint/RescueWithoutErrorClass' => 'Style/RescueStandardError',
|
67
|
-
'Style/SpaceAfterControlKeyword' => 'Layout/SpaceAroundKeyword',
|
68
|
-
'Style/SpaceBeforeModifierKeyword' => 'Layout/SpaceAroundKeyword',
|
69
|
-
'Style/TrailingComma' => 'Style/TrailingCommaInArguments, ' \
|
70
|
-
'Style/TrailingCommaInArrayLiteral, and/or ' \
|
71
|
-
'Style/TrailingCommaInHashLiteral',
|
72
|
-
'Style/TrailingCommaInLiteral' => 'Style/TrailingCommaInArrayLiteral ' \
|
73
|
-
'and/or ' \
|
74
|
-
'Style/TrailingCommaInHashLiteral',
|
75
|
-
'Style/BracesAroundHashParameters' => nil
|
76
|
-
}.map do |old_name, other_cops|
|
77
|
-
if other_cops
|
78
|
-
more = ". Please use #{other_cops} instead".gsub(%r{[A-Z]\w+/\w+},
|
79
|
-
'`\&`')
|
80
|
-
end
|
81
|
-
[old_name, "The `#{old_name}` cop has been removed#{more}."]
|
82
|
-
end
|
83
|
-
|
84
|
-
REMOVED_COPS_WITH_REASON = {
|
85
|
-
'Lint/InvalidCharacterLiteral' => 'it was never being actually triggered',
|
86
|
-
'Lint/SpaceBeforeFirstArg' =>
|
87
|
-
'it was a duplicate of `Layout/SpaceBeforeFirstArg`. Please use ' \
|
88
|
-
'`Layout/SpaceBeforeFirstArg` instead',
|
89
|
-
'Style/MethodMissingSuper' => 'it has been superseded by `Lint/MissingSuper`. Please use ' \
|
90
|
-
'`Lint/MissingSuper` instead',
|
91
|
-
'Lint/UselessComparison' => 'it has been superseded by '\
|
92
|
-
'`Lint/BinaryOperatorWithIdenticalOperands`. Please use '\
|
93
|
-
'`Lint/BinaryOperatorWithIdenticalOperands` instead'
|
94
|
-
}.map do |cop_name, reason|
|
95
|
-
[cop_name, "The `#{cop_name}` cop has been removed since #{reason}."]
|
96
|
-
end
|
97
|
-
|
98
|
-
SPLIT_COPS = {
|
99
|
-
'Style/MethodMissing' =>
|
100
|
-
'The `Style/MethodMissing` cop has been split into ' \
|
101
|
-
'`Style/MethodMissingSuper` and `Style/MissingRespondToMissing`.'
|
102
|
-
}.to_a
|
103
|
-
|
104
|
-
OBSOLETE_COPS = Hash[*(RENAMED_COPS + MOVED_COPS + REMOVED_COPS +
|
105
|
-
REMOVED_COPS_WITH_REASON + SPLIT_COPS).flatten]
|
106
|
-
|
107
|
-
# Parameters can be deprecated but not disabled by setting `severity: :warning`
|
108
|
-
OBSOLETE_PARAMETERS = [
|
109
|
-
{
|
110
|
-
cops: %w[Layout/SpaceAroundOperators Style/SpaceAroundOperators],
|
111
|
-
parameters: 'MultiSpaceAllowedForOperators',
|
112
|
-
alternative: 'If your intention was to allow extra spaces for ' \
|
113
|
-
'alignment, please use AllowForAlignment: true instead.'
|
114
|
-
},
|
115
|
-
{
|
116
|
-
cops: 'Style/Encoding',
|
117
|
-
parameters: %w[EnforcedStyle SupportedStyles
|
118
|
-
AutoCorrectEncodingComment],
|
119
|
-
alternative: 'Style/Encoding no longer supports styles. ' \
|
120
|
-
'The "never" behavior is always assumed.'
|
121
|
-
},
|
122
|
-
{
|
123
|
-
cops: 'Style/IfUnlessModifier',
|
124
|
-
parameters: 'MaxLineLength',
|
125
|
-
alternative: '`Style/IfUnlessModifier: MaxLineLength` has been ' \
|
126
|
-
'removed. Use `Layout/LineLength: Max` instead'
|
127
|
-
},
|
128
|
-
{
|
129
|
-
cops: 'Style/WhileUntilModifier',
|
130
|
-
parameters: 'MaxLineLength',
|
131
|
-
alternative: '`Style/WhileUntilModifier: MaxLineLength` has been ' \
|
132
|
-
'removed. Use `Layout/LineLength: Max` instead'
|
133
|
-
},
|
134
|
-
{
|
135
|
-
cops: 'AllCops',
|
136
|
-
parameters: 'RunRailsCops',
|
137
|
-
alternative: "Use the following configuration instead:\n" \
|
138
|
-
"Rails:\n Enabled: true"
|
139
|
-
},
|
140
|
-
{
|
141
|
-
cops: 'Layout/CaseIndentation',
|
142
|
-
parameters: 'IndentWhenRelativeTo',
|
143
|
-
alternative: '`IndentWhenRelativeTo` has been renamed to ' \
|
144
|
-
'`EnforcedStyle`'
|
145
|
-
},
|
146
|
-
{
|
147
|
-
cops: %w[Lint/BlockAlignment Layout/BlockAlignment Lint/EndAlignment
|
148
|
-
Layout/EndAlignment Lint/DefEndAlignment
|
149
|
-
Layout/DefEndAlignment],
|
150
|
-
parameters: 'AlignWith',
|
151
|
-
alternative: '`AlignWith` has been renamed to `EnforcedStyleAlignWith`'
|
152
|
-
},
|
153
|
-
{
|
154
|
-
cops: 'Rails/UniqBeforePluck',
|
155
|
-
parameters: 'EnforcedMode',
|
156
|
-
alternative: '`EnforcedMode` has been renamed to `EnforcedStyle`'
|
157
|
-
},
|
158
|
-
{
|
159
|
-
cops: 'Style/MethodCallWithArgsParentheses',
|
160
|
-
parameters: 'IgnoredMethodPatterns',
|
161
|
-
alternative: '`IgnoredMethodPatterns` has been renamed to ' \
|
162
|
-
'`IgnoredPatterns`'
|
163
|
-
},
|
164
|
-
{
|
165
|
-
cops: %w[Performance/Count Performance/Detect],
|
166
|
-
parameters: 'SafeMode',
|
167
|
-
alternative: '`SafeMode` has been removed. ' \
|
168
|
-
'Use `SafeAutoCorrect` instead.'
|
169
|
-
},
|
170
|
-
{
|
171
|
-
cops: 'Bundler/GemComment',
|
172
|
-
parameters: 'Whitelist',
|
173
|
-
alternative: '`Whitelist` has been renamed to `IgnoredGems`.'
|
174
|
-
},
|
175
|
-
{
|
176
|
-
cops: %w[
|
177
|
-
Lint/SafeNavigationChain Lint/SafeNavigationConsistency
|
178
|
-
Style/NestedParenthesizedCalls Style/SafeNavigation
|
179
|
-
Style/TrivialAccessors
|
180
|
-
],
|
181
|
-
parameters: 'Whitelist',
|
182
|
-
alternative: '`Whitelist` has been renamed to `AllowedMethods`.'
|
183
|
-
},
|
184
|
-
{
|
185
|
-
cops: 'Style/IpAddresses',
|
186
|
-
parameters: 'Whitelist',
|
187
|
-
alternative: '`Whitelist` has been renamed to `AllowedAddresses`.'
|
188
|
-
},
|
189
|
-
{
|
190
|
-
cops: 'Naming/HeredocDelimiterNaming',
|
191
|
-
parameters: 'Blacklist',
|
192
|
-
alternative: '`Blacklist` has been renamed to `ForbiddenDelimiters`.'
|
193
|
-
},
|
194
|
-
{
|
195
|
-
cops: 'Naming/PredicateName',
|
196
|
-
parameters: 'NamePrefixBlacklist',
|
197
|
-
alternative: '`NamePrefixBlacklist` has been renamed to ' \
|
198
|
-
'`ForbiddenPrefixes`.'
|
199
|
-
},
|
200
|
-
{
|
201
|
-
cops: 'Naming/PredicateName',
|
202
|
-
parameters: 'NameWhitelist',
|
203
|
-
alternative: '`NameWhitelist` has been renamed to ' \
|
204
|
-
'`AllowedMethods`.'
|
205
|
-
},
|
206
|
-
{
|
207
|
-
cops: %w[Metrics/BlockLength Metrics/MethodLength],
|
208
|
-
parameters: 'ExcludedMethods',
|
209
|
-
alternative: '`ExcludedMethods` has been renamed to `IgnoredMethods`.',
|
210
|
-
severity: :warning
|
211
|
-
}
|
212
|
-
].freeze
|
213
|
-
|
214
|
-
OBSOLETE_ENFORCED_STYLES = [
|
215
|
-
{
|
216
|
-
cop: 'Layout/IndentationConsistency',
|
217
|
-
parameter: 'EnforcedStyle',
|
218
|
-
enforced_style: 'rails',
|
219
|
-
alternative: '`EnforcedStyle: rails` has been renamed to ' \
|
220
|
-
'`EnforcedStyle: indented_internal_methods`'
|
221
|
-
}
|
222
|
-
].freeze
|
223
|
-
|
224
|
-
attr_reader :warnings
|
30
|
+
# Can be extended by extension libraries to add their own obsoletions
|
31
|
+
self.files = [DEFAULT_RULES_FILE]
|
225
32
|
|
226
33
|
def initialize(config)
|
227
34
|
@config = config
|
35
|
+
@rules = load_rules
|
228
36
|
@warnings = []
|
229
37
|
end
|
230
38
|
|
231
|
-
def
|
232
|
-
messages =
|
233
|
-
obsolete_enforced_style].flatten.compact
|
39
|
+
def reject_obsolete!
|
40
|
+
messages = obsoletions.flatten.compact
|
234
41
|
return if messages.empty?
|
235
42
|
|
236
43
|
raise ValidationError, messages.join("\n")
|
@@ -238,64 +45,59 @@ module RuboCop
|
|
238
45
|
|
239
46
|
private
|
240
47
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
48
|
+
# Default rules for obsoletions are in config/obsoletion.yml
|
49
|
+
# Additional rules files can be added with `RuboCop::ConfigObsoletion.files << filename`
|
50
|
+
def load_rules
|
51
|
+
rules = self.class.files.each_with_object({}) do |filename, hash|
|
52
|
+
hash.merge!(YAML.safe_load(File.read(filename))) do |_key, first, second|
|
53
|
+
first.merge(second)
|
54
|
+
end
|
248
55
|
end
|
249
|
-
end
|
250
56
|
|
251
|
-
|
252
|
-
|
253
|
-
obsolete_enforced_style_message(params[:cop], params[:parameter],
|
254
|
-
params[:enforced_style],
|
255
|
-
params[:alternative])
|
256
|
-
end
|
257
|
-
end
|
57
|
+
cop_rules = rules.slice(*COP_RULE_CLASSES.keys)
|
58
|
+
parameter_rules = rules.slice(*PARAMETER_RULE_CLASSES.keys)
|
258
59
|
|
259
|
-
|
260
|
-
|
60
|
+
load_cop_rules(cop_rules).concat(load_parameter_rules(parameter_rules))
|
61
|
+
end
|
261
62
|
|
262
|
-
|
63
|
+
# Cop rules are keyed by the name of the original cop
|
64
|
+
def load_cop_rules(rules)
|
65
|
+
rules.flat_map do |rule_type, data|
|
66
|
+
data.map do |cop_name, configuration|
|
67
|
+
next unless configuration # allow configurations to be disabled with `CopName: ~`
|
263
68
|
|
264
|
-
|
265
|
-
|
69
|
+
COP_RULE_CLASSES[rule_type].new(@config, cop_name, configuration)
|
70
|
+
end.compact
|
71
|
+
end
|
266
72
|
end
|
267
73
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
74
|
+
# Parameter rules may apply to multiple cops and multiple parameters
|
75
|
+
# and are given as an array. Each combination is turned into a separate
|
76
|
+
# rule object.
|
77
|
+
def load_parameter_rules(rules)
|
78
|
+
rules.flat_map do |rule_type, data|
|
79
|
+
data.flat_map do |configuration|
|
80
|
+
cops = Array(configuration['cops'])
|
81
|
+
parameters = Array(configuration['parameters'])
|
82
|
+
|
83
|
+
cops.product(parameters).map do |cop, parameter|
|
84
|
+
PARAMETER_RULE_CLASSES[rule_type].new(@config, cop, parameter, configuration)
|
85
|
+
end
|
277
86
|
end
|
278
|
-
|
279
|
-
messages
|
280
87
|
end
|
281
88
|
end
|
282
89
|
|
283
|
-
def
|
284
|
-
|
285
|
-
|
286
|
-
@config[cop]&.key?(param)
|
287
|
-
end
|
288
|
-
next if obsolete_parameters.empty?
|
90
|
+
def obsoletions
|
91
|
+
rules.map do |rule|
|
92
|
+
next unless rule.violated?
|
289
93
|
|
290
|
-
|
291
|
-
|
292
|
-
|
94
|
+
if rule.warning?
|
95
|
+
@warnings.push(rule.message)
|
96
|
+
next
|
293
97
|
end
|
294
|
-
end
|
295
|
-
end
|
296
98
|
|
297
|
-
|
298
|
-
|
99
|
+
rule.message
|
100
|
+
end
|
299
101
|
end
|
300
102
|
end
|
301
103
|
end
|