rubocop 1.5.2 → 1.6.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +5 -2
  4. data/config/obsoletion.yml +196 -0
  5. data/lib/rubocop.rb +10 -0
  6. data/lib/rubocop/cli/command/suggest_extensions.rb +16 -44
  7. data/lib/rubocop/config_obsoletion.rb +63 -263
  8. data/lib/rubocop/config_obsoletion/changed_enforced_styles.rb +33 -0
  9. data/lib/rubocop/config_obsoletion/changed_parameter.rb +21 -0
  10. data/lib/rubocop/config_obsoletion/cop_rule.rb +34 -0
  11. data/lib/rubocop/config_obsoletion/extracted_cop.rb +44 -0
  12. data/lib/rubocop/config_obsoletion/parameter_rule.rb +44 -0
  13. data/lib/rubocop/config_obsoletion/removed_cop.rb +41 -0
  14. data/lib/rubocop/config_obsoletion/renamed_cop.rb +34 -0
  15. data/lib/rubocop/config_obsoletion/rule.rb +41 -0
  16. data/lib/rubocop/config_obsoletion/split_cop.rb +27 -0
  17. data/lib/rubocop/config_validator.rb +11 -4
  18. data/lib/rubocop/cop/base.rb +17 -15
  19. data/lib/rubocop/cop/cop.rb +2 -2
  20. data/lib/rubocop/cop/correctors/string_literal_corrector.rb +6 -8
  21. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -1
  22. data/lib/rubocop/cop/layout/line_length.rb +6 -16
  23. data/lib/rubocop/cop/migration/department_name.rb +1 -1
  24. data/lib/rubocop/cop/mixin/string_help.rb +4 -1
  25. data/lib/rubocop/cop/naming/accessor_method_name.rb +15 -1
  26. data/lib/rubocop/cop/style/character_literal.rb +10 -11
  27. data/lib/rubocop/cop/style/float_division.rb +44 -1
  28. data/lib/rubocop/cop/style/if_unless_modifier.rb +4 -0
  29. data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
  30. data/lib/rubocop/cop/style/perl_backrefs.rb +86 -9
  31. data/lib/rubocop/cop/style/redundant_argument.rb +14 -1
  32. data/lib/rubocop/cop/style/single_line_block_params.rb +30 -7
  33. data/lib/rubocop/cop/style/sole_nested_conditional.rb +12 -6
  34. data/lib/rubocop/cop/style/special_global_vars.rb +1 -13
  35. data/lib/rubocop/cop/style/string_concatenation.rb +19 -0
  36. data/lib/rubocop/cop/style/string_literals.rb +14 -8
  37. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +4 -3
  38. data/lib/rubocop/formatter/emacs_style_formatter.rb +2 -0
  39. data/lib/rubocop/formatter/simple_text_formatter.rb +2 -0
  40. data/lib/rubocop/formatter/tap_formatter.rb +2 -0
  41. data/lib/rubocop/lockfile.rb +40 -0
  42. data/lib/rubocop/version.rb +1 -1
  43. metadata +14 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77baac77fdf5ed6293449d9653e1caeadc94b18e49bbd5115176c3681b8ed752
4
- data.tar.gz: 677ced7d3409d54555aaba855aec07fac0717bdb100eef4ea0196d68688247d6
3
+ metadata.gz: ae0bcfc68121984fb71e933b1a00aa8d418d99dd4005cce76e986d6c387c0e50
4
+ data.tar.gz: '0465797f84ca499f634aac95e745a4192bb62d68f5d935b4a7e21b925893b131'
5
5
  SHA512:
6
- metadata.gz: d083c6f78d892e14780bc3ab2cadf4b4208b87ab3dae357df39cc5dcbd9c2a18ff416795cd73a39c0d743fd07923ccbd092b916be3e738114558aa2b37f724cc
7
- data.tar.gz: 6a5e0502cfbc9c0c5c11f075b89a91ea7ae4ec1b70134fbe6930caca9f7959282dea23f9358db291cca2a4e1fa72e830a1717c1c845528024eb89d23e6368379
6
+ metadata.gz: eb0e28d3926209e380aed52e134801e3e206cf9ca1bace01e133223ddfe37507a888a70b629cefb7711951eaffd089078daa0a7065cf0730ccfd79febe80f1ff
7
+ data.tar.gz: 17fcb97b537f9529a5bb484d85f5873f1745905712472586550f463cf689465f12aaa291efcf9371babc17b8ca7e5b2d5a99d7f6a46c800fdb3dba8dca58989e
data/README.md CHANGED
@@ -51,7 +51,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
51
51
  in your `Gemfile`:
52
52
 
53
53
  ```rb
54
- gem 'rubocop', '~> 1.5', require: false
54
+ gem 'rubocop', '~> 1.6', require: false
55
55
  ```
56
56
 
57
57
  See [versioning](https://docs.rubocop.org/rubocop/1.0/versioning.html) for further details.
@@ -3209,9 +3209,10 @@ Style/ExponentialNotation:
3209
3209
  Style/FloatDivision:
3210
3210
  Description: 'For performing float division, coerce one side only.'
3211
3211
  StyleGuide: '#float-division'
3212
- Reference: 'https://github.com/rubocop-hq/ruby-style-guide/issues/628'
3212
+ Reference: 'https://blog.rubystyle.guide/ruby/2019/06/21/float-division.html'
3213
3213
  Enabled: true
3214
3214
  VersionAdded: '0.72'
3215
+ VersionChanged: '1.6'
3215
3216
  EnforcedStyle: single_coerce
3216
3217
  SupportedStyles:
3217
3218
  - left_coerce
@@ -4025,6 +4026,7 @@ Style/RedundantArgument:
4025
4026
  Enabled: pending
4026
4027
  Safe: false
4027
4028
  VersionAdded: '1.4'
4029
+ VersionChanged: '1.6'
4028
4030
  Methods:
4029
4031
  # Array#join
4030
4032
  join: ''
@@ -4272,7 +4274,7 @@ Style/SingleLineBlockParams:
4272
4274
  Description: 'Enforces the names of some block params.'
4273
4275
  Enabled: false
4274
4276
  VersionAdded: '0.16'
4275
- VersionChanged: '0.47'
4277
+ VersionChanged: '1.6'
4276
4278
  Methods:
4277
4279
  - reduce:
4278
4280
  - acc
@@ -4345,6 +4347,7 @@ Style/StringConcatenation:
4345
4347
  Enabled: true
4346
4348
  Safe: false
4347
4349
  VersionAdded: '0.89'
4350
+ VersionChanged: '1.6'
4348
4351
 
4349
4352
  Style/StringHashKeys:
4350
4353
  Description: 'Prefer symbols instead of strings as hash keys.'
@@ -0,0 +1,196 @@
1
+ # Configuration of obsolete/deprecated cops used by `ConfigObsoletion`
2
+
3
+ # Cops that were renamed
4
+ renamed:
5
+ Layout/AlignArguments: Layout/ArgumentAlignment
6
+ Layout/AlignArray: Layout/ArrayAlignment
7
+ Layout/AlignHash: Layout/HashAlignment
8
+ Layout/AlignParameters: Layout/ParameterAlignment
9
+ Layout/IndentArray: Layout/FirstArrayElementIndentation
10
+ Layout/IndentAssignment: Layout/AssignmentIndentation
11
+ Layout/IndentFirstArgument: Layout/FirstArgumentIndentation
12
+ Layout/IndentFirstArrayElement: Layout/FirstArrayElementIndentation
13
+ Layout/IndentFirstHashElement: Layout/FirstHashElementIndentation
14
+ Layout/IndentFirstParameter: Layout/FirstParameterIndentation
15
+ Layout/IndentHash: Layout/FirstHashElementIndentation
16
+ Layout/IndentHeredoc: Layout/HeredocIndentation
17
+ Layout/LeadingBlankLines: Layout/LeadingEmptyLines
18
+ Layout/Tab: Layout/IndentationStyle
19
+ Layout/TrailingBlankLines: Layout/TrailingEmptyLines
20
+ Lint/BlockAlignment: Layout/BlockAlignment
21
+ Lint/DefEndAlignment: Layout/DefEndAlignment
22
+ Lint/DuplicatedKey: Lint/DuplicateHashKey
23
+ Lint/EndAlignment: Layout/EndAlignment
24
+ Lint/EndInMethod: Style/EndBlock
25
+ Lint/Eval: Security/Eval
26
+ Lint/HandleExceptions: Lint/SuppressedException
27
+ Lint/MultipleCompare: Lint/MultipleComparison
28
+ Lint/StringConversionInInterpolation: Lint/RedundantStringCoercion
29
+ Lint/UnneededCopDisableDirective: Lint/RedundantCopDisableDirective
30
+ Lint/UnneededCopEnableDirective: Lint/RedundantCopEnableDirective
31
+ Lint/UnneededRequireStatement: Lint/RedundantRequireStatement
32
+ Lint/UnneededSplatExpansion: Lint/RedundantSplatExpansion
33
+ Metrics/LineLength: Layout/LineLength
34
+ Naming/UncommunicativeBlockParamName: Naming/BlockParameterName
35
+ Naming/UncommunicativeMethodParamName: Naming/MethodParameterName
36
+ Style/AccessorMethodName: Naming/AccessorMethodName
37
+ Style/AsciiIdentifiers: Naming/AsciiIdentifiers
38
+ Style/ClassAndModuleCamelCase: Naming/ClassAndModuleCamelCase
39
+ Style/ConstantName: Naming/ConstantName
40
+ Style/DeprecatedHashMethods: Style/PreferredHashMethods
41
+ Style/FileName: Naming/FileName
42
+ Style/FlipFlop: Lint/FlipFlop
43
+ Style/MethodCallParentheses: Style/MethodCallWithoutArgsParentheses
44
+ Style/MethodName: Naming/MethodName
45
+ Style/OpMethod: Naming/BinaryOperatorParameterName
46
+ Style/PredicateName: Naming/PredicateName
47
+ Style/SingleSpaceBeforeFirstArg: Layout/SpaceBeforeFirstArg
48
+ Style/UnneededCapitalW: Style/RedundantCapitalW
49
+ Style/UnneededCondition: Style/RedundantCondition
50
+ Style/UnneededInterpolation: Style/RedundantInterpolation
51
+ Style/UnneededPercentQ: Style/RedundantPercentQ
52
+ Style/UnneededSort: Style/RedundantSort
53
+ Style/VariableName: Naming/VariableName
54
+ Style/VariableNumber: Naming/VariableNumber
55
+
56
+ # Cops that were removed
57
+ removed:
58
+ Layout/SpaceAfterControlKeyword:
59
+ alternatives: Layout/SpaceAroundKeyword
60
+ Layout/SpaceBeforeModifierKeyword:
61
+ alternatives: Layout/SpaceAroundKeyword
62
+ Lint/InvalidCharacterLiteral:
63
+ reason: it was never being actually triggered
64
+ Lint/RescueWithoutErrorClass:
65
+ alternatives: Style/RescueStandardError
66
+ Lint/SpaceBeforeFirstArg:
67
+ reason: >
68
+ it was a duplicate of `Layout/SpaceBeforeFirstArg`. Please use
69
+ `Layout/SpaceBeforeFirstArg` instead
70
+ Lint/UselessComparison:
71
+ reason: >
72
+ it has been superseded by
73
+ `Lint/BinaryOperatorWithIdenticalOperands`. Please use
74
+ `Lint/BinaryOperatorWithIdenticalOperands` instead
75
+ Style/BracesAroundHashParameters: true
76
+ Style/MethodMissingSuper:
77
+ reason: >
78
+ it has been superseded by `Lint/MissingSuper`. Please use
79
+ `Lint/MissingSuper` instead
80
+ Style/SpaceAfterControlKeyword:
81
+ alternatives: Layout/SpaceAroundKeyword
82
+ Style/SpaceBeforeModifierKeyword:
83
+ alternatives: Layout/SpaceAroundKeyword
84
+ Style/TrailingComma:
85
+ alternatives:
86
+ - Style/TrailingCommaInArguments
87
+ - Style/TrailingCommaInArrayLiteral
88
+ - Style/TrailingCommaInHashLiteral
89
+ Style/TrailingCommaInLiteral:
90
+ alternatives:
91
+ - Style/TrailingCommaInArrayLiteral
92
+ - Style/TrailingCommaInHashLiteral
93
+
94
+ # Cops split into multiple other cops
95
+ split:
96
+ Style/MethodMissing:
97
+ alternatives:
98
+ - Style/MethodMissingSuper
99
+ - Style/MissingRespondToMissing
100
+
101
+ # Cops that were extracted into a different gem
102
+ extracted:
103
+ Performance/*: rubocop-performance
104
+ Rails/*: rubocop-rails
105
+
106
+ # Cop parameters that have been changed
107
+ # Can be treated as a warning instead of a failure with `severity: warning`
108
+ changed_parameters:
109
+ - cops:
110
+ - Layout/SpaceAroundOperators
111
+ - Style/SpaceAroundOperators
112
+ parameters: MultiSpaceAllowedForOperators
113
+ reason: >
114
+ If your intention was to allow extra spaces for alignment, please
115
+ use `AllowForAlignment: true` instead.
116
+ - cops: Style/Encoding
117
+ parameters:
118
+ - EnforcedStyle
119
+ - SupportedStyles
120
+ - AutoCorrectEncodingComment
121
+ reason: '`Style/Encoding` no longer supports styles. The "never" behavior is always assumed.'
122
+ - cops: Style/IfUnlessModifier
123
+ parameters: MaxLineLength
124
+ reason: >
125
+ `Style/IfUnlessModifier: MaxLineLength` has been removed.
126
+ Use `Layout/LineLength: Max` instead
127
+ - cops: Style/WhileUntilModifier
128
+ parameters: MaxLineLength
129
+ reason: >
130
+ `Style/WhileUntilModifier: MaxLineLength` has been removed.
131
+ Use `Layout/LineLength: Max` instead
132
+ - cops: AllCops
133
+ parameters: RunRailsCops
134
+ reason: |-
135
+ Use the following configuration instead:
136
+ Rails:
137
+ Enabled: true
138
+ - cops: Layout/CaseIndentation
139
+ parameters: IndentWhenRelativeTo
140
+ alternative: EnforcedStyle
141
+ - cops:
142
+ - Lint/BlockAlignment
143
+ - Layout/BlockAlignment
144
+ - Lint/EndAlignment
145
+ - Layout/EndAlignment
146
+ - Lint/DefEndAlignment
147
+ - Layout/DefEndAlignment
148
+ parameters: AlignWith
149
+ alternative: EnforcedStyleAlignWith
150
+ - cops: Rails/UniqBeforePluck
151
+ parameters: EnforcedMode
152
+ alternative: EnforcedStyle
153
+ - cops: Style/MethodCallWithArgsParentheses
154
+ parameters: IgnoredMethodPatterns
155
+ alternative: IgnoredPatterns
156
+ - cops:
157
+ - Performance/Count
158
+ - Performance/Detect
159
+ parameters: SafeMode
160
+ reason: "`SafeMode` has been removed. Use `SafeAutoCorrect` instead."
161
+ - cops: Bundler/GemComment
162
+ parameters: Whitelist
163
+ alternative: IgnoredGems
164
+ - cops:
165
+ - Lint/SafeNavigationChain
166
+ - Lint/SafeNavigationConsistency
167
+ - Style/NestedParenthesizedCalls
168
+ - Style/SafeNavigation
169
+ - Style/TrivialAccessors
170
+ parameters: Whitelist
171
+ alternative: AllowedMethods
172
+ - cops: Style/IpAddresses
173
+ parameters: Whitelist
174
+ alternative: AllowedAddresses
175
+ - cops: Naming/HeredocDelimiterNaming
176
+ parameters: Blacklist
177
+ alternative: ForbiddenDelimiters
178
+ - cops: Naming/PredicateName
179
+ parameters: NamePrefixBlacklist
180
+ alternative: ForbiddenPrefixes
181
+ - cops: Naming/PredicateName
182
+ parameters: NameWhitelist
183
+ alternative: AllowedMethods
184
+ - cops:
185
+ - Metrics/BlockLength
186
+ - Metrics/MethodLength
187
+ parameters: ExcludedMethods
188
+ alternative: IgnoredMethods
189
+ severity: warning
190
+
191
+ # Enforced styles that have been removed or replaced
192
+ changed_enforced_styles:
193
+ - cops: Layout/IndentationConsistency
194
+ parameters: EnforcedStyle
195
+ value: rails
196
+ alternative: indented_internal_methods
@@ -632,9 +632,19 @@ require_relative 'rubocop/cached_data'
632
632
  require_relative 'rubocop/config'
633
633
  require_relative 'rubocop/config_loader_resolver'
634
634
  require_relative 'rubocop/config_loader'
635
+ require_relative 'rubocop/config_obsoletion/rule'
636
+ require_relative 'rubocop/config_obsoletion/cop_rule'
637
+ require_relative 'rubocop/config_obsoletion/parameter_rule'
638
+ require_relative 'rubocop/config_obsoletion/changed_enforced_styles'
639
+ require_relative 'rubocop/config_obsoletion/changed_parameter'
640
+ require_relative 'rubocop/config_obsoletion/extracted_cop'
641
+ require_relative 'rubocop/config_obsoletion/removed_cop'
642
+ require_relative 'rubocop/config_obsoletion/renamed_cop'
643
+ require_relative 'rubocop/config_obsoletion/split_cop'
635
644
  require_relative 'rubocop/config_obsoletion'
636
645
  require_relative 'rubocop/config_store'
637
646
  require_relative 'rubocop/config_validator'
647
+ require_relative 'rubocop/lockfile'
638
648
  require_relative 'rubocop/target_finder'
639
649
  require_relative 'rubocop/directive_comment'
640
650
  require_relative 'rubocop/comment_config'
@@ -3,7 +3,10 @@
3
3
  module RuboCop
4
4
  class CLI
5
5
  module Command
6
- # Run all the selected cops and report the result.
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.
@@ -11,39 +14,6 @@ module RuboCop
11
14
 
12
15
  self.command_name = :suggest_extensions
13
16
 
14
- class << self
15
- # Gems that the current bundle depends on
16
- # Suggestions are only made for gems that are 1st party dependencies
17
- def dependent_gems
18
- bundler do |gems|
19
- gems.dependencies.map(&:name)
20
- end
21
- end
22
-
23
- # All installed gems in the current bundle
24
- # If a suggestion is installed but not depended on, it still should not
25
- # be suggested.
26
- def installed_gems
27
- bundler do
28
- # Load specs from the lockfile without trying to resolve them
29
- return [] unless Bundler.default_lockfile
30
-
31
- lockfile = Bundler.read_file(Bundler.default_lockfile)
32
- Bundler::LockfileParser.new(lockfile).specs.map(&:name)
33
- end
34
- end
35
-
36
- private
37
-
38
- def bundler
39
- return [] unless defined?(Bundler)
40
-
41
- yield Bundler.load
42
- rescue Bundler::BundlerError
43
- []
44
- end
45
- end
46
-
47
17
  def run
48
18
  return if skip? || extensions.none?
49
19
 
@@ -82,25 +52,27 @@ module RuboCop
82
52
  end
83
53
 
84
54
  def extensions
85
- return [] unless dependent_gems.any?
55
+ return [] unless lockfile.dependencies.any?
86
56
 
87
- @extensions ||= begin
88
- extensions = @config_store.for_pwd.for_all_cops['SuggestExtensions'] || {}
89
- extensions.select { |_, v| (Array(v) & dependent_gems).any? }.keys - installed_gems
90
- end
57
+ extensions = @config_store.for_pwd.for_all_cops['SuggestExtensions'] || {}
58
+ extensions.select { |_, v| (Array(v) & dependent_gems).any? }.keys - installed_gems
91
59
  end
92
60
 
93
- def puts(*args)
94
- output = (@options[:stderr] ? $stderr : $stdout)
95
- output.puts(*args)
61
+ def lockfile
62
+ @lockfile ||= Lockfile.new
96
63
  end
97
64
 
98
65
  def dependent_gems
99
- @dependent_gems ||= self.class.dependent_gems
66
+ lockfile.dependencies.map(&:name)
100
67
  end
101
68
 
102
69
  def installed_gems
103
- @installed_gems ||= self.class.installed_gems
70
+ lockfile.gems.map(&:name)
71
+ end
72
+
73
+ def puts(*args)
74
+ output = (@options[:stderr] ? $stderr : $stdout)
75
+ output.puts(*args)
104
76
  end
105
77
  end
106
78
  end
@@ -4,233 +4,40 @@ module RuboCop
4
4
  # This class handles obsolete configuration.
5
5
  # @api private
6
6
  class ConfigObsoletion
7
- RENAMED_COPS = {
8
- 'Layout/AlignArguments' => 'Layout/ArgumentAlignment',
9
- 'Layout/AlignArray' => 'Layout/ArrayAlignment',
10
- 'Layout/AlignHash' => 'Layout/HashAlignment',
11
- 'Layout/AlignParameters' => 'Layout/ParameterAlignment',
12
- 'Layout/IndentArray' => 'Layout/FirstArrayElementIndentation',
13
- 'Layout/IndentAssignment' => 'Layout/AssignmentIndentation',
14
- 'Layout/IndentFirstArgument' => 'Layout/FirstArgumentIndentation',
15
- 'Layout/IndentFirstArrayElement' => 'Layout/FirstArrayElementIndentation',
16
- 'Layout/IndentFirstHashElement' => 'Layout/FirstHashElementIndentation',
17
- 'Layout/IndentFirstParameter' => 'Layout/FirstParameterIndentation',
18
- 'Layout/IndentHash' => 'Layout/FirstHashElementIndentation',
19
- 'Layout/IndentHeredoc' => 'Layout/HeredocIndentation',
20
- 'Layout/LeadingBlankLines' => 'Layout/LeadingEmptyLines',
21
- 'Layout/Tab' => 'Layout/IndentationStyle',
22
- 'Layout/TrailingBlankLines' => 'Layout/TrailingEmptyLines',
23
- 'Lint/DuplicatedKey' => 'Lint/DuplicateHashKey',
24
- 'Lint/EndInMethod' => 'Style/EndBlock',
25
- 'Lint/HandleExceptions' => 'Lint/SuppressedException',
26
- 'Lint/MultipleCompare' => 'Lint/MultipleComparison',
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
- REMOVED_COPS = {
64
- 'Layout/SpaceAfterControlKeyword' => 'Layout/SpaceAroundKeyword',
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 reject_obsolete_cops_and_parameters
232
- messages = [obsolete_cops, obsolete_parameters,
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,57 @@ module RuboCop
238
45
 
239
46
  private
240
47
 
241
- def obsolete_cops
242
- OBSOLETE_COPS.map do |cop_name, message|
243
- next unless @config.key?(cop_name) ||
244
- @config.key?(Cop::Badge.parse(cop_name).cop_name)
245
-
246
- message + "\n(obsolete configuration found in " \
247
- "#{smart_loaded_path}, please update it)"
248
- end
249
- end
250
-
251
- def obsolete_enforced_style
252
- OBSOLETE_ENFORCED_STYLES.map do |params|
253
- obsolete_enforced_style_message(params[:cop], params[:parameter],
254
- params[:enforced_style],
255
- params[:alternative])
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
256
55
  end
257
- end
258
-
259
- def obsolete_enforced_style_message(cop, param, enforced_style, alternative)
260
- style = @config[cop]&.detect { |key, _| key.start_with?(param) }
261
56
 
262
- return unless style && style[1] == enforced_style
57
+ cop_rules = rules.slice(*COP_RULE_CLASSES.keys)
58
+ parameter_rules = rules.slice(*PARAMETER_RULE_CLASSES.keys)
263
59
 
264
- "obsolete `#{param}: #{enforced_style}` (for #{cop}) found in " \
265
- "#{smart_loaded_path}\n#{alternative}"
60
+ load_cop_rules(cop_rules).concat(load_parameter_rules(parameter_rules))
266
61
  end
267
62
 
268
- def obsolete_parameters
269
- OBSOLETE_PARAMETERS.collect do |params|
270
- messages = obsolete_parameter_message(params[:cops], params[:parameters],
271
- params[:alternative])
272
-
273
- # Warnings are collected separately and not added to the error message
274
- if messages && params.fetch(:severity, :error) == :warning
275
- @warnings.concat(messages)
276
- next
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 |configuration|
67
+ COP_RULE_CLASSES[rule_type].new(@config, *configuration)
277
68
  end
278
-
279
- messages
280
69
  end
281
70
  end
282
71
 
283
- def obsolete_parameter_message(cops, parameters, alternative)
284
- Array(cops).map do |cop|
285
- obsolete_parameters = Array(parameters).select do |param|
286
- @config[cop]&.key?(param)
287
- end
288
- next if obsolete_parameters.empty?
289
-
290
- obsolete_parameters.map do |parameter|
291
- "obsolete parameter #{parameter} (for #{cop}) found in " \
292
- "#{smart_loaded_path}\n#{alternative}"
72
+ # Parameter rules may apply to multiple cops and multiple parameters
73
+ # and are given as an array. Each combination is turned into a separate
74
+ # rule object.
75
+ def load_parameter_rules(rules)
76
+ rules.flat_map do |rule_type, data|
77
+ data.flat_map do |configuration|
78
+ cops = Array(configuration['cops'])
79
+ parameters = Array(configuration['parameters'])
80
+
81
+ cops.product(parameters).map do |cop, parameter|
82
+ PARAMETER_RULE_CLASSES[rule_type].new(@config, cop, parameter, configuration)
83
+ end
293
84
  end
294
85
  end
295
86
  end
296
87
 
297
- def smart_loaded_path
298
- PathUtil.smart_path(@config.loaded_path)
88
+ def obsoletions
89
+ rules.map do |rule|
90
+ next unless rule.violated?
91
+
92
+ if rule.warning?
93
+ @warnings.push(rule.message)
94
+ next
95
+ end
96
+
97
+ rule.message
98
+ end
299
99
  end
300
100
  end
301
101
  end