rubocop 1.31.1 → 1.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +68 -16
  4. data/config/obsoletion.yml +23 -1
  5. data/lib/rubocop/cache_config.rb +29 -0
  6. data/lib/rubocop/cli/command/auto_genenerate_config.rb +2 -2
  7. data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
  8. data/lib/rubocop/cli.rb +1 -0
  9. data/lib/rubocop/config.rb +1 -1
  10. data/lib/rubocop/config_finder.rb +68 -0
  11. data/lib/rubocop/config_loader.rb +5 -45
  12. data/lib/rubocop/config_loader_resolver.rb +1 -1
  13. data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
  14. data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
  15. data/lib/rubocop/config_obsoletion.rb +7 -2
  16. data/lib/rubocop/cop/base.rb +1 -1
  17. data/lib/rubocop/cop/generator.rb +4 -0
  18. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +60 -0
  19. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  20. data/lib/rubocop/cop/layout/block_end_newline.rb +32 -5
  21. data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -1
  22. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +4 -3
  23. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +3 -3
  24. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +57 -13
  25. data/lib/rubocop/cop/layout/line_length.rb +2 -0
  26. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -1
  27. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +45 -0
  28. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +26 -6
  29. data/lib/rubocop/cop/lint/debugger.rb +11 -1
  30. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +10 -4
  31. data/lib/rubocop/cop/lint/empty_conditional_body.rb +60 -1
  32. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +60 -25
  33. data/lib/rubocop/cop/lint/number_conversion.rb +28 -6
  34. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +7 -0
  35. data/lib/rubocop/cop/lint/require_range_parentheses.rb +57 -0
  36. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +35 -1
  37. data/lib/rubocop/cop/metrics/abc_size.rb +3 -1
  38. data/lib/rubocop/cop/metrics/block_length.rb +6 -6
  39. data/lib/rubocop/cop/metrics/method_length.rb +8 -7
  40. data/lib/rubocop/cop/mixin/allowed_methods.rb +15 -1
  41. data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -1
  42. data/lib/rubocop/cop/mixin/check_line_breakable.rb +4 -0
  43. data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
  44. data/lib/rubocop/cop/mixin/def_node.rb +2 -7
  45. data/lib/rubocop/cop/mixin/method_complexity.rb +4 -9
  46. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +6 -13
  47. data/lib/rubocop/cop/mixin/percent_array.rb +60 -1
  48. data/lib/rubocop/cop/naming/predicate_name.rb +30 -1
  49. data/lib/rubocop/cop/style/block_delimiters.rb +26 -7
  50. data/lib/rubocop/cop/style/class_and_module_children.rb +4 -4
  51. data/lib/rubocop/cop/style/class_equality_comparison.rb +50 -3
  52. data/lib/rubocop/cop/style/empty_else.rb +37 -0
  53. data/lib/rubocop/cop/style/empty_heredoc.rb +73 -0
  54. data/lib/rubocop/cop/style/fetch_env_var.rb +10 -177
  55. data/lib/rubocop/cop/style/format_string_token.rb +25 -6
  56. data/lib/rubocop/cop/style/hash_except.rb +0 -4
  57. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
  58. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
  59. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -7
  60. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +19 -2
  61. data/lib/rubocop/cop/style/module_function.rb +2 -2
  62. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +9 -0
  63. data/lib/rubocop/cop/style/numeric_predicate.rb +43 -9
  64. data/lib/rubocop/cop/style/redundant_condition.rb +19 -4
  65. data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -1
  66. data/lib/rubocop/cop/style/redundant_sort.rb +21 -6
  67. data/lib/rubocop/cop/style/semicolon.rb +27 -3
  68. data/lib/rubocop/cop/style/symbol_array.rb +2 -3
  69. data/lib/rubocop/cop/style/symbol_proc.rb +35 -7
  70. data/lib/rubocop/cop/style/trivial_accessors.rb +3 -0
  71. data/lib/rubocop/cop/style/word_array.rb +2 -3
  72. data/lib/rubocop/options.rb +3 -6
  73. data/lib/rubocop/rake_task.rb +5 -1
  74. data/lib/rubocop/result_cache.rb +22 -20
  75. data/lib/rubocop/rspec/shared_contexts.rb +14 -14
  76. data/lib/rubocop/rspec/support.rb +14 -0
  77. data/lib/rubocop/runner.rb +4 -0
  78. data/lib/rubocop/server/cache.rb +33 -1
  79. data/lib/rubocop/server/cli.rb +19 -2
  80. data/lib/rubocop/server/client_command/base.rb +1 -1
  81. data/lib/rubocop/version.rb +1 -1
  82. data/lib/rubocop.rb +4 -2
  83. metadata +12 -7
  84. data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e6cb927ae20cdc9cc2258d8f57b483c0fad68f03563e4f4a1823070510c8fac
4
- data.tar.gz: 68a3e3f99f11ef787da421d67a2674027c425978e494fd7ab6c1ea0a614748df
3
+ metadata.gz: 141b5fc0ee48c7fdf1fc347bb2b59b59933f6d46f575cfb4f380bfc101090345
4
+ data.tar.gz: 862c5d1952e777ec19bd1b8782c9e98e065c3d80db7a7d2c91da4406afeb886c
5
5
  SHA512:
6
- metadata.gz: 991b16c032399b14752c8a71ad92d3e2000c57941eafdace759cc5cb4f7a8f18dc58952597575375cb2a7df425ffffd1e2b029dabc9d98834c5142cc38435382
7
- data.tar.gz: f92f9b6704829816959e3ccd8c61fa439dfd75cbc09a145028de9d8cae2a636946da775b49e35a7b42a78d9af288969e72afaeb1b2fd47235a9e83201cdf4df7
6
+ metadata.gz: 2be012822408e3aa884dfe85e8a2153144f53d47550a0f7233a60448a8ab18c5c5411959742a4cb9652e972451f05cf0d447451eba53e46260baefa8f2c234e6
7
+ data.tar.gz: 063e8ef0056793c86aee9f952db454eac5422c369bdf1ce4a719fcc21279214b86a800f58229b0ade17b963fb2c8e49608bd1883c840d8370b207b3aa4ee916c
data/README.md CHANGED
@@ -46,14 +46,14 @@ If you'd rather install RuboCop using `bundler`, add a line for it in your `Gemf
46
46
  gem 'rubocop', require: false
47
47
  ```
48
48
 
49
- RuboCop is stable between major versions, both in terms of API and cop configuration.
49
+ RuboCop is stable between minor versions, both in terms of API and cop configuration.
50
50
  We aim to ease the maintenance of RuboCop extensions and the upgrades between RuboCop
51
51
  releases. All big changes are reserved for major releases.
52
52
  To prevent an unwanted RuboCop update you might want to use a conservative version lock
53
53
  in your `Gemfile`:
54
54
 
55
55
  ```rb
56
- gem 'rubocop', '~> 1.31', require: false
56
+ gem 'rubocop', '~> 1.33', require: false
57
57
  ```
58
58
 
59
59
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
data/config/default.yml CHANGED
@@ -977,6 +977,11 @@ Layout/LineContinuationLeadingSpace:
977
977
  AutoCorrect: false
978
978
  SafeAutoCorrect: false
979
979
  VersionAdded: '1.31'
980
+ VersionChanged: '1.32'
981
+ EnforcedStyle: trailing
982
+ SupportedStyles:
983
+ - leading
984
+ - trailing
980
985
 
981
986
  Layout/LineContinuationSpacing:
982
987
  Description: 'Checks the spacing in front of backslash in line continuations.'
@@ -1153,6 +1158,13 @@ Layout/MultilineMethodDefinitionBraceLayout:
1153
1158
  - new_line
1154
1159
  - same_line
1155
1160
 
1161
+ Layout/MultilineMethodParameterLineBreaks:
1162
+ Description: >-
1163
+ Checks that each parameter in a multi-line method definition
1164
+ starts on a separate line.
1165
+ Enabled: false
1166
+ VersionAdded: '1.32'
1167
+
1156
1168
  Layout/MultilineOperationIndentation:
1157
1169
  Description: >-
1158
1170
  Checks indentation of binary operations that span more than
@@ -1490,7 +1502,9 @@ Lint/AmbiguousBlockAssociation:
1490
1502
  Enabled: true
1491
1503
  VersionAdded: '0.48'
1492
1504
  VersionChanged: '1.13'
1493
- IgnoredMethods: []
1505
+ AllowedMethods: []
1506
+ AllowedPatterns: []
1507
+ IgnoredMethods: [] # deprecated
1494
1508
 
1495
1509
  Lint/AmbiguousOperator:
1496
1510
  Description: >-
@@ -1741,6 +1755,7 @@ Lint/EmptyConditionalBody:
1741
1755
  Enabled: true
1742
1756
  AllowComments: true
1743
1757
  VersionAdded: '0.89'
1758
+ VersionChanged: '1.33'
1744
1759
 
1745
1760
  Lint/EmptyEnsure:
1746
1761
  Description: 'Checks for empty ensure block.'
@@ -1958,6 +1973,7 @@ Lint/NoReturnInBeginEndBlocks:
1958
1973
 
1959
1974
  Lint/NonAtomicFileOperation:
1960
1975
  Description: Checks for non-atomic file operations.
1976
+ StyleGuide: '#atomic-file-operations'
1961
1977
  Enabled: pending
1962
1978
  VersionAdded: '1.31'
1963
1979
  SafeAutoCorrect: false
@@ -1979,7 +1995,9 @@ Lint/NumberConversion:
1979
1995
  VersionAdded: '0.53'
1980
1996
  VersionChanged: '1.1'
1981
1997
  SafeAutoCorrect: false
1982
- IgnoredMethods: []
1998
+ AllowedMethods: []
1999
+ AllowedPatterns: []
2000
+ IgnoredMethods: [] # deprecated
1983
2001
  IgnoredClasses:
1984
2002
  - Time
1985
2003
  - DateTime
@@ -2128,6 +2146,11 @@ Lint/RequireParentheses:
2128
2146
  Enabled: true
2129
2147
  VersionAdded: '0.18'
2130
2148
 
2149
+ Lint/RequireRangeParentheses:
2150
+ Description: 'Checks that a range literal is enclosed in parentheses when the end of the range is at a line break.'
2151
+ Enabled: pending
2152
+ VersionAdded: '1.32'
2153
+
2131
2154
  Lint/RequireRelativeSelfPath:
2132
2155
  Description: 'Checks for uses a file requiring itself with `require_relative`.'
2133
2156
  Enabled: pending
@@ -2426,7 +2449,9 @@ Metrics/AbcSize:
2426
2449
  VersionChanged: '1.5'
2427
2450
  # The ABC size is a calculated magnitude, so this number can be an Integer or
2428
2451
  # a Float.
2429
- IgnoredMethods: []
2452
+ AllowedMethods: []
2453
+ AllowedPatterns: []
2454
+ IgnoredMethods: [] # deprecated
2430
2455
  CountRepeatedAttributes: true
2431
2456
  Max: 17
2432
2457
 
@@ -2439,10 +2464,12 @@ Metrics/BlockLength:
2439
2464
  Max: 25
2440
2465
  CountAsOne: []
2441
2466
  ExcludedMethods: [] # deprecated, retained for backwards compatibility
2442
- IgnoredMethods:
2467
+ AllowedMethods:
2443
2468
  # By default, exclude the `#refine` method, as it tends to have larger
2444
2469
  # associated blocks.
2445
2470
  - refine
2471
+ AllowedPatterns: []
2472
+ IgnoredMethods: [] # deprecated
2446
2473
  Exclude:
2447
2474
  - '**/*.gemspec'
2448
2475
 
@@ -2472,7 +2499,9 @@ Metrics/CyclomaticComplexity:
2472
2499
  Enabled: true
2473
2500
  VersionAdded: '0.25'
2474
2501
  VersionChanged: '0.81'
2475
- IgnoredMethods: []
2502
+ AllowedMethods: []
2503
+ AllowedPatterns: []
2504
+ IgnoredMethods: [] # deprecated
2476
2505
  Max: 7
2477
2506
 
2478
2507
  Metrics/MethodLength:
@@ -2485,7 +2514,9 @@ Metrics/MethodLength:
2485
2514
  Max: 10
2486
2515
  CountAsOne: []
2487
2516
  ExcludedMethods: [] # deprecated, retained for backwards compatibility
2488
- IgnoredMethods: []
2517
+ AllowedMethods: []
2518
+ AllowedPatterns: []
2519
+ IgnoredMethods: [] # deprecated
2489
2520
 
2490
2521
  Metrics/ModuleLength:
2491
2522
  Description: 'Avoid modules longer than 100 lines of code.'
@@ -2513,7 +2544,9 @@ Metrics/PerceivedComplexity:
2513
2544
  Enabled: true
2514
2545
  VersionAdded: '0.25'
2515
2546
  VersionChanged: '0.81'
2516
- IgnoredMethods: []
2547
+ AllowedMethods: []
2548
+ AllowedPatterns: []
2549
+ IgnoredMethods: [] # deprecated
2517
2550
  Max: 8
2518
2551
 
2519
2552
  ################## Migration #############################
@@ -3044,7 +3077,7 @@ Style/BlockDelimiters:
3044
3077
  # This looks at the usage of a block's method to determine its type (e.g. is
3045
3078
  # the result of a `map` assigned to a variable or passed to another
3046
3079
  # method) but exceptions are permitted in the `ProceduralMethods`,
3047
- # `FunctionalMethods` and `IgnoredMethods` sections below.
3080
+ # `FunctionalMethods` and `AllowedMethods` sections below.
3048
3081
  - semantic
3049
3082
  # The `braces_for_chaining` style enforces braces around single line blocks
3050
3083
  # and do..end around multi-line blocks, except for multi-line blocks whose
@@ -3085,7 +3118,7 @@ Style/BlockDelimiters:
3085
3118
  - let!
3086
3119
  - subject
3087
3120
  - watch
3088
- IgnoredMethods:
3121
+ AllowedMethods:
3089
3122
  # Methods that can be either procedural or functional and cannot be
3090
3123
  # categorised from their usage alone, e.g.
3091
3124
  #
@@ -3102,6 +3135,8 @@ Style/BlockDelimiters:
3102
3135
  - lambda
3103
3136
  - proc
3104
3137
  - it
3138
+ AllowedPatterns: []
3139
+ IgnoredMethods: [] # deprecated
3105
3140
  # The AllowBracesOnProceduralOneLiners option is ignored unless the
3106
3141
  # EnforcedStyle is set to `semantic`. If so:
3107
3142
  #
@@ -3205,10 +3240,12 @@ Style/ClassEqualityComparison:
3205
3240
  StyleGuide: '#instance-of-vs-class-comparison'
3206
3241
  Enabled: true
3207
3242
  VersionAdded: '0.93'
3208
- IgnoredMethods:
3243
+ AllowedMethods:
3209
3244
  - ==
3210
3245
  - equal?
3211
3246
  - eql?
3247
+ AllowedPatterns: []
3248
+ IgnoredMethods: [] # deprecated
3212
3249
 
3213
3250
  Style/ClassMethods:
3214
3251
  Description: 'Use self when defining module/class methods.'
@@ -3495,6 +3532,12 @@ Style/EmptyElse:
3495
3532
  - empty
3496
3533
  - nil
3497
3534
  - both
3535
+ AllowComments: false
3536
+
3537
+ Style/EmptyHeredoc:
3538
+ Description: 'Checks for using empty heredoc to reduce redundancy.'
3539
+ Enabled: pending
3540
+ VersionAdded: '1.32'
3498
3541
 
3499
3542
  Style/EmptyLambdaParameter:
3500
3543
  Description: 'Omit parens for empty lambda parameters.'
@@ -3664,7 +3707,9 @@ Style/FormatStringToken:
3664
3707
  MaxUnannotatedPlaceholdersAllowed: 1
3665
3708
  VersionAdded: '0.49'
3666
3709
  VersionChanged: '1.0'
3667
- IgnoredMethods: []
3710
+ AllowedMethods: []
3711
+ AllowedPatterns: []
3712
+ IgnoredMethods: [] # deprecated
3668
3713
 
3669
3714
  Style/FrozenStringLiteralComment:
3670
3715
  Description: >-
@@ -3983,7 +4028,8 @@ Style/MethodCallWithArgsParentheses:
3983
4028
  VersionAdded: '0.47'
3984
4029
  VersionChanged: '1.7'
3985
4030
  IgnoreMacros: true
3986
- IgnoredMethods: []
4031
+ AllowedMethods: []
4032
+ IgnoredMethods: [] # deprecated
3987
4033
  AllowedPatterns: []
3988
4034
  IgnoredPatterns: [] # deprecated
3989
4035
  IncludedMacros: []
@@ -4000,7 +4046,9 @@ Style/MethodCallWithoutArgsParentheses:
4000
4046
  Description: 'Do not use parentheses for method calls with no arguments.'
4001
4047
  StyleGuide: '#method-invocation-parens'
4002
4048
  Enabled: true
4003
- IgnoredMethods: []
4049
+ AllowedMethods: []
4050
+ AllowedPatterns: []
4051
+ IgnoredMethods: [] # deprecated
4004
4052
  VersionAdded: '0.47'
4005
4053
  VersionChanged: '0.55'
4006
4054
 
@@ -4370,7 +4418,9 @@ Style/NumericPredicate:
4370
4418
  SupportedStyles:
4371
4419
  - predicate
4372
4420
  - comparison
4373
- IgnoredMethods: []
4421
+ AllowedMethods: []
4422
+ AllowedPatterns: []
4423
+ IgnoredMethods: [] # deprecated
4374
4424
  # Exclude RSpec specs because assertions like `expect(1).to be > 0` cause
4375
4425
  # false positives.
4376
4426
  Exclude:
@@ -5007,11 +5057,13 @@ Style/SymbolProc:
5007
5057
  VersionAdded: '0.26'
5008
5058
  VersionChanged: '1.28'
5009
5059
  AllowMethodsWithArguments: false
5010
- # A list of method names to be ignored by the check.
5060
+ # A list of method names to be always allowed by the check.
5011
5061
  # The names should be fairly unique, otherwise you'll end up ignoring lots of code.
5012
- IgnoredMethods:
5062
+ AllowedMethods:
5013
5063
  - respond_to
5014
5064
  - define_method
5065
+ AllowedPatterns: []
5066
+ IgnoredMethods: [] # deprecated
5015
5067
  AllowComments: false
5016
5068
 
5017
5069
  Style/TernaryParentheses:
@@ -187,7 +187,9 @@ changed_parameters:
187
187
  - Metrics/BlockLength
188
188
  - Metrics/MethodLength
189
189
  parameters: ExcludedMethods
190
- alternative: IgnoredMethods
190
+ alternatives:
191
+ - AllowedMethods
192
+ - AllowedPatterns
191
193
  severity: warning
192
194
  - cops: Lint/Debugger
193
195
  parameters: DebuggerReceivers
@@ -202,6 +204,26 @@ changed_parameters:
202
204
  parameters: IgnoredPatterns
203
205
  alternative: AllowedPatterns
204
206
  severity: warning
207
+ - cops:
208
+ - Lint/AmbiguousBlockAssociation
209
+ - Lint/NumberConversion
210
+ - Metrics/AbcSize
211
+ - Metrics/BlockLength
212
+ - Metrics/CyclomaticComplexity
213
+ - Metrics/MethodLength
214
+ - Metrics/PerceivedComplexity
215
+ - Style/BlockDelimiters
216
+ - Style/ClassEqualityComparison
217
+ - Style/FormatStringToken
218
+ - Style/MethodCallWithArgsParentheses
219
+ - Style/MethodCallWithoutArgsParentheses
220
+ - Style/NumericPredicate
221
+ - Style/SymbolLiteral
222
+ parameters: IgnoredMethods
223
+ alternatives:
224
+ - AllowedMethods
225
+ - AllowedPatterns
226
+ severity: warning
205
227
 
206
228
  # Enforced styles that have been removed or replaced
207
229
  changed_enforced_styles:
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ # This class represents the cache config of the caching RuboCop runs.
5
+ # @api private
6
+ class CacheConfig
7
+ def self.root_dir
8
+ root = ENV.fetch('RUBOCOP_CACHE_ROOT', nil)
9
+ root ||= yield
10
+ root ||= if ENV.key?('XDG_CACHE_HOME')
11
+ # Include user ID in the path to make sure the user has write
12
+ # access.
13
+ File.join(ENV.fetch('XDG_CACHE_HOME'), Process.uid.to_s)
14
+ else
15
+ # On FreeBSD, the /home path is a symbolic link to /usr/home
16
+ # and the $HOME environment variable returns the /home path.
17
+ #
18
+ # As $HOME is a built-in environment variable, FreeBSD users
19
+ # always get a warning message.
20
+ #
21
+ # To avoid raising warn log messages on FreeBSD, we retrieve
22
+ # the real path of the home folder.
23
+ File.join(File.realpath(Dir.home), '.cache')
24
+ end
25
+
26
+ File.join(root, 'rubocop_cache')
27
+ end
28
+ end
29
+ end
@@ -98,7 +98,7 @@ module RuboCop
98
98
  def add_inheritance_from_auto_generated_file(config_file)
99
99
  file_string = " #{relative_path_to_todo_from_options_config}"
100
100
 
101
- config_file ||= ConfigLoader::DOTFILE
101
+ config_file ||= ConfigFinder::DOTFILE
102
102
 
103
103
  if File.exist?(config_file)
104
104
  files = Array(ConfigLoader.load_yaml_configuration(config_file)['inherit_from'])
@@ -113,7 +113,7 @@ module RuboCop
113
113
  write_config_file(config_file, file_string, rubocop_yml_contents)
114
114
 
115
115
  puts "Added inheritance from `#{relative_path_to_todo_from_options_config}` " \
116
- "in `#{ConfigLoader::DOTFILE}`."
116
+ "in `#{ConfigFinder::DOTFILE}`."
117
117
  end
118
118
 
119
119
  def existing_configuration(config_file)
@@ -6,7 +6,7 @@ module RuboCop
6
6
  # Generate a .rubocop.yml file in the current directory.
7
7
  # @api private
8
8
  class InitDotfile < Base
9
- DOTFILE = ConfigLoader::DOTFILE
9
+ DOTFILE = ConfigFinder::DOTFILE
10
10
 
11
11
  self.command_name = :init
12
12
 
data/lib/rubocop/cli.rb CHANGED
@@ -12,6 +12,7 @@ module RuboCop
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
14
14
  ignore_disable_comments lint only only_guide_cops require safe
15
+ autocorrect safe_autocorrect autocorrect_all
15
16
  ].freeze
16
17
 
17
18
  class Finished < StandardError; end
@@ -25,7 +25,7 @@ module RuboCop
25
25
  @loaded_path = loaded_path
26
26
  @for_cop = Hash.new do |h, cop|
27
27
  qualified_cop_name = Cop::Registry.qualified_cop_name(cop, loaded_path)
28
- cop_options = self[qualified_cop_name] || {}
28
+ cop_options = self[qualified_cop_name].dup || {}
29
29
  cop_options['Enabled'] = enable_cop?(qualified_cop_name, cop_options)
30
30
  h[cop] = cop_options
31
31
  end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'file_finder'
4
+
5
+ module RuboCop
6
+ # This class has methods related to finding configuration path.
7
+ # @api private
8
+ class ConfigFinder
9
+ DOTFILE = '.rubocop.yml'
10
+ XDG_CONFIG = 'config.yml'
11
+ RUBOCOP_HOME = File.realpath(File.join(File.dirname(__FILE__), '..', '..'))
12
+ DEFAULT_FILE = File.join(RUBOCOP_HOME, 'config', 'default.yml')
13
+
14
+ class << self
15
+ include FileFinder
16
+
17
+ attr_writer :project_root
18
+
19
+ def find_config_path(target_dir)
20
+ find_project_dotfile(target_dir) || find_user_dotfile || find_user_xdg_config ||
21
+ DEFAULT_FILE
22
+ end
23
+
24
+ # Returns the path RuboCop inferred as the root of the project. No file
25
+ # searches will go past this directory.
26
+ def project_root
27
+ @project_root ||= find_project_root
28
+ end
29
+
30
+ private
31
+
32
+ def find_project_root
33
+ pwd = Dir.pwd
34
+ gems_file = find_last_file_upwards('Gemfile', pwd) || find_last_file_upwards('gems.rb', pwd)
35
+ return unless gems_file
36
+
37
+ File.dirname(gems_file)
38
+ end
39
+
40
+ def find_project_dotfile(target_dir)
41
+ find_file_upwards(DOTFILE, target_dir, project_root)
42
+ end
43
+
44
+ def find_user_dotfile
45
+ return unless ENV.key?('HOME')
46
+
47
+ file = File.join(Dir.home, DOTFILE)
48
+
49
+ return file if File.exist?(file)
50
+ end
51
+
52
+ def find_user_xdg_config
53
+ xdg_config_home = expand_path(ENV.fetch('XDG_CONFIG_HOME', '~/.config'))
54
+ xdg_config = File.join(xdg_config_home, 'rubocop', XDG_CONFIG)
55
+
56
+ return xdg_config if File.exist?(xdg_config)
57
+ end
58
+
59
+ def expand_path(path)
60
+ File.expand_path(path)
61
+ rescue ArgumentError
62
+ # Could happen because HOME or ID could not be determined. Fall back on
63
+ # using the path literally in that case.
64
+ path
65
+ end
66
+ end
67
+ end
68
+ end
@@ -3,6 +3,7 @@
3
3
  require 'erb'
4
4
  require 'yaml'
5
5
  require 'pathname'
6
+ require_relative 'config_finder'
6
7
 
7
8
  module RuboCop
8
9
  # Raised when a RuboCop configuration file is not found.
@@ -15,8 +16,7 @@ module RuboCop
15
16
  # during a run of the rubocop program, if files in several
16
17
  # directories are inspected.
17
18
  class ConfigLoader
18
- DOTFILE = '.rubocop.yml'
19
- XDG_CONFIG = 'config.yml'
19
+ DOTFILE = ConfigFinder::DOTFILE
20
20
  RUBOCOP_HOME = File.realpath(File.join(File.dirname(__FILE__), '..', '..'))
21
21
  DEFAULT_FILE = File.join(RUBOCOP_HOME, 'config', 'default.yml')
22
22
 
@@ -25,7 +25,7 @@ module RuboCop
25
25
 
26
26
  attr_accessor :debug, :ignore_parent_exclusion, :disable_pending_cops, :enable_pending_cops,
27
27
  :ignore_unrecognized_cops
28
- attr_writer :default_configuration, :project_root
28
+ attr_writer :default_configuration
29
29
  attr_reader :loaded_features
30
30
 
31
31
  alias debug? debug
@@ -95,8 +95,7 @@ module RuboCop
95
95
  # user's home directory is checked. If there's no .rubocop.yml
96
96
  # there either, the path to the default file is returned.
97
97
  def configuration_file_for(target_dir)
98
- find_project_dotfile(target_dir) || find_user_dotfile ||
99
- find_user_xdg_config || DEFAULT_FILE
98
+ ConfigFinder.find_config_path(target_dir)
100
99
  end
101
100
 
102
101
  def configuration_from_file(config_file, check: true)
@@ -122,7 +121,7 @@ module RuboCop
122
121
  end
123
122
 
124
123
  def add_excludes_from_files(config, config_file)
125
- exclusion_file = find_last_file_upwards(DOTFILE, config_file, project_root)
124
+ exclusion_file = find_last_file_upwards(DOTFILE, config_file, ConfigFinder.project_root)
126
125
 
127
126
  return unless exclusion_file
128
127
  return if PathUtil.relative_path(exclusion_file) == PathUtil.relative_path(config_file)
@@ -138,12 +137,6 @@ module RuboCop
138
137
  end
139
138
  end
140
139
 
141
- # Returns the path RuboCop inferred as the root of the project. No file
142
- # searches will go past this directory.
143
- def project_root
144
- @project_root ||= find_project_root
145
- end
146
-
147
140
  PENDING_BANNER = <<~BANNER
148
141
  The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.yml` file.
149
142
 
@@ -187,39 +180,6 @@ module RuboCop
187
180
  File.absolute_path(file.is_a?(RemoteConfig) ? file.file : file)
188
181
  end
189
182
 
190
- def find_project_dotfile(target_dir)
191
- find_file_upwards(DOTFILE, target_dir, project_root)
192
- end
193
-
194
- def find_project_root
195
- pwd = Dir.pwd
196
- gems_file = find_last_file_upwards('Gemfile', pwd) || find_last_file_upwards('gems.rb', pwd)
197
- return unless gems_file
198
-
199
- File.dirname(gems_file)
200
- end
201
-
202
- def find_user_dotfile
203
- return unless ENV.key?('HOME')
204
-
205
- file = File.join(Dir.home, DOTFILE)
206
- return file if File.exist?(file)
207
- end
208
-
209
- def find_user_xdg_config
210
- xdg_config_home = expand_path(ENV.fetch('XDG_CONFIG_HOME', '~/.config'))
211
- xdg_config = File.join(xdg_config_home, 'rubocop', XDG_CONFIG)
212
- return xdg_config if File.exist?(xdg_config)
213
- end
214
-
215
- def expand_path(path)
216
- File.expand_path(path)
217
- rescue ArgumentError
218
- # Could happen because HOME or ID could not be determined. Fall back on
219
- # using the path literally in that case.
220
- path
221
- end
222
-
223
183
  def resolver
224
184
  @resolver ||= ConfigLoaderResolver.new
225
185
  end
@@ -179,7 +179,7 @@ module RuboCop
179
179
 
180
180
  def determine_inherit_mode(hash, key)
181
181
  cop_cfg = hash[key]
182
- local_inherit = cop_cfg.delete('inherit_mode') if cop_cfg.is_a?(Hash)
182
+ local_inherit = cop_cfg['inherit_mode'] if cop_cfg.is_a?(Hash)
183
183
  local_inherit || hash['inherit_mode'] || {}
184
184
  end
185
185
 
@@ -12,6 +12,11 @@ module RuboCop
12
12
 
13
13
  if alternative
14
14
  "#{base}\n`#{parameter}` has been renamed to `#{alternative.chomp}`."
15
+ elsif alternatives
16
+ "#{base}\n`#{parameter}` has been renamed to #{to_sentence(alternatives.map do |item|
17
+ "`#{item}`"
18
+ end,
19
+ connector: 'and/or')}."
15
20
  else
16
21
  "#{base}\n#{reason.chomp}"
17
22
  end
@@ -32,6 +32,10 @@ module RuboCop
32
32
  metadata['alternative']
33
33
  end
34
34
 
35
+ def alternatives
36
+ metadata['alternatives']
37
+ end
38
+
35
39
  def reason
36
40
  metadata['reason']
37
41
  end
@@ -47,10 +47,15 @@ module RuboCop
47
47
 
48
48
  # Default rules for obsoletions are in config/obsoletion.yml
49
49
  # Additional rules files can be added with `RuboCop::ConfigObsoletion.files << filename`
50
- def load_rules
50
+ def load_rules # rubocop:disable Metrics/AbcSize
51
51
  rules = self.class.files.each_with_object({}) do |filename, hash|
52
52
  hash.merge!(YAML.safe_load(File.read(filename))) do |_key, first, second|
53
- first.merge(second)
53
+ case first
54
+ when Hash
55
+ first.merge(second)
56
+ when Array
57
+ first.concat(second)
58
+ end
54
59
  end
55
60
  end
56
61
 
@@ -48,7 +48,7 @@ module RuboCop
48
48
  InvestigationReport = Struct.new(:cop, :processed_source, :offenses, :corrector)
49
49
 
50
50
  # List of methods names to restrict calls for `on_send` / `on_csend`
51
- RESTRICT_ON_SEND = Set[].freeze
51
+ RESTRICT_ON_SEND = Set[].freeze # rubocop:disable InternalAffairs/UselessRestrictOnSend
52
52
 
53
53
  # List of cops that should not try to autocorrect at the same
54
54
  # time as this cop
@@ -62,6 +62,10 @@ module RuboCop
62
62
  # For example
63
63
  MSG = 'Use `#good_method` instead of `#bad_method`.'
64
64
 
65
+ # TODO: Don't call `on_send` unless the method name is in this list
66
+ # If you don't need `on_send` in the cop you created, remove it.
67
+ RESTRICT_ON_SEND = %%i[bad_method].freeze
68
+
65
69
  # @!method bad_method?(node)
66
70
  def_node_matcher :bad_method?, <<~PATTERN
67
71
  (send nil? :bad_method ...)