rubocop 1.32.0 → 1.33.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/config/default.yml +45 -16
- data/config/obsoletion.yml +23 -1
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +2 -2
- data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
- data/lib/rubocop/config_finder.rb +68 -0
- data/lib/rubocop/config_loader.rb +5 -45
- data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
- data/lib/rubocop/config_obsoletion.rb +7 -2
- data/lib/rubocop/cop/layout/block_end_newline.rb +32 -5
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +21 -8
- data/lib/rubocop/cop/lint/debugger.rb +11 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +60 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +24 -8
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -1
- data/lib/rubocop/cop/metrics/block_length.rb +6 -7
- data/lib/rubocop/cop/metrics/method_length.rb +8 -8
- data/lib/rubocop/cop/mixin/allowed_methods.rb +15 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +4 -9
- data/lib/rubocop/cop/naming/predicate_name.rb +24 -3
- data/lib/rubocop/cop/style/block_delimiters.rb +26 -7
- data/lib/rubocop/cop/style/class_and_module_children.rb +4 -4
- data/lib/rubocop/cop/style/class_equality_comparison.rb +32 -7
- data/lib/rubocop/cop/style/empty_heredoc.rb +15 -1
- data/lib/rubocop/cop/style/format_string_token.rb +21 -8
- data/lib/rubocop/cop/style/hash_except.rb +0 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -7
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -6
- data/lib/rubocop/cop/style/numeric_predicate.rb +28 -8
- data/lib/rubocop/cop/style/redundant_condition.rb +19 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +21 -6
- data/lib/rubocop/cop/style/symbol_proc.rb +29 -9
- data/lib/rubocop/result_cache.rb +22 -20
- data/lib/rubocop/server/cache.rb +33 -1
- data/lib/rubocop/server/cli.rb +19 -2
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +0 -1
- metadata +5 -4
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 141b5fc0ee48c7fdf1fc347bb2b59b59933f6d46f575cfb4f380bfc101090345
|
4
|
+
data.tar.gz: 862c5d1952e777ec19bd1b8782c9e98e065c3d80db7a7d2c91da4406afeb886c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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.
|
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
@@ -1502,7 +1502,9 @@ Lint/AmbiguousBlockAssociation:
|
|
1502
1502
|
Enabled: true
|
1503
1503
|
VersionAdded: '0.48'
|
1504
1504
|
VersionChanged: '1.13'
|
1505
|
-
|
1505
|
+
AllowedMethods: []
|
1506
|
+
AllowedPatterns: []
|
1507
|
+
IgnoredMethods: [] # deprecated
|
1506
1508
|
|
1507
1509
|
Lint/AmbiguousOperator:
|
1508
1510
|
Description: >-
|
@@ -1753,6 +1755,7 @@ Lint/EmptyConditionalBody:
|
|
1753
1755
|
Enabled: true
|
1754
1756
|
AllowComments: true
|
1755
1757
|
VersionAdded: '0.89'
|
1758
|
+
VersionChanged: '1.33'
|
1756
1759
|
|
1757
1760
|
Lint/EmptyEnsure:
|
1758
1761
|
Description: 'Checks for empty ensure block.'
|
@@ -1970,6 +1973,7 @@ Lint/NoReturnInBeginEndBlocks:
|
|
1970
1973
|
|
1971
1974
|
Lint/NonAtomicFileOperation:
|
1972
1975
|
Description: Checks for non-atomic file operations.
|
1976
|
+
StyleGuide: '#atomic-file-operations'
|
1973
1977
|
Enabled: pending
|
1974
1978
|
VersionAdded: '1.31'
|
1975
1979
|
SafeAutoCorrect: false
|
@@ -1991,7 +1995,9 @@ Lint/NumberConversion:
|
|
1991
1995
|
VersionAdded: '0.53'
|
1992
1996
|
VersionChanged: '1.1'
|
1993
1997
|
SafeAutoCorrect: false
|
1994
|
-
|
1998
|
+
AllowedMethods: []
|
1999
|
+
AllowedPatterns: []
|
2000
|
+
IgnoredMethods: [] # deprecated
|
1995
2001
|
IgnoredClasses:
|
1996
2002
|
- Time
|
1997
2003
|
- DateTime
|
@@ -2443,7 +2449,9 @@ Metrics/AbcSize:
|
|
2443
2449
|
VersionChanged: '1.5'
|
2444
2450
|
# The ABC size is a calculated magnitude, so this number can be an Integer or
|
2445
2451
|
# a Float.
|
2446
|
-
|
2452
|
+
AllowedMethods: []
|
2453
|
+
AllowedPatterns: []
|
2454
|
+
IgnoredMethods: [] # deprecated
|
2447
2455
|
CountRepeatedAttributes: true
|
2448
2456
|
Max: 17
|
2449
2457
|
|
@@ -2456,10 +2464,12 @@ Metrics/BlockLength:
|
|
2456
2464
|
Max: 25
|
2457
2465
|
CountAsOne: []
|
2458
2466
|
ExcludedMethods: [] # deprecated, retained for backwards compatibility
|
2459
|
-
|
2467
|
+
AllowedMethods:
|
2460
2468
|
# By default, exclude the `#refine` method, as it tends to have larger
|
2461
2469
|
# associated blocks.
|
2462
2470
|
- refine
|
2471
|
+
AllowedPatterns: []
|
2472
|
+
IgnoredMethods: [] # deprecated
|
2463
2473
|
Exclude:
|
2464
2474
|
- '**/*.gemspec'
|
2465
2475
|
|
@@ -2489,7 +2499,9 @@ Metrics/CyclomaticComplexity:
|
|
2489
2499
|
Enabled: true
|
2490
2500
|
VersionAdded: '0.25'
|
2491
2501
|
VersionChanged: '0.81'
|
2492
|
-
|
2502
|
+
AllowedMethods: []
|
2503
|
+
AllowedPatterns: []
|
2504
|
+
IgnoredMethods: [] # deprecated
|
2493
2505
|
Max: 7
|
2494
2506
|
|
2495
2507
|
Metrics/MethodLength:
|
@@ -2502,7 +2514,9 @@ Metrics/MethodLength:
|
|
2502
2514
|
Max: 10
|
2503
2515
|
CountAsOne: []
|
2504
2516
|
ExcludedMethods: [] # deprecated, retained for backwards compatibility
|
2505
|
-
|
2517
|
+
AllowedMethods: []
|
2518
|
+
AllowedPatterns: []
|
2519
|
+
IgnoredMethods: [] # deprecated
|
2506
2520
|
|
2507
2521
|
Metrics/ModuleLength:
|
2508
2522
|
Description: 'Avoid modules longer than 100 lines of code.'
|
@@ -2530,7 +2544,9 @@ Metrics/PerceivedComplexity:
|
|
2530
2544
|
Enabled: true
|
2531
2545
|
VersionAdded: '0.25'
|
2532
2546
|
VersionChanged: '0.81'
|
2533
|
-
|
2547
|
+
AllowedMethods: []
|
2548
|
+
AllowedPatterns: []
|
2549
|
+
IgnoredMethods: [] # deprecated
|
2534
2550
|
Max: 8
|
2535
2551
|
|
2536
2552
|
################## Migration #############################
|
@@ -3061,7 +3077,7 @@ Style/BlockDelimiters:
|
|
3061
3077
|
# This looks at the usage of a block's method to determine its type (e.g. is
|
3062
3078
|
# the result of a `map` assigned to a variable or passed to another
|
3063
3079
|
# method) but exceptions are permitted in the `ProceduralMethods`,
|
3064
|
-
# `FunctionalMethods` and `
|
3080
|
+
# `FunctionalMethods` and `AllowedMethods` sections below.
|
3065
3081
|
- semantic
|
3066
3082
|
# The `braces_for_chaining` style enforces braces around single line blocks
|
3067
3083
|
# and do..end around multi-line blocks, except for multi-line blocks whose
|
@@ -3102,7 +3118,7 @@ Style/BlockDelimiters:
|
|
3102
3118
|
- let!
|
3103
3119
|
- subject
|
3104
3120
|
- watch
|
3105
|
-
|
3121
|
+
AllowedMethods:
|
3106
3122
|
# Methods that can be either procedural or functional and cannot be
|
3107
3123
|
# categorised from their usage alone, e.g.
|
3108
3124
|
#
|
@@ -3119,6 +3135,8 @@ Style/BlockDelimiters:
|
|
3119
3135
|
- lambda
|
3120
3136
|
- proc
|
3121
3137
|
- it
|
3138
|
+
AllowedPatterns: []
|
3139
|
+
IgnoredMethods: [] # deprecated
|
3122
3140
|
# The AllowBracesOnProceduralOneLiners option is ignored unless the
|
3123
3141
|
# EnforcedStyle is set to `semantic`. If so:
|
3124
3142
|
#
|
@@ -3222,10 +3240,12 @@ Style/ClassEqualityComparison:
|
|
3222
3240
|
StyleGuide: '#instance-of-vs-class-comparison'
|
3223
3241
|
Enabled: true
|
3224
3242
|
VersionAdded: '0.93'
|
3225
|
-
|
3243
|
+
AllowedMethods:
|
3226
3244
|
- ==
|
3227
3245
|
- equal?
|
3228
3246
|
- eql?
|
3247
|
+
AllowedPatterns: []
|
3248
|
+
IgnoredMethods: [] # deprecated
|
3229
3249
|
|
3230
3250
|
Style/ClassMethods:
|
3231
3251
|
Description: 'Use self when defining module/class methods.'
|
@@ -3687,7 +3707,9 @@ Style/FormatStringToken:
|
|
3687
3707
|
MaxUnannotatedPlaceholdersAllowed: 1
|
3688
3708
|
VersionAdded: '0.49'
|
3689
3709
|
VersionChanged: '1.0'
|
3690
|
-
|
3710
|
+
AllowedMethods: []
|
3711
|
+
AllowedPatterns: []
|
3712
|
+
IgnoredMethods: [] # deprecated
|
3691
3713
|
|
3692
3714
|
Style/FrozenStringLiteralComment:
|
3693
3715
|
Description: >-
|
@@ -4006,7 +4028,8 @@ Style/MethodCallWithArgsParentheses:
|
|
4006
4028
|
VersionAdded: '0.47'
|
4007
4029
|
VersionChanged: '1.7'
|
4008
4030
|
IgnoreMacros: true
|
4009
|
-
|
4031
|
+
AllowedMethods: []
|
4032
|
+
IgnoredMethods: [] # deprecated
|
4010
4033
|
AllowedPatterns: []
|
4011
4034
|
IgnoredPatterns: [] # deprecated
|
4012
4035
|
IncludedMacros: []
|
@@ -4023,7 +4046,9 @@ Style/MethodCallWithoutArgsParentheses:
|
|
4023
4046
|
Description: 'Do not use parentheses for method calls with no arguments.'
|
4024
4047
|
StyleGuide: '#method-invocation-parens'
|
4025
4048
|
Enabled: true
|
4026
|
-
|
4049
|
+
AllowedMethods: []
|
4050
|
+
AllowedPatterns: []
|
4051
|
+
IgnoredMethods: [] # deprecated
|
4027
4052
|
VersionAdded: '0.47'
|
4028
4053
|
VersionChanged: '0.55'
|
4029
4054
|
|
@@ -4393,7 +4418,9 @@ Style/NumericPredicate:
|
|
4393
4418
|
SupportedStyles:
|
4394
4419
|
- predicate
|
4395
4420
|
- comparison
|
4396
|
-
|
4421
|
+
AllowedMethods: []
|
4422
|
+
AllowedPatterns: []
|
4423
|
+
IgnoredMethods: [] # deprecated
|
4397
4424
|
# Exclude RSpec specs because assertions like `expect(1).to be > 0` cause
|
4398
4425
|
# false positives.
|
4399
4426
|
Exclude:
|
@@ -5030,11 +5057,13 @@ Style/SymbolProc:
|
|
5030
5057
|
VersionAdded: '0.26'
|
5031
5058
|
VersionChanged: '1.28'
|
5032
5059
|
AllowMethodsWithArguments: false
|
5033
|
-
# A list of method names to be
|
5060
|
+
# A list of method names to be always allowed by the check.
|
5034
5061
|
# The names should be fairly unique, otherwise you'll end up ignoring lots of code.
|
5035
|
-
|
5062
|
+
AllowedMethods:
|
5036
5063
|
- respond_to
|
5037
5064
|
- define_method
|
5065
|
+
AllowedPatterns: []
|
5066
|
+
IgnoredMethods: [] # deprecated
|
5038
5067
|
AllowComments: false
|
5039
5068
|
|
5040
5069
|
Style/TernaryParentheses:
|
data/config/obsoletion.yml
CHANGED
@@ -187,7 +187,9 @@ changed_parameters:
|
|
187
187
|
- Metrics/BlockLength
|
188
188
|
- Metrics/MethodLength
|
189
189
|
parameters: ExcludedMethods
|
190
|
-
|
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 ||=
|
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 `#{
|
116
|
+
"in `#{ConfigFinder::DOTFILE}`."
|
117
117
|
end
|
118
118
|
|
119
119
|
def existing_configuration(config_file)
|
@@ -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 =
|
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
|
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
|
-
|
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
|
@@ -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
|
@@ -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
|
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
|
|
@@ -36,24 +36,51 @@ module RuboCop
|
|
36
36
|
# If the end is on its own line, there is no offense
|
37
37
|
return if begins_its_line?(node.loc.end)
|
38
38
|
|
39
|
-
|
40
|
-
corrector.replace(delimiter_range(node), "\n#{node.loc.end.source}#{offset(node)}")
|
41
|
-
end
|
39
|
+
register_offense(node)
|
42
40
|
end
|
43
41
|
|
44
42
|
private
|
45
43
|
|
44
|
+
def register_offense(node)
|
45
|
+
add_offense(node.loc.end, message: message(node)) do |corrector|
|
46
|
+
offense_range = offense_range(node)
|
47
|
+
replacement = "\n#{offense_range.source.strip}"
|
48
|
+
|
49
|
+
if (heredoc = last_heredoc_argument(node.body))
|
50
|
+
corrector.remove(offense_range)
|
51
|
+
corrector.insert_after(heredoc.loc.heredoc_end, replacement)
|
52
|
+
else
|
53
|
+
corrector.replace(offense_range, replacement)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
46
58
|
def message(node)
|
47
59
|
format(MSG, line: node.loc.end.line, column: node.loc.end.column + 1)
|
48
60
|
end
|
49
61
|
|
50
|
-
def
|
62
|
+
def last_heredoc_argument(node)
|
63
|
+
return unless (arguments = node&.arguments)
|
64
|
+
|
65
|
+
heredoc = arguments.reverse.detect(&:heredoc?)
|
66
|
+
return heredoc if heredoc
|
67
|
+
|
68
|
+
last_heredoc_argument(node.children.first)
|
69
|
+
end
|
70
|
+
|
71
|
+
def offense_range(node)
|
51
72
|
Parser::Source::Range.new(
|
52
73
|
node.loc.expression.source_buffer,
|
53
74
|
node.children.compact.last.loc.expression.end_pos,
|
54
|
-
node.loc.expression.end_pos
|
75
|
+
end_of_method_chain(node).loc.expression.end_pos
|
55
76
|
)
|
56
77
|
end
|
78
|
+
|
79
|
+
def end_of_method_chain(node)
|
80
|
+
return node unless node.parent&.call_type?
|
81
|
+
|
82
|
+
end_of_method_chain(node.parent)
|
83
|
+
end
|
57
84
|
end
|
58
85
|
end
|
59
86
|
end
|
@@ -153,7 +153,8 @@ module RuboCop
|
|
153
153
|
MSG = 'Indent the first argument one step more than %<base>s.'
|
154
154
|
|
155
155
|
def on_send(node)
|
156
|
-
return if style != :consistent && enforce_first_argument_with_fixed_indentation?
|
156
|
+
return if style != :consistent && enforce_first_argument_with_fixed_indentation? &&
|
157
|
+
!enable_layout_first_method_argument_line_break?
|
157
158
|
return if !node.arguments? || bare_operator?(node) || node.setter_method?
|
158
159
|
|
159
160
|
indent = base_indentation(node) + configured_indentation_width
|
@@ -267,6 +268,10 @@ module RuboCop
|
|
267
268
|
argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
|
268
269
|
end
|
269
270
|
|
271
|
+
def enable_layout_first_method_argument_line_break?
|
272
|
+
config.for_cop('Layout/FirstMethodArgumentLineBreak')['Enabled']
|
273
|
+
end
|
274
|
+
|
270
275
|
def argument_alignment_config
|
271
276
|
config.for_cop('Layout/ArgumentAlignment')
|
272
277
|
end
|
@@ -6,8 +6,8 @@ module RuboCop
|
|
6
6
|
# Checks for ambiguous block association with method
|
7
7
|
# when param passed without parentheses.
|
8
8
|
#
|
9
|
-
# This cop can customize
|
10
|
-
# By default, there are no methods to
|
9
|
+
# This cop can customize allowed methods with `AllowedMethods`.
|
10
|
+
# By default, there are no methods to allowed.
|
11
11
|
#
|
12
12
|
# @example
|
13
13
|
#
|
@@ -30,18 +30,30 @@ module RuboCop
|
|
30
30
|
# # Lambda arguments require no disambiguation
|
31
31
|
# foo = ->(bar) { bar.baz }
|
32
32
|
#
|
33
|
-
# @example
|
33
|
+
# @example AllowedMethods: [] (default)
|
34
34
|
#
|
35
35
|
# # bad
|
36
36
|
# expect { do_something }.to change { object.attribute }
|
37
37
|
#
|
38
|
-
# @example
|
38
|
+
# @example AllowedMethods: [change]
|
39
39
|
#
|
40
40
|
# # good
|
41
41
|
# expect { do_something }.to change { object.attribute }
|
42
42
|
#
|
43
|
+
# @example AllowedPatterns: [] (default)
|
44
|
+
#
|
45
|
+
# # bad
|
46
|
+
# expect { do_something }.to change { object.attribute }
|
47
|
+
#
|
48
|
+
# @example AllowedPatterns: [/change/]
|
49
|
+
#
|
50
|
+
# # good
|
51
|
+
# expect { do_something }.to change { object.attribute }
|
52
|
+
# expect { do_something }.to not_change { object.attribute }
|
53
|
+
#
|
43
54
|
class AmbiguousBlockAssociation < Base
|
44
|
-
include
|
55
|
+
include AllowedMethods
|
56
|
+
include AllowedPattern
|
45
57
|
|
46
58
|
MSG = 'Parenthesize the param `%<param>s` to make sure that the ' \
|
47
59
|
'block will be associated with the `%<method>s` method ' \
|
@@ -52,7 +64,7 @@ module RuboCop
|
|
52
64
|
|
53
65
|
return unless ambiguous_block_association?(node)
|
54
66
|
return if node.parenthesized? || node.last_argument.lambda? || node.last_argument.proc? ||
|
55
|
-
|
67
|
+
allowed_method_pattern?(node)
|
56
68
|
|
57
69
|
message = message(node)
|
58
70
|
|
@@ -66,9 +78,10 @@ module RuboCop
|
|
66
78
|
send_node.last_argument.block_type? && !send_node.last_argument.send_node.arguments?
|
67
79
|
end
|
68
80
|
|
69
|
-
def
|
81
|
+
def allowed_method_pattern?(node)
|
70
82
|
node.assignment? || node.operator_method? || node.method?(:[]) ||
|
71
|
-
|
83
|
+
allowed_method?(node.last_argument.method_name) ||
|
84
|
+
matches_allowed_pattern?(node.last_argument.method_name)
|
72
85
|
end
|
73
86
|
|
74
87
|
def message(send_node)
|