rubocop 1.39.0 → 1.42.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 (145) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +91 -10
  5. data/exe/rubocop +1 -1
  6. data/lib/rubocop/cli.rb +1 -1
  7. data/lib/rubocop/comment_config.rb +5 -0
  8. data/lib/rubocop/config.rb +39 -15
  9. data/lib/rubocop/config_loader.rb +14 -5
  10. data/lib/rubocop/config_loader_resolver.rb +6 -2
  11. data/lib/rubocop/config_validator.rb +1 -1
  12. data/lib/rubocop/cop/badge.rb +9 -4
  13. data/lib/rubocop/cop/base.rb +84 -74
  14. data/lib/rubocop/cop/commissioner.rb +8 -3
  15. data/lib/rubocop/cop/cop.rb +29 -29
  16. data/lib/rubocop/cop/corrector.rb +23 -11
  17. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +22 -6
  18. data/lib/rubocop/cop/gemspec/dependency_version.rb +16 -18
  19. data/lib/rubocop/cop/internal_affairs/cop_description.rb +3 -1
  20. data/lib/rubocop/cop/internal_affairs/lambda_or_proc.rb +46 -0
  21. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  22. data/lib/rubocop/cop/layout/class_structure.rb +32 -11
  23. data/lib/rubocop/cop/layout/comment_indentation.rb +3 -1
  24. data/lib/rubocop/cop/layout/empty_lines.rb +2 -0
  25. data/lib/rubocop/cop/layout/extra_spacing.rb +10 -6
  26. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +38 -2
  27. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +49 -2
  28. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +61 -2
  29. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +52 -2
  30. data/lib/rubocop/cop/layout/indentation_style.rb +7 -2
  31. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +5 -0
  32. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +11 -5
  33. data/lib/rubocop/cop/layout/line_length.rb +2 -0
  34. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +51 -2
  35. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
  36. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +49 -2
  37. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +53 -2
  38. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +58 -2
  39. data/lib/rubocop/cop/layout/redundant_line_break.rb +2 -2
  40. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  41. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +1 -1
  42. data/lib/rubocop/cop/layout/trailing_whitespace.rb +11 -4
  43. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  44. data/lib/rubocop/cop/lint/assignment_in_condition.rb +11 -1
  45. data/lib/rubocop/cop/lint/constant_resolution.rb +4 -0
  46. data/lib/rubocop/cop/lint/debugger.rb +3 -1
  47. data/lib/rubocop/cop/lint/deprecated_constants.rb +8 -1
  48. data/lib/rubocop/cop/lint/duplicate_branch.rb +0 -2
  49. data/lib/rubocop/cop/lint/duplicate_methods.rb +19 -8
  50. data/lib/rubocop/cop/lint/empty_block.rb +1 -5
  51. data/lib/rubocop/cop/lint/empty_conditional_body.rb +1 -1
  52. data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
  53. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -5
  54. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +19 -0
  55. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -0
  56. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +15 -3
  57. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  58. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
  59. data/lib/rubocop/cop/lint/require_parentheses.rb +3 -1
  60. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +10 -12
  61. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +5 -4
  62. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +4 -3
  63. data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -1
  64. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -3
  65. data/lib/rubocop/cop/lint/void.rb +6 -6
  66. data/lib/rubocop/cop/metrics/block_length.rb +9 -4
  67. data/lib/rubocop/cop/metrics/class_length.rb +10 -5
  68. data/lib/rubocop/cop/metrics/method_length.rb +9 -4
  69. data/lib/rubocop/cop/metrics/module_length.rb +10 -5
  70. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  71. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -4
  72. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +6 -3
  73. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  74. data/lib/rubocop/cop/mixin/allowed_identifiers.rb +2 -2
  75. data/lib/rubocop/cop/mixin/annotation_comment.rb +13 -6
  76. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +21 -9
  77. data/lib/rubocop/cop/mixin/first_element_line_break.rb +11 -7
  78. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +28 -5
  79. data/lib/rubocop/cop/mixin/line_length_help.rb +8 -1
  80. data/lib/rubocop/cop/mixin/method_complexity.rb +5 -3
  81. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +5 -3
  82. data/lib/rubocop/cop/mixin/percent_array.rb +3 -5
  83. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
  84. data/lib/rubocop/cop/mixin/require_library.rb +2 -0
  85. data/lib/rubocop/cop/mixin/rescue_node.rb +3 -3
  86. data/lib/rubocop/cop/mixin/statement_modifier.rb +15 -1
  87. data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
  88. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +2 -0
  89. data/lib/rubocop/cop/naming/inclusive_language.rb +4 -1
  90. data/lib/rubocop/cop/registry.rb +51 -36
  91. data/lib/rubocop/cop/security/compound_hash.rb +2 -1
  92. data/lib/rubocop/cop/style/alias.rb +9 -1
  93. data/lib/rubocop/cop/style/array_intersect.rb +111 -0
  94. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  95. data/lib/rubocop/cop/style/concat_array_literals.rb +86 -0
  96. data/lib/rubocop/cop/style/documentation.rb +11 -5
  97. data/lib/rubocop/cop/style/guard_clause.rb +44 -9
  98. data/lib/rubocop/cop/style/hash_syntax.rb +10 -7
  99. data/lib/rubocop/cop/style/identical_conditional_branches.rb +15 -0
  100. data/lib/rubocop/cop/style/if_with_semicolon.rb +4 -4
  101. data/lib/rubocop/cop/style/inverse_methods.rb +2 -0
  102. data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -1
  103. data/lib/rubocop/cop/style/map_to_set.rb +61 -0
  104. data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -4
  105. data/lib/rubocop/cop/style/min_max_comparison.rb +73 -0
  106. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  107. data/lib/rubocop/cop/style/redundant_argument.rb +3 -0
  108. data/lib/rubocop/cop/style/redundant_constant_base.rb +85 -0
  109. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +39 -0
  110. data/lib/rubocop/cop/style/redundant_return.rb +7 -0
  111. data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
  112. data/lib/rubocop/cop/style/redundant_string_escape.rb +6 -3
  113. data/lib/rubocop/cop/style/require_order.rb +142 -0
  114. data/lib/rubocop/cop/style/safe_navigation.rb +35 -6
  115. data/lib/rubocop/cop/style/select_by_regexp.rb +13 -5
  116. data/lib/rubocop/cop/style/semicolon.rb +2 -1
  117. data/lib/rubocop/cop/style/signal_exception.rb +8 -6
  118. data/lib/rubocop/cop/style/string_literals.rb +1 -5
  119. data/lib/rubocop/cop/style/symbol_proc.rb +2 -4
  120. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -4
  121. data/lib/rubocop/cop/style/word_array.rb +41 -0
  122. data/lib/rubocop/cop/style/yoda_expression.rb +74 -0
  123. data/lib/rubocop/cop/style/zero_length_predicate.rb +31 -14
  124. data/lib/rubocop/cop/team.rb +30 -30
  125. data/lib/rubocop/cop/util.rb +32 -5
  126. data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
  127. data/lib/rubocop/cop/variable_force.rb +17 -29
  128. data/lib/rubocop/cops_documentation_generator.rb +33 -11
  129. data/lib/rubocop/directive_comment.rb +1 -1
  130. data/lib/rubocop/file_patterns.rb +43 -0
  131. data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
  132. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  133. data/lib/rubocop/formatter.rb +5 -1
  134. data/lib/rubocop/options.rb +8 -0
  135. data/lib/rubocop/path_util.rb +39 -16
  136. data/lib/rubocop/result_cache.rb +2 -2
  137. data/lib/rubocop/rspec/cop_helper.rb +4 -1
  138. data/lib/rubocop/rspec/support.rb +2 -2
  139. data/lib/rubocop/runner.rb +10 -3
  140. data/lib/rubocop/server/core.rb +1 -1
  141. data/lib/rubocop/target_finder.rb +1 -1
  142. data/lib/rubocop/target_ruby.rb +1 -2
  143. data/lib/rubocop/version.rb +1 -1
  144. data/lib/rubocop.rb +19 -6
  145. metadata +19 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 881807be0f0f6eea20bd13bd8f08fdb158a5b155c8d3a22fd748683a68c1fef1
4
- data.tar.gz: 2a8e7d4b02f1ba468e02a4c20f8e3b830ce2a1d8ff0210f86aaeafab597c8c88
3
+ metadata.gz: e37ffc01dbd2782dd811d4c35129f893502179457e76d8e3501d7c3683563cc2
4
+ data.tar.gz: 9dba5be8e2168e986170e8366a62c73940262bfffec0a374c3a01b3f207ca291
5
5
  SHA512:
6
- metadata.gz: 11ea36bec754b07912e06b5481f964d10a6dbf5bfd56f99d8a8842ca46d56ae03a342a283d843336f977760c28a697ee995aa98268254a55b1218fa57a9fb5c7
7
- data.tar.gz: b5096cb4589d9bafdab0b6ab409ea9e7841dc06b274aeb7f7d5a26e703cb216c2a428d695fb2a087637467f1cdd5ac005398c66ee3e7d28d49cb4b203a87667d
6
+ metadata.gz: 23769dc5239a734dc07a859a594e1cc0b732d05d24c61c1887525f9f69f748e0c23cbb84404e865e00a04bfb5c91e73d1e0bdb7908a72340ede4245fc38508c6
7
+ data.tar.gz: f016891fb54e93a8f6c418d4aa97f7400a74c187c8cf5dbbe274020ea5bda900721f2a7fefbbb368472664cf21a4b586db4fb9373510c27da6428aa490d504e6
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-22 Bozhidar Batsov
1
+ Copyright (c) 2012-23 Bozhidar Batsov
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
53
53
  in your `Gemfile`:
54
54
 
55
55
  ```rb
56
- gem 'rubocop', '~> 1.39', require: false
56
+ gem 'rubocop', '~> 1.42', require: false
57
57
  ```
58
58
 
59
59
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
@@ -246,5 +246,5 @@ RuboCop's changelog is available [here](CHANGELOG.md).
246
246
 
247
247
  ## Copyright
248
248
 
249
- Copyright (c) 2012-2022 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for
249
+ Copyright (c) 2012-2023 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for
250
250
  further details.
data/config/default.yml CHANGED
@@ -161,7 +161,9 @@ AllCops:
161
161
  Bundler/DuplicatedGem:
162
162
  Description: 'Checks for duplicate gem entries in Gemfile.'
163
163
  Enabled: true
164
+ Severity: warning
164
165
  VersionAdded: '0.46'
166
+ VersionChanged: '1.40'
165
167
  Include:
166
168
  - '**/*.gemfile'
167
169
  - '**/Gemfile'
@@ -213,7 +215,9 @@ Bundler/InsecureProtocolSource:
213
215
  because HTTP requests are insecure. Please change your source to
214
216
  'https://rubygems.org' if possible, or 'http://rubygems.org' if not.
215
217
  Enabled: true
218
+ Severity: warning
216
219
  VersionAdded: '0.50'
220
+ VersionChanged: '1.40'
217
221
  AllowHttpProtocol: true
218
222
  Include:
219
223
  - '**/*.gemfile'
@@ -252,14 +256,18 @@ Gemspec/DependencyVersion:
252
256
  Gemspec/DeprecatedAttributeAssignment:
253
257
  Description: Checks that deprecated attribute assignments are not set in a gemspec file.
254
258
  Enabled: pending
259
+ Severity: warning
255
260
  VersionAdded: '1.30'
261
+ VersionChanged: '1.40'
256
262
  Include:
257
263
  - '**/*.gemspec'
258
264
 
259
265
  Gemspec/DuplicatedAssignment:
260
266
  Description: 'An attribute assignment method calls should be listed only once in a gemspec.'
261
267
  Enabled: true
268
+ Severity: warning
262
269
  VersionAdded: '0.52'
270
+ VersionChanged: '1.40'
263
271
  Include:
264
272
  - '**/*.gemspec'
265
273
 
@@ -278,7 +286,9 @@ Gemspec/OrderedDependencies:
278
286
  Gemspec/RequireMFA:
279
287
  Description: 'Checks that the gemspec has metadata to require Multi-Factor Authentication from RubyGems.'
280
288
  Enabled: pending
289
+ Severity: warning
281
290
  VersionAdded: '1.23'
291
+ VersionChanged: '1.40'
282
292
  Reference:
283
293
  - https://guides.rubygems.org/mfa-requirement-opt-in/
284
294
  Include:
@@ -287,8 +297,9 @@ Gemspec/RequireMFA:
287
297
  Gemspec/RequiredRubyVersion:
288
298
  Description: 'Checks that `required_ruby_version` of gemspec is specified and equal to `TargetRubyVersion` of .rubocop.yml.'
289
299
  Enabled: true
300
+ Severity: warning
290
301
  VersionAdded: '0.52'
291
- VersionChanged: '1.22'
302
+ VersionChanged: '1.40'
292
303
  Include:
293
304
  - '**/*.gemspec'
294
305
 
@@ -296,7 +307,9 @@ Gemspec/RubyVersionGlobalsUsage:
296
307
  Description: Checks usage of RUBY_VERSION in gemspec.
297
308
  StyleGuide: '#no-ruby-version-in-the-gemspec'
298
309
  Enabled: true
310
+ Severity: warning
299
311
  VersionAdded: '0.72'
312
+ VersionChanged: '1.40'
300
313
  Include:
301
314
  - '**/*.gemspec'
302
315
 
@@ -378,8 +391,9 @@ Layout/AssignmentIndentation:
378
391
  Checks the indentation of the first line of the
379
392
  right-hand-side of a multi-line assignment.
380
393
  Enabled: true
394
+ SafeAutoCorrect: false
381
395
  VersionAdded: '0.49'
382
- VersionChanged: '0.77'
396
+ VersionChanged: '1.40'
383
397
  # By default the indentation width from `Layout/IndentationWidth` is used,
384
398
  # but it can be overridden by setting this parameter.
385
399
  IndentationWidth: ~
@@ -748,6 +762,7 @@ Layout/FirstArrayElementLineBreak:
748
762
  multi-line array.
749
763
  Enabled: false
750
764
  VersionAdded: '0.49'
765
+ AllowMultilineFinalElement: false
751
766
 
752
767
  Layout/FirstHashElementIndentation:
753
768
  Description: 'Checks the indentation of the first key in a hash literal.'
@@ -780,6 +795,7 @@ Layout/FirstHashElementLineBreak:
780
795
  multi-line hash.
781
796
  Enabled: false
782
797
  VersionAdded: '0.49'
798
+ AllowMultilineFinalElement: false
783
799
 
784
800
  Layout/FirstMethodArgumentLineBreak:
785
801
  Description: >-
@@ -787,6 +803,7 @@ Layout/FirstMethodArgumentLineBreak:
787
803
  multi-line method call.
788
804
  Enabled: false
789
805
  VersionAdded: '0.49'
806
+ AllowMultilineFinalElement: false
790
807
 
791
808
  Layout/FirstMethodParameterLineBreak:
792
809
  Description: >-
@@ -794,6 +811,7 @@ Layout/FirstMethodParameterLineBreak:
794
811
  multi-line method parameter definition.
795
812
  Enabled: false
796
813
  VersionAdded: '0.49'
814
+ AllowMultilineFinalElement: false
797
815
 
798
816
  Layout/FirstParameterIndentation:
799
817
  Description: >-
@@ -1053,6 +1071,7 @@ Layout/MultilineArrayLineBreaks:
1053
1071
  starts on a separate line.
1054
1072
  Enabled: false
1055
1073
  VersionAdded: '0.67'
1074
+ AllowMultilineFinalElement: false
1056
1075
 
1057
1076
  Layout/MultilineAssignmentLayout:
1058
1077
  Description: 'Check for a newline after the assignment operator in multi-line assignments.'
@@ -1103,6 +1122,7 @@ Layout/MultilineHashKeyLineBreaks:
1103
1122
  starts on a separate line.
1104
1123
  Enabled: false
1105
1124
  VersionAdded: '0.67'
1125
+ AllowMultilineFinalElement: false
1106
1126
 
1107
1127
  Layout/MultilineMethodArgumentLineBreaks:
1108
1128
  Description: >-
@@ -1110,6 +1130,7 @@ Layout/MultilineMethodArgumentLineBreaks:
1110
1130
  starts on a separate line.
1111
1131
  Enabled: false
1112
1132
  VersionAdded: '0.67'
1133
+ AllowMultilineFinalElement: false
1113
1134
 
1114
1135
  Layout/MultilineMethodCallBraceLayout:
1115
1136
  Description: >-
@@ -1164,6 +1185,7 @@ Layout/MultilineMethodParameterLineBreaks:
1164
1185
  starts on a separate line.
1165
1186
  Enabled: false
1166
1187
  VersionAdded: '1.32'
1188
+ AllowMultilineFinalElement: false
1167
1189
 
1168
1190
  Layout/MultilineOperationIndentation:
1169
1191
  Description: >-
@@ -1643,7 +1665,7 @@ Lint/DeprecatedConstants:
1643
1665
  Description: 'Checks for deprecated constants.'
1644
1666
  Enabled: pending
1645
1667
  VersionAdded: '1.8'
1646
- VersionChanged: '1.22'
1668
+ VersionChanged: '1.40'
1647
1669
  # You can configure deprecated constants.
1648
1670
  # If there is an alternative method, you can set alternative value as `Alternative`.
1649
1671
  # And you can set the deprecated version as `DeprecatedVersion`.
@@ -1670,6 +1692,12 @@ Lint/DeprecatedConstants:
1670
1692
  'Random::DEFAULT':
1671
1693
  Alternative: 'Random.new'
1672
1694
  DeprecatedVersion: '3.0'
1695
+ 'Struct::Group':
1696
+ Alternative: 'Etc::Group'
1697
+ DeprecatedVersion: '3.0'
1698
+ 'Struct::Passwd':
1699
+ Alternative: 'Etc::Passwd'
1700
+ DeprecatedVersion: '3.0'
1673
1701
 
1674
1702
  Lint/DeprecatedOpenSSLConstant:
1675
1703
  Description: "Don't use algorithm constants for `OpenSSL::Cipher` and `OpenSSL::Digest`."
@@ -1894,11 +1922,11 @@ Lint/InheritException:
1894
1922
  - runtime_error
1895
1923
 
1896
1924
  Lint/InterpolationCheck:
1897
- Description: 'Raise warning for interpolation in single q strs.'
1925
+ Description: 'Checks for interpolation in a single quoted string.'
1898
1926
  Enabled: true
1899
- Safe: false
1927
+ SafeAutoCorrect: false
1900
1928
  VersionAdded: '0.50'
1901
- VersionChanged: '0.87'
1929
+ VersionChanged: '1.40'
1902
1930
 
1903
1931
  Lint/LambdaWithoutLiteralBlock:
1904
1932
  Description: 'Checks uses of lambda without a literal block.'
@@ -2806,6 +2834,7 @@ Naming/MethodParameterName:
2806
2834
  - as
2807
2835
  - at
2808
2836
  - by
2837
+ - cc
2809
2838
  - db
2810
2839
  - id
2811
2840
  - if
@@ -3013,6 +3042,11 @@ Style/ArrayCoercion:
3013
3042
  Enabled: false
3014
3043
  VersionAdded: '0.88'
3015
3044
 
3045
+ Style/ArrayIntersect:
3046
+ Description: 'Use `array1.intersect?(array2)` instead of `(array1 & array2).any?`.'
3047
+ Enabled: 'pending'
3048
+ VersionAdded: '1.40'
3049
+
3016
3050
  Style/ArrayJoin:
3017
3051
  Description: 'Use Array#join instead of Array#*.'
3018
3052
  StyleGuide: '#array-join'
@@ -3392,6 +3426,12 @@ Style/CommentedKeyword:
3392
3426
  VersionAdded: '0.51'
3393
3427
  VersionChanged: '1.19'
3394
3428
 
3429
+ Style/ConcatArrayLiterals:
3430
+ Description: 'Enforces the use of `Array#push(item)` instead of `Array#concat([item])` to avoid redundant array literals.'
3431
+ Enabled: pending
3432
+ Safe: false
3433
+ VersionAdded: '1.41'
3434
+
3395
3435
  Style/ConditionalAssignment:
3396
3436
  Description: >-
3397
3437
  Use the return value of `if` and `case` statements for
@@ -3861,7 +3901,7 @@ Style/HashSyntax:
3861
3901
  - never
3862
3902
  # accepts both shorthand and explicit use of hash literal value.
3863
3903
  - either
3864
- # like "either", but will avoid mixing styles in a single hash
3904
+ # forces use of the 3.1 syntax only if all values can be omitted in the hash.
3865
3905
  - consistent
3866
3906
  # Force hashes that have a symbol value to use hash rockets
3867
3907
  UseHashRocketsWithSymbolValues: false
@@ -4070,6 +4110,12 @@ Style/MapToHash:
4070
4110
  VersionAdded: '1.24'
4071
4111
  Safe: false
4072
4112
 
4113
+ Style/MapToSet:
4114
+ Description: 'Prefer `to_set` with a block over `map.to_set`.'
4115
+ Enabled: pending
4116
+ Safe: false
4117
+ VersionAdded: '1.42'
4118
+
4073
4119
  Style/MethodCallWithArgsParentheses:
4074
4120
  Description: 'Use parentheses for method calls with arguments.'
4075
4121
  StyleGuide: '#method-invocation-parens'
@@ -4128,6 +4174,12 @@ Style/MinMax:
4128
4174
  Enabled: true
4129
4175
  VersionAdded: '0.50'
4130
4176
 
4177
+ Style/MinMaxComparison:
4178
+ Description: 'Enforces the use of `max` or `min` instead of comparison for greater or less.'
4179
+ Enabled: pending
4180
+ Safe: false
4181
+ VersionAdded: '1.42'
4182
+
4131
4183
  Style/MissingElse:
4132
4184
  Description: >-
4133
4185
  Require if/case expressions to have an else branches.
@@ -4660,10 +4712,12 @@ Style/RedundantArgument:
4660
4712
  Enabled: pending
4661
4713
  Safe: false
4662
4714
  VersionAdded: '1.4'
4663
- VersionChanged: '1.7'
4715
+ VersionChanged: '1.40'
4664
4716
  Methods:
4665
4717
  # Array#join
4666
4718
  join: ''
4719
+ # Array#sum
4720
+ sum: 0
4667
4721
  # String#split
4668
4722
  split: ' '
4669
4723
  # String#chomp
@@ -4698,6 +4752,16 @@ Style/RedundantConditional:
4698
4752
  Enabled: true
4699
4753
  VersionAdded: '0.50'
4700
4754
 
4755
+ Style/RedundantConstantBase:
4756
+ Description: Avoid redundant `::` prefix on constant.
4757
+ Enabled: pending
4758
+ VersionAdded: '1.40'
4759
+
4760
+ Style/RedundantDoubleSplatHashBraces:
4761
+ Description: 'Checks for redundant uses of double splat hash braces.'
4762
+ Enabled: pending
4763
+ VersionAdded: '1.41'
4764
+
4701
4765
  Style/RedundantEach:
4702
4766
  Description: 'Checks for redundant `each`.'
4703
4767
  Enabled: pending
@@ -4838,6 +4902,12 @@ Style/RegexpLiteral:
4838
4902
  # are found in the regexp string.
4839
4903
  AllowInnerSlashes: false
4840
4904
 
4905
+ Style/RequireOrder:
4906
+ Description: Sort `require` and `require_relative` in alphabetical order.
4907
+ Enabled: false
4908
+ SafeAutoCorrect: false
4909
+ VersionAdded: '1.40'
4910
+
4841
4911
  Style/RescueModifier:
4842
4912
  Description: 'Avoid using rescue in its modifier form.'
4843
4913
  StyleGuide: '#no-rescue-modifiers'
@@ -5122,12 +5192,11 @@ Style/SymbolProc:
5122
5192
  Enabled: true
5123
5193
  Safe: false
5124
5194
  VersionAdded: '0.26'
5125
- VersionChanged: '1.28'
5195
+ VersionChanged: '1.40'
5126
5196
  AllowMethodsWithArguments: false
5127
5197
  # A list of method names to be always allowed by the check.
5128
5198
  # The names should be fairly unique, otherwise you'll end up ignoring lots of code.
5129
5199
  AllowedMethods:
5130
- - respond_to
5131
5200
  - define_method
5132
5201
  AllowedPatterns: []
5133
5202
  IgnoredMethods: [] # deprecated
@@ -5369,6 +5438,18 @@ Style/YodaCondition:
5369
5438
  VersionAdded: '0.49'
5370
5439
  VersionChanged: '0.75'
5371
5440
 
5441
+ Style/YodaExpression:
5442
+ Description: 'Forbid the use of yoda expressions.'
5443
+ Enabled: pending
5444
+ Safe: false
5445
+ VersionAdded: '1.42'
5446
+ SupportedOperators:
5447
+ - '*'
5448
+ - '+'
5449
+ - '&'
5450
+ - '|'
5451
+ - '^'
5452
+
5372
5453
  Style/ZeroLengthPredicate:
5373
5454
  Description: 'Use #empty? when testing for objects of length 0.'
5374
5455
  Enabled: true
data/exe/rubocop CHANGED
@@ -11,8 +11,8 @@ exit exit_status if server_cli.exit?
11
11
  if RuboCop::Server.running?
12
12
  exit_status = RuboCop::Server::ClientCommand::Exec.new.run
13
13
  else
14
- require 'rubocop'
15
14
  require 'benchmark'
15
+ require 'rubocop'
16
16
 
17
17
  cli = RuboCop::CLI.new
18
18
 
data/lib/rubocop/cli.rb CHANGED
@@ -7,7 +7,7 @@ module RuboCop
7
7
  STATUS_SUCCESS = 0
8
8
  STATUS_OFFENSES = 1
9
9
  STATUS_ERROR = 2
10
- STATUS_INTERRUPTED = 128 + Signal.list['INT']
10
+ STATUS_INTERRUPTED = Signal.list['INT'] + 128
11
11
  DEFAULT_PARALLEL_OPTIONS = %i[
12
12
  color debug display_style_guide display_time display_only_fail_level_offenses
13
13
  display_only_failed except extra_details fail_level fix_layout format
@@ -31,6 +31,7 @@ module RuboCop
31
31
 
32
32
  def initialize(processed_source)
33
33
  @processed_source = processed_source
34
+ @no_directives = !processed_source.raw_source.include?('rubocop')
34
35
  end
35
36
 
36
37
  def cop_enabled_at_line?(cop, line_number)
@@ -74,6 +75,8 @@ module RuboCop
74
75
  end
75
76
 
76
77
  def analyze # rubocop:todo Metrics/AbcSize
78
+ return {} if @no_directives
79
+
77
80
  analyses = Hash.new { |hash, key| hash[key] = CopAnalysis.new([], nil) }
78
81
  inject_disabled_cops_directives(analyses)
79
82
 
@@ -146,6 +149,8 @@ module RuboCop
146
149
  end
147
150
 
148
151
  def each_directive
152
+ return if @no_directives
153
+
149
154
  processed_source.comments.each do |comment|
150
155
  directive = DirectiveComment.new(comment)
151
156
  yield directive if directive.cop_names
@@ -21,24 +21,30 @@ module RuboCop
21
21
  DEFAULT_RAILS_VERSION = 5.0
22
22
  attr_reader :loaded_path
23
23
 
24
+ def self.create(hash, path, check: true)
25
+ config = new(hash, path)
26
+ config.check if check
27
+
28
+ config
29
+ end
30
+
31
+ # rubocop:disable Metrics/AbcSize
24
32
  def initialize(hash = {}, loaded_path = nil)
25
33
  @loaded_path = loaded_path
26
34
  @for_cop = Hash.new do |h, cop|
27
- qualified_cop_name = Cop::Registry.qualified_cop_name(cop, loaded_path)
35
+ cop_name = cop.respond_to?(:cop_name) ? cop.cop_name : cop
36
+ qualified_cop_name = Cop::Registry.qualified_cop_name(cop_name, loaded_path)
28
37
  cop_options = self[qualified_cop_name].dup || {}
29
38
  cop_options['Enabled'] = enable_cop?(qualified_cop_name, cop_options)
30
- h[cop] = cop_options
39
+ h[cop] = h[cop_name] = cop_options
31
40
  end
32
41
  @hash = hash
33
42
  @validator = ConfigValidator.new(self)
34
- end
35
43
 
36
- def self.create(hash, path, check: true)
37
- config = new(hash, path)
38
- config.check if check
39
-
40
- config
44
+ @badge_config_cache = {}.compare_by_identity
45
+ @clusivity_config_exists_cache = {}
41
46
  end
47
+ # rubocop:enable Metrics/AbcSize
42
48
 
43
49
  def loaded_features
44
50
  @loaded_features ||= ConfigLoader.loaded_features
@@ -116,14 +122,31 @@ module RuboCop
116
122
  # Note: the 'Enabled' attribute is calculated according to the department's
117
123
  # and 'AllCops' configuration; other attributes are not inherited.
118
124
  def for_cop(cop)
119
- @for_cop[cop.respond_to?(:cop_name) ? cop.cop_name : cop]
125
+ @for_cop[cop]
120
126
  end
121
127
 
122
128
  # @return [Config] for the given cop merged with that of its department (if any)
123
129
  # Note: the 'Enabled' attribute is same as that returned by `for_cop`
124
130
  def for_badge(badge)
125
- cop_config = for_cop(badge.to_s)
126
- fetch(badge.department.to_s) { return cop_config }.merge(cop_config)
131
+ @badge_config_cache[badge] ||= begin
132
+ department_config = self[badge.department_name]
133
+ cop_config = for_cop(badge.to_s)
134
+ if department_config
135
+ department_config.merge(cop_config)
136
+ else
137
+ cop_config
138
+ end
139
+ end
140
+ end
141
+
142
+ # @return [Boolean] whether config for this badge has 'Include' or 'Exclude' keys
143
+ # @api private
144
+ def clusivity_config_for_badge?(badge)
145
+ exists = @clusivity_config_exists_cache[badge.to_s]
146
+ return exists unless exists.nil?
147
+
148
+ cop_config = for_badge(badge)
149
+ @clusivity_config_exists_cache[badge.to_s] = cop_config['Include'] || cop_config['Exclude']
127
150
  end
128
151
 
129
152
  # @return [Config] for the given department name.
@@ -215,7 +238,7 @@ module RuboCop
215
238
  # directory since that wouldn't work.
216
239
  def base_dir_for_path_parameters
217
240
  @base_dir_for_path_parameters ||=
218
- if File.basename(loaded_path).start_with?('.rubocop') &&
241
+ if loaded_path && File.basename(loaded_path).start_with?('.rubocop') &&
219
242
  loaded_path != File.join(Dir.home, ConfigLoader::DOTFILE)
220
243
  File.expand_path(File.dirname(loaded_path))
221
244
  else
@@ -272,9 +295,10 @@ module RuboCop
272
295
  return nil unless lock_file_path
273
296
 
274
297
  File.foreach(lock_file_path) do |line|
275
- # If rails is in Gemfile.lock or gems.lock, there should be a line like:
276
- # rails (X.X.X)
277
- result = line.match(/^\s+rails\s+\((\d+\.\d+)/)
298
+ # If Rails (or one of its frameworks) is in Gemfile.lock or gems.lock, there should be
299
+ # a line like:
300
+ # railties (X.X.X)
301
+ result = line.match(/^\s+railties\s+\((\d+\.\d+)/)
278
302
  return result.captures.first.to_f if result
279
303
  end
280
304
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'erb'
4
- require 'yaml'
5
4
  require 'pathname'
5
+ require 'yaml'
6
6
  require_relative 'config_finder'
7
7
 
8
8
  module RuboCop
@@ -42,18 +42,18 @@ module RuboCop
42
42
 
43
43
  hash = load_yaml_configuration(path)
44
44
 
45
- # Resolve requires first in case they define additional cops
46
45
  loaded_features = resolver.resolve_requires(path, hash)
47
46
  add_loaded_features(loaded_features)
48
47
 
49
- add_missing_namespaces(path, hash)
50
-
51
48
  resolver.override_department_setting_for_cops({}, hash)
52
49
  resolver.resolve_inheritance_from_gems(hash)
53
50
  resolver.resolve_inheritance(path, hash, file, debug?)
54
-
55
51
  hash.delete('inherit_from')
56
52
 
53
+ # Adding missing namespaces only after resolving requires & inheritance,
54
+ # since both can introduce new cops that need to be considered here.
55
+ add_missing_namespaces(path, hash)
56
+
57
57
  Config.create(hash, path, check: check)
58
58
  end
59
59
 
@@ -137,6 +137,15 @@ module RuboCop
137
137
  end
138
138
  end
139
139
 
140
+ # @api private
141
+ def inject_defaults!(project_root)
142
+ path = File.join(project_root, 'config', 'default.yml')
143
+ config = load_file(path)
144
+ new_config = ConfigLoader.merge_with_default(config, path)
145
+ puts "configuration from #{path}" if debug?
146
+ @default_configuration = new_config
147
+ end
148
+
140
149
  # Returns the path RuboCop inferred as the root of the project. No file
141
150
  # searches will go past this directory.
142
151
  # @deprecated Use `RuboCop::ConfigFinder.project_root` instead.
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'yaml'
4
3
  require 'pathname'
4
+ require 'yaml'
5
5
 
6
6
  module RuboCop
7
7
  # A help class for ConfigLoader that handles configuration resolution.
@@ -206,7 +206,11 @@ module RuboCop
206
206
  end
207
207
 
208
208
  def base_configs(path, inherit_from, file)
209
- configs = Array(inherit_from).compact.map do |f|
209
+ inherit_froms = Array(inherit_from).compact.flat_map do |f|
210
+ PathUtil.glob?(f) ? Dir.glob(f) : f
211
+ end
212
+
213
+ configs = inherit_froms.map do |f|
210
214
  ConfigLoader.load_file(inherited_file(path, f, file))
211
215
  end
212
216
 
@@ -162,7 +162,7 @@ module RuboCop
162
162
  return unless syntax_config && default_config.merge(syntax_config) != default_config
163
163
 
164
164
  raise ValidationError,
165
- "configuration for Syntax cop found in #{smart_loaded_path}\n" \
165
+ "configuration for Lint/Syntax cop found in #{smart_loaded_path}\n" \
166
166
  'It\'s not possible to disable this cop.'
167
167
  end
168
168
 
@@ -10,7 +10,7 @@ module RuboCop
10
10
  # allow for badge references in source files that omit the department for
11
11
  # RuboCop to infer.
12
12
  class Badge
13
- attr_reader :department, :cop_name
13
+ attr_reader :department, :department_name, :cop_name
14
14
 
15
15
  def self.for(class_name)
16
16
  parts = class_name.split('::')
@@ -18,19 +18,23 @@ module RuboCop
18
18
  new(name_deep_enough ? parts[2..] : parts.last(2))
19
19
  end
20
20
 
21
+ @parse_cache = {}
22
+
21
23
  def self.parse(identifier)
22
- new(identifier.split('/').map { |i| camel_case(i) })
24
+ @parse_cache[identifier] ||= new(identifier.split('/').map! { |i| camel_case(i) })
23
25
  end
24
26
 
25
27
  def self.camel_case(name_part)
26
28
  return 'RSpec' if name_part == 'rspec'
29
+ return name_part unless name_part.match?(/^[a-z]|_[a-z]/)
27
30
 
28
- name_part.gsub(/^\w|_\w/) { |match| match[-1, 1].upcase }
31
+ name_part.gsub(/^[a-z]|_[a-z]/) { |match| match[-1, 1].upcase }
29
32
  end
30
33
 
31
34
  def initialize(class_name_parts)
32
35
  department_parts = class_name_parts[0...-1]
33
36
  @department = (department_parts.join('/').to_sym unless department_parts.empty?)
37
+ @department_name = @department&.to_s
34
38
  @cop_name = class_name_parts.last
35
39
  end
36
40
 
@@ -40,7 +44,8 @@ module RuboCop
40
44
  alias eql? ==
41
45
 
42
46
  def hash
43
- [department, cop_name].hash
47
+ # Do hashing manually to reduce Array allocations.
48
+ department.hash ^ cop_name.hash # rubocop:disable Security/CompoundHash
44
49
  end
45
50
 
46
51
  def match?(other)