rubocop 1.22.3 → 1.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +37 -4
- data/lib/rubocop/cop/gemspec/date_assignment.rb +2 -10
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +1 -10
- data/lib/rubocop/cop/gemspec/require_mfa.rb +146 -0
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -10
- data/lib/rubocop/cop/generator.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +22 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +11 -5
- data/lib/rubocop/cop/lint/ambiguous_range.rb +2 -2
- data/lib/rubocop/cop/lint/number_conversion.rb +5 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +117 -0
- data/lib/rubocop/cop/metrics/parameter_lists.rb +1 -1
- data/lib/rubocop/cop/mixin/gemspec_help.rb +30 -0
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -5
- data/lib/rubocop/cop/naming/file_name.rb +37 -4
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/format_string_token.rb +2 -1
- data/lib/rubocop/cop/style/open_struct_use.rb +69 -0
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +12 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +11 -1
- data/lib/rubocop/formatter/html_formatter.rb +5 -2
- data/lib/rubocop/formatter/json_formatter.rb +4 -1
- data/lib/rubocop/remote_config.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop/yaml_duplication_checker.rb +1 -1
- data/lib/rubocop.rb +4 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf11fe2d8f8be8879d6afc63d6f3be50b970c7910c83f1d22847d1fc9654d4aa
|
4
|
+
data.tar.gz: fd4c7ef3838a286efe3d1729672cc7a0e72f47cfb4c8d815699d53d2a974a372
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4014183525b58378a0e628ae5136d17c148a41c6c25dd51eddc810ca08fbd89d652f6c715b58eef149005af1145469936416864869b6e63a4c9e521627ab1cb4
|
7
|
+
data.tar.gz: 6e0e2a9a9d6fae829b73bd49814965a28d447207aaf7d1dda073f34130343557df965c77cc998d6ddb0d59eca09f1307d6ca56cbd3fcade575ca52950d1a56d3
|
data/README.md
CHANGED
@@ -54,7 +54,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
54
54
|
in your `Gemfile`:
|
55
55
|
|
56
56
|
```rb
|
57
|
-
gem 'rubocop', '~> 1.
|
57
|
+
gem 'rubocop', '~> 1.23', require: false
|
58
58
|
```
|
59
59
|
|
60
60
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
data/config/default.yml
CHANGED
@@ -150,6 +150,7 @@ AllCops:
|
|
150
150
|
rubocop-minitest: [minitest]
|
151
151
|
rubocop-sequel: [sequel]
|
152
152
|
rubocop-rake: [rake]
|
153
|
+
rubocop-graphql: [graphql]
|
153
154
|
|
154
155
|
#################### Bundler ###############################
|
155
156
|
|
@@ -258,6 +259,15 @@ Gemspec/OrderedDependencies:
|
|
258
259
|
Include:
|
259
260
|
- '**/*.gemspec'
|
260
261
|
|
262
|
+
Gemspec/RequireMFA:
|
263
|
+
Description: 'Checks that the gemspec has metadata to require MFA from RubyGems.'
|
264
|
+
Enabled: pending
|
265
|
+
VersionAdded: '1.23'
|
266
|
+
Reference:
|
267
|
+
- https://guides.rubygems.org/mfa-requirement-opt-in/
|
268
|
+
Include:
|
269
|
+
- '**/*.gemspec'
|
270
|
+
|
261
271
|
Gemspec/RequiredRubyVersion:
|
262
272
|
Description: 'Checks that `required_ruby_version` of gemspec is specified and equal to `TargetRubyVersion` of .rubocop.yml.'
|
263
273
|
Enabled: true
|
@@ -511,13 +521,13 @@ Layout/EmptyLineBetweenDefs:
|
|
511
521
|
StyleGuide: '#empty-lines-between-methods'
|
512
522
|
Enabled: true
|
513
523
|
VersionAdded: '0.49'
|
514
|
-
VersionChanged: '1.
|
524
|
+
VersionChanged: '1.23'
|
515
525
|
EmptyLineBetweenMethodDefs: true
|
516
526
|
EmptyLineBetweenClassDefs: true
|
517
527
|
EmptyLineBetweenModuleDefs: true
|
518
|
-
#
|
519
|
-
# need an empty line between them.
|
520
|
-
AllowAdjacentOneLineDefs:
|
528
|
+
# `AllowAdjacentOneLineDefs` means that single line method definitions don't
|
529
|
+
# need an empty line between them. `true` by default.
|
530
|
+
AllowAdjacentOneLineDefs: true
|
521
531
|
# Can be array to specify minimum and maximum number of empty lines, e.g. [1, 2]
|
522
532
|
NumberOfEmptyLines: 1
|
523
533
|
|
@@ -2308,6 +2318,11 @@ Lint/UselessMethodDefinition:
|
|
2308
2318
|
Safe: false
|
2309
2319
|
AllowComments: true
|
2310
2320
|
|
2321
|
+
Lint/UselessRuby2Keywords:
|
2322
|
+
Description: 'Finds unnecessary uses of `ruby2_keywords`.'
|
2323
|
+
Enabled: pending
|
2324
|
+
VersionAdded: '1.23'
|
2325
|
+
|
2311
2326
|
Lint/UselessSetterCall:
|
2312
2327
|
Description: 'Checks for useless setter call to a local variable.'
|
2313
2328
|
Enabled: true
|
@@ -2501,6 +2516,7 @@ Naming/FileName:
|
|
2501
2516
|
StyleGuide: '#snake-case-files'
|
2502
2517
|
Enabled: true
|
2503
2518
|
VersionAdded: '0.50'
|
2519
|
+
VersionChanged: '1.23'
|
2504
2520
|
# Camel case file names listed in `AllCops:Include` and all file names listed
|
2505
2521
|
# in `AllCops:Exclude` are excluded by default. Add extra excludes here.
|
2506
2522
|
Exclude: []
|
@@ -2513,6 +2529,13 @@ Naming/FileName:
|
|
2513
2529
|
# whether each source file's class or module name matches the file name --
|
2514
2530
|
# not whether the nested module hierarchy matches the subdirectory path.
|
2515
2531
|
CheckDefinitionPathHierarchy: true
|
2532
|
+
# paths that are considered root directories, for example "lib" in most ruby projects
|
2533
|
+
# or "app/models" in rails projects
|
2534
|
+
CheckDefinitionPathHierarchyRoots:
|
2535
|
+
- lib
|
2536
|
+
- spec
|
2537
|
+
- test
|
2538
|
+
- src
|
2516
2539
|
# If non-`nil`, expect all source file names to match the following regex.
|
2517
2540
|
# Only the file name itself is matched, not the entire file path.
|
2518
2541
|
# Use anchors as necessary if you want to match the entire name rather than
|
@@ -4216,6 +4239,16 @@ Style/OneLineConditional:
|
|
4216
4239
|
VersionAdded: '0.9'
|
4217
4240
|
VersionChanged: '0.90'
|
4218
4241
|
|
4242
|
+
Style/OpenStructUse:
|
4243
|
+
Description: >-
|
4244
|
+
Avoid using OpenStruct. As of Ruby 3.0, use is officially discouraged due to performance,
|
4245
|
+
version compatibility, and potential security issues.
|
4246
|
+
Reference:
|
4247
|
+
- https://docs.ruby-lang.org/en/3.0.0/OpenStruct.html#class-OpenStruct-label-Caveats
|
4248
|
+
|
4249
|
+
Enabled: pending
|
4250
|
+
VersionAdded: '1.23'
|
4251
|
+
|
4219
4252
|
Style/OptionHash:
|
4220
4253
|
Description: "Don't use option hashes when you can use keyword arguments."
|
4221
4254
|
Enabled: false
|
@@ -21,21 +21,13 @@ module RuboCop
|
|
21
21
|
#
|
22
22
|
class DateAssignment < Base
|
23
23
|
include RangeHelp
|
24
|
+
include GemspecHelp
|
24
25
|
extend AutoCorrector
|
25
26
|
|
26
27
|
MSG = 'Do not use `date =` in gemspec, it is set automatically when the gem is packaged.'
|
27
28
|
|
28
|
-
# @!method gem_specification(node)
|
29
|
-
def_node_matcher :gem_specification, <<~PATTERN
|
30
|
-
(block
|
31
|
-
(send
|
32
|
-
(const
|
33
|
-
(const {cbase nil?} :Gem) :Specification) :new)
|
34
|
-
...)
|
35
|
-
PATTERN
|
36
|
-
|
37
29
|
def on_block(block_node)
|
38
|
-
return unless gem_specification(block_node)
|
30
|
+
return unless gem_specification?(block_node)
|
39
31
|
|
40
32
|
block_parameter = block_node.arguments.first.source
|
41
33
|
|
@@ -36,20 +36,11 @@ module RuboCop
|
|
36
36
|
# end
|
37
37
|
class DuplicatedAssignment < Base
|
38
38
|
include RangeHelp
|
39
|
+
include GemspecHelp
|
39
40
|
|
40
41
|
MSG = '`%<assignment>s` method calls already given on line '\
|
41
42
|
'%<line_of_first_occurrence>d of the gemspec.'
|
42
43
|
|
43
|
-
# @!method gem_specification(node)
|
44
|
-
def_node_search :gem_specification, <<~PATTERN
|
45
|
-
(block
|
46
|
-
(send
|
47
|
-
(const
|
48
|
-
(const {cbase nil?} :Gem) :Specification) :new)
|
49
|
-
(args
|
50
|
-
(arg $_)) ...)
|
51
|
-
PATTERN
|
52
|
-
|
53
44
|
# @!method assignment_method_declarations(node)
|
54
45
|
def_node_search :assignment_method_declarations, <<~PATTERN
|
55
46
|
(send
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Gemspec
|
6
|
+
# Requires a gemspec to have `rubygems_mfa_required` metadata set.
|
7
|
+
#
|
8
|
+
# This setting tells RubyGems that MFA is required for accounts to
|
9
|
+
# be able perform any of these privileged operations:
|
10
|
+
#
|
11
|
+
# * gem push
|
12
|
+
# * gem yank
|
13
|
+
# * gem owner --add/remove
|
14
|
+
# * adding or removing owners using gem ownership page
|
15
|
+
#
|
16
|
+
# This helps make your gem more secure, as users can be more
|
17
|
+
# confident that gem updates were pushed by maintainers.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
#
|
21
|
+
# # bad
|
22
|
+
# Gem::Specification.new do |spec|
|
23
|
+
# # no `rubygems_mfa_required` metadata specified
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# Gem::Specification.new do |spec|
|
28
|
+
# spec.metadata = {
|
29
|
+
# 'rubygems_mfa_required' => 'true'
|
30
|
+
# }
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# # good
|
34
|
+
# Gem::Specification.new do |spec|
|
35
|
+
# spec.metadata['rubygems_mfa_required'] = 'true'
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # bad
|
39
|
+
# Gem::Specification.new do |spec|
|
40
|
+
# spec.metadata = {
|
41
|
+
# 'rubygems_mfa_required' => 'false'
|
42
|
+
# }
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# # good
|
46
|
+
# Gem::Specification.new do |spec|
|
47
|
+
# spec.metadata = {
|
48
|
+
# 'rubygems_mfa_required' => 'true'
|
49
|
+
# }
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# # bad
|
53
|
+
# Gem::Specification.new do |spec|
|
54
|
+
# spec.metadata['rubygems_mfa_required'] = 'false'
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# # good
|
58
|
+
# Gem::Specification.new do |spec|
|
59
|
+
# spec.metadata['rubygems_mfa_required'] = 'true'
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
class RequireMFA < Base
|
63
|
+
include GemspecHelp
|
64
|
+
extend AutoCorrector
|
65
|
+
|
66
|
+
MSG = "`metadata['rubygems_mfa_required']` must be set to `'true'`."
|
67
|
+
|
68
|
+
# @!method metadata(node)
|
69
|
+
def_node_matcher :metadata, <<~PATTERN
|
70
|
+
`{
|
71
|
+
(send _ :metadata= $_)
|
72
|
+
(send (send _ :metadata) :[]= (str "rubygems_mfa_required") $_)
|
73
|
+
}
|
74
|
+
PATTERN
|
75
|
+
|
76
|
+
# @!method rubygems_mfa_required(node)
|
77
|
+
def_node_search :rubygems_mfa_required, <<~PATTERN
|
78
|
+
(pair (str "rubygems_mfa_required") $_)
|
79
|
+
PATTERN
|
80
|
+
|
81
|
+
# @!method true_string?(node)
|
82
|
+
def_node_matcher :true_string?, <<~PATTERN
|
83
|
+
(str "true")
|
84
|
+
PATTERN
|
85
|
+
|
86
|
+
def on_block(node) # rubocop:disable Metrics/MethodLength
|
87
|
+
gem_specification(node) do |block_var|
|
88
|
+
metadata_value = metadata(node)
|
89
|
+
mfa_value = mfa_value(metadata_value)
|
90
|
+
|
91
|
+
if mfa_value
|
92
|
+
unless true_string?(mfa_value)
|
93
|
+
add_offense(mfa_value) do |corrector|
|
94
|
+
change_value(corrector, mfa_value)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
else
|
98
|
+
add_offense(node) do |corrector|
|
99
|
+
autocorrect(corrector, node, block_var, metadata_value)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def mfa_value(metadata_value)
|
108
|
+
return unless metadata_value
|
109
|
+
return metadata_value if metadata_value.str_type?
|
110
|
+
|
111
|
+
rubygems_mfa_required(metadata_value).first
|
112
|
+
end
|
113
|
+
|
114
|
+
def autocorrect(corrector, node, block_var, metadata)
|
115
|
+
if metadata
|
116
|
+
return unless metadata.hash_type?
|
117
|
+
|
118
|
+
correct_metadata(corrector, metadata)
|
119
|
+
else
|
120
|
+
correct_missing_metadata(corrector, node, block_var)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def correct_metadata(corrector, metadata)
|
125
|
+
if metadata.pairs.any?
|
126
|
+
corrector.insert_after(metadata.pairs.last, ",\n'rubygems_mfa_required' => 'true'")
|
127
|
+
else
|
128
|
+
corrector.insert_before(metadata.loc.end, "'rubygems_mfa_required' => 'true'")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def correct_missing_metadata(corrector, node, block_var)
|
133
|
+
corrector.insert_before(node.loc.end, <<~RUBY)
|
134
|
+
#{block_var}.metadata = {
|
135
|
+
'rubygems_mfa_required' => 'true'
|
136
|
+
}
|
137
|
+
RUBY
|
138
|
+
end
|
139
|
+
|
140
|
+
def change_value(corrector, value)
|
141
|
+
corrector.replace(value, "'true'")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -26,20 +26,13 @@ module RuboCop
|
|
26
26
|
# end
|
27
27
|
#
|
28
28
|
class RubyVersionGlobalsUsage < Base
|
29
|
+
include GemspecHelp
|
30
|
+
|
29
31
|
MSG = 'Do not use `RUBY_VERSION` in gemspec file.'
|
30
32
|
|
31
33
|
# @!method ruby_version?(node)
|
32
34
|
def_node_matcher :ruby_version?, '(const {cbase nil?} :RUBY_VERSION)'
|
33
35
|
|
34
|
-
# @!method gem_specification?(node)
|
35
|
-
def_node_search :gem_specification?, <<~PATTERN
|
36
|
-
(block
|
37
|
-
(send
|
38
|
-
(const
|
39
|
-
(const {cbase nil?} :Gem) :Specification) :new)
|
40
|
-
...)
|
41
|
-
PATTERN
|
42
|
-
|
43
36
|
def on_const(node)
|
44
37
|
return unless gem_spec_with_ruby_version?(node)
|
45
38
|
|
@@ -49,7 +42,7 @@ module RuboCop
|
|
49
42
|
private
|
50
43
|
|
51
44
|
def gem_spec_with_ruby_version?(node)
|
52
|
-
gem_specification
|
45
|
+
gem_specification(processed_source.ast) && ruby_version?(node)
|
53
46
|
end
|
54
47
|
end
|
55
48
|
end
|
@@ -150,7 +150,7 @@ module RuboCop
|
|
150
150
|
1. Modify the description of #{badge} in config/default.yml
|
151
151
|
2. Implement your new cop in the generated file!
|
152
152
|
3. Commit your new cop with a message such as
|
153
|
-
e.g. "Add new `#{badge}` cop
|
153
|
+
e.g. "Add new `#{badge}` cop"
|
154
154
|
4. Run `bundle exec rake changelog:new` to generate a changelog entry
|
155
155
|
for your new cop.
|
156
156
|
TODO
|
@@ -77,13 +77,34 @@ module RuboCop
|
|
77
77
|
# def b
|
78
78
|
# end
|
79
79
|
#
|
80
|
-
# @example AllowAdjacentOneLineDefs: true
|
80
|
+
# @example AllowAdjacentOneLineDefs: true (default)
|
81
81
|
#
|
82
82
|
# # good
|
83
83
|
# class ErrorA < BaseError; end
|
84
84
|
# class ErrorB < BaseError; end
|
85
85
|
# class ErrorC < BaseError; end
|
86
86
|
#
|
87
|
+
# # good
|
88
|
+
# class ErrorA < BaseError; end
|
89
|
+
#
|
90
|
+
# class ErrorB < BaseError; end
|
91
|
+
#
|
92
|
+
# class ErrorC < BaseError; end
|
93
|
+
#
|
94
|
+
# @example AllowAdjacentOneLineDefs: false
|
95
|
+
#
|
96
|
+
# # bad
|
97
|
+
# class ErrorA < BaseError; end
|
98
|
+
# class ErrorB < BaseError; end
|
99
|
+
# class ErrorC < BaseError; end
|
100
|
+
#
|
101
|
+
# # good
|
102
|
+
# class ErrorA < BaseError; end
|
103
|
+
#
|
104
|
+
# class ErrorB < BaseError; end
|
105
|
+
#
|
106
|
+
# class ErrorC < BaseError; end
|
107
|
+
#
|
87
108
|
class EmptyLineBetweenDefs < Base
|
88
109
|
include RangeHelp
|
89
110
|
extend AutoCorrector
|
@@ -30,15 +30,17 @@ module RuboCop
|
|
30
30
|
def on_send(node)
|
31
31
|
return unless arrow_lambda_with_args?(node)
|
32
32
|
|
33
|
-
lambda_node = range_of_offense(node)
|
34
|
-
|
35
33
|
if style == :require_space && !space_after_arrow?(node)
|
34
|
+
lambda_node = range_of_offense(node)
|
35
|
+
|
36
36
|
add_offense(lambda_node, message: MSG_REQUIRE_SPACE) do |corrector|
|
37
|
-
corrector.insert_before(node
|
37
|
+
corrector.insert_before(lambda_arguments(node), ' ')
|
38
38
|
end
|
39
39
|
elsif style == :require_no_space && space_after_arrow?(node)
|
40
|
-
|
41
|
-
|
40
|
+
space = space_after_arrow(node)
|
41
|
+
|
42
|
+
add_offense(space, message: MSG_REQUIRE_NO_SPACE) do |corrector|
|
43
|
+
corrector.remove(space)
|
42
44
|
end
|
43
45
|
end
|
44
46
|
end
|
@@ -66,6 +68,10 @@ module RuboCop
|
|
66
68
|
node.parent.arguments.loc.expression.end_pos
|
67
69
|
)
|
68
70
|
end
|
71
|
+
|
72
|
+
def lambda_arguments(node)
|
73
|
+
node.parent.children[1]
|
74
|
+
end
|
69
75
|
end
|
70
76
|
end
|
71
77
|
end
|
@@ -8,7 +8,7 @@ module RuboCop
|
|
8
8
|
# Ranges have quite low precedence, which leads to unexpected behaviour when
|
9
9
|
# using a range with other operators. This cop avoids that by making ranges
|
10
10
|
# explicit by requiring parenthesis around complex range boundaries (anything
|
11
|
-
# that is not a
|
11
|
+
# that is not a literal: numerics, strings, symbols, etc.).
|
12
12
|
#
|
13
13
|
# This cop can be configured with `RequireParenthesesForMethodChains` in order to
|
14
14
|
# specify whether method chains (including `self.foo`) should be wrapped in parens
|
@@ -81,7 +81,7 @@ module RuboCop
|
|
81
81
|
|
82
82
|
def acceptable?(node)
|
83
83
|
node.begin_type? ||
|
84
|
-
node.
|
84
|
+
node.literal? ||
|
85
85
|
node.variable? || node.const_type? || node.self_type? ||
|
86
86
|
(node.call_type? && acceptable_call?(node))
|
87
87
|
end
|
@@ -30,6 +30,7 @@ module RuboCop
|
|
30
30
|
# '10'.to_i
|
31
31
|
# '10.2'.to_f
|
32
32
|
# '10'.to_c
|
33
|
+
# '1/3'.to_r
|
33
34
|
# ['1', '2', '3'].map(&:to_i)
|
34
35
|
# foo.try(:to_f)
|
35
36
|
# bar.send(:to_c)
|
@@ -39,6 +40,7 @@ module RuboCop
|
|
39
40
|
# Integer('10', 10)
|
40
41
|
# Float('10.2')
|
41
42
|
# Complex('10')
|
43
|
+
# Rational('1/3')
|
42
44
|
# ['1', '2', '3'].map { |i| Integer(i, 10) }
|
43
45
|
# foo.try { |i| Float(i) }
|
44
46
|
# bar.send { |i| Complex(i) }
|
@@ -59,13 +61,14 @@ module RuboCop
|
|
59
61
|
CONVERSION_METHOD_CLASS_MAPPING = {
|
60
62
|
to_i: "#{Integer.name}(%<number_object>s, 10)",
|
61
63
|
to_f: "#{Float.name}(%<number_object>s)",
|
62
|
-
to_c: "#{Complex.name}(%<number_object>s)"
|
64
|
+
to_c: "#{Complex.name}(%<number_object>s)",
|
65
|
+
to_r: "#{Rational.name}(%<number_object>s)"
|
63
66
|
}.freeze
|
64
67
|
MSG = 'Replace unsafe number conversion with number '\
|
65
68
|
'class parsing, instead of using '\
|
66
69
|
'`%<current>s`, use stricter '\
|
67
70
|
'`%<corrected_method>s`.'
|
68
|
-
CONVERSION_METHODS = %i[Integer Float Complex to_i to_f to_c].freeze
|
71
|
+
CONVERSION_METHODS = %i[Integer Float Complex Rational to_i to_f to_c to_r].freeze
|
69
72
|
METHODS = CONVERSION_METHOD_CLASS_MAPPING.keys.map(&:inspect).join(' ')
|
70
73
|
|
71
74
|
# @!method to_method(node)
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop looks for `ruby2_keywords` calls for methods that do not need it.
|
7
|
+
#
|
8
|
+
# `ruby2_keywords` should only be called on methods that accept an argument splat
|
9
|
+
# (`*args`) but do not explicit keyword arguments (`k:` or `k: true`) or
|
10
|
+
# a keyword splat (`**kwargs`).
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# # good (splat argument without keyword arguments)
|
14
|
+
# ruby2_keywords def foo(*args); end
|
15
|
+
#
|
16
|
+
# # bad (no arguments)
|
17
|
+
# ruby2_keywords def foo; end
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# def foo; end
|
21
|
+
#
|
22
|
+
# # bad (positional argument)
|
23
|
+
# ruby2_keywords def foo(arg); end
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# def foo(arg); end
|
27
|
+
#
|
28
|
+
# # bad (double splatted argument)
|
29
|
+
# ruby2_keywords def foo(**args); end
|
30
|
+
#
|
31
|
+
# # good
|
32
|
+
# def foo(**args); end
|
33
|
+
#
|
34
|
+
# # bad (keyword arguments)
|
35
|
+
# ruby2_keywords def foo(i:, j:); end
|
36
|
+
#
|
37
|
+
# # good
|
38
|
+
# def foo(i:, j:); end
|
39
|
+
#
|
40
|
+
# # bad (splat argument with keyword arguments)
|
41
|
+
# ruby2_keywords def foo(*args, i:, j:); end
|
42
|
+
#
|
43
|
+
# # good
|
44
|
+
# def foo(*args, i:, j:); end
|
45
|
+
#
|
46
|
+
# # bad (splat argument with double splat)
|
47
|
+
# ruby2_keywords def foo(*args, **kwargs); end
|
48
|
+
#
|
49
|
+
# # good
|
50
|
+
# def foo(*args, **kwargs); end
|
51
|
+
#
|
52
|
+
# # bad (ruby2_keywords given a symbol)
|
53
|
+
# def foo; end
|
54
|
+
# ruby2_keywords :foo
|
55
|
+
#
|
56
|
+
# # good
|
57
|
+
# def foo; end
|
58
|
+
#
|
59
|
+
# # bad (ruby2_keywords with dynamic method)
|
60
|
+
# define_method(:foo) { |arg| }
|
61
|
+
# ruby2_keywords :foo
|
62
|
+
#
|
63
|
+
# # good
|
64
|
+
# define_method(:foo) { |arg| }
|
65
|
+
#
|
66
|
+
class UselessRuby2Keywords < Base
|
67
|
+
MSG = '`ruby2_keywords` is unnecessary for method `%<method_name>s`.'
|
68
|
+
RESTRICT_ON_SEND = %i[ruby2_keywords].freeze
|
69
|
+
|
70
|
+
# Looks for statically or dynamically defined methods with a given name
|
71
|
+
# @!method method_definition(node, method_name)
|
72
|
+
def_node_matcher :method_definition, <<~PATTERN
|
73
|
+
{
|
74
|
+
(def %1 ...)
|
75
|
+
({block numblock} (send _ :define_method (sym %1)) ...)
|
76
|
+
}
|
77
|
+
PATTERN
|
78
|
+
|
79
|
+
def on_send(node)
|
80
|
+
if node.first_argument.def_type?
|
81
|
+
inspect_def(node, node.first_argument)
|
82
|
+
elsif node.first_argument.sym_type?
|
83
|
+
inspect_sym(node, node.first_argument)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def inspect_def(node, def_node)
|
90
|
+
return if allowed_arguments(def_node.arguments)
|
91
|
+
|
92
|
+
add_offense(node.loc.selector, message: format(MSG, method_name: def_node.method_name))
|
93
|
+
end
|
94
|
+
|
95
|
+
def inspect_sym(node, sym_node)
|
96
|
+
return unless node.parent
|
97
|
+
|
98
|
+
method_name = sym_node.value
|
99
|
+
definition = node.parent.each_child_node.detect { |n| method_definition(n, method_name) }
|
100
|
+
|
101
|
+
return unless definition
|
102
|
+
return if allowed_arguments(definition.arguments)
|
103
|
+
|
104
|
+
add_offense(node, message: format(MSG, method_name: method_name))
|
105
|
+
end
|
106
|
+
|
107
|
+
# `ruby2_keywords` is only allowed if there's a `restarg` and no keyword arguments
|
108
|
+
def allowed_arguments(arguments)
|
109
|
+
return false if arguments.empty?
|
110
|
+
|
111
|
+
arguments.each_child_node(:restarg).any? &&
|
112
|
+
arguments.each_child_node(:kwarg, :kwoptarg, :kwrestarg).none?
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
# as they add less complexity than positional or optional parameters.
|
11
11
|
#
|
12
12
|
# NOTE: Explicit block argument `&block` is not counted to prevent
|
13
|
-
#
|
13
|
+
# erroneous change that is avoided by making block argument implicit.
|
14
14
|
#
|
15
15
|
# @example Max: 3
|
16
16
|
# # good
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Common functionality for checking gem declarations.
|
6
|
+
module GemspecHelp
|
7
|
+
extend NodePattern::Macros
|
8
|
+
|
9
|
+
# @!method gem_specification?(node)
|
10
|
+
def_node_matcher :gem_specification?, <<~PATTERN
|
11
|
+
(block
|
12
|
+
(send
|
13
|
+
(const
|
14
|
+
(const {cbase nil?} :Gem) :Specification) :new)
|
15
|
+
(args
|
16
|
+
(arg $_)) ...)
|
17
|
+
PATTERN
|
18
|
+
|
19
|
+
# @!method gem_specification(node)
|
20
|
+
def_node_search :gem_specification, <<~PATTERN
|
21
|
+
(block
|
22
|
+
(send
|
23
|
+
(const
|
24
|
+
(const {cbase nil?} :Gem) :Specification) :new)
|
25
|
+
(args
|
26
|
+
(arg $_)) ...)
|
27
|
+
PATTERN
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -13,11 +13,7 @@ module RuboCop
|
|
13
13
|
if style == :single_quotes
|
14
14
|
!double_quotes_required?(src)
|
15
15
|
else
|
16
|
-
|
17
|
-
# 1. It contains a double quote
|
18
|
-
# 2. It contains text that would become an escape sequence with double quotes
|
19
|
-
# 3. It contains text that would become an interpolation with double quotes
|
20
|
-
!/" | (?<!\\)\\[aAbcdefkMnprsStuUxzZ0-7] | \#[@{$]/x.match?(src)
|
16
|
+
!/" | \\[^'\\] | \#[@{$]/x.match?(src)
|
21
17
|
end
|
22
18
|
end
|
23
19
|
end
|
@@ -14,6 +14,18 @@ module RuboCop
|
|
14
14
|
# (i.e. `bundler-console` becomes `Bundler::Console`). As such, the
|
15
15
|
# gemspec is supposed to be named `bundler-console.gemspec`.
|
16
16
|
#
|
17
|
+
# When `ExpectMatchingDefinition` (default: `false`) is `true`, the cop requires
|
18
|
+
# each file to have a class, module or `Struct` defined in it that matches
|
19
|
+
# the filename. This can be further configured using
|
20
|
+
# `CheckDefinitionPathHierarchy` (default: `true`) to determine whether the
|
21
|
+
# path should match the namespace of the above definition.
|
22
|
+
#
|
23
|
+
# When `IgnoreExecutableScripts` (default: `true`) is `true`, files that start
|
24
|
+
# with a shebang line are not considered by the cop.
|
25
|
+
#
|
26
|
+
# When `Regex` is set, the cop will flag any filename that does not match
|
27
|
+
# the regular expression.
|
28
|
+
#
|
17
29
|
# @example
|
18
30
|
# # bad
|
19
31
|
# lib/layoutManager.rb
|
@@ -28,11 +40,19 @@ module RuboCop
|
|
28
40
|
include RangeHelp
|
29
41
|
|
30
42
|
MSG_SNAKE_CASE = 'The name of this source file (`%<basename>s`) should use snake_case.'
|
31
|
-
MSG_NO_DEFINITION = '
|
43
|
+
MSG_NO_DEFINITION = '`%<basename>s` should define a class or module called `%<namespace>s`.'
|
32
44
|
MSG_REGEX = '`%<basename>s` should match `%<regex>s`.'
|
33
45
|
|
34
46
|
SNAKE_CASE = /^[\d[[:lower:]]_.?!]+$/.freeze
|
35
47
|
|
48
|
+
# @!method struct_definition(node)
|
49
|
+
def_node_matcher :struct_definition, <<~PATTERN
|
50
|
+
{
|
51
|
+
(casgn $_ $_ (send (const {nil? cbase} :Struct) :new ...))
|
52
|
+
(casgn $_ $_ (block (send (const {nil? cbase} :Struct) :new ...) ...))
|
53
|
+
}
|
54
|
+
PATTERN
|
55
|
+
|
36
56
|
def on_new_investigation
|
37
57
|
file_path = processed_source.file_path
|
38
58
|
return if config.file_to_exclude?(file_path) || config.allowed_camel_case_file?(file_path)
|
@@ -103,6 +123,10 @@ module RuboCop
|
|
103
123
|
cop_config['CheckDefinitionPathHierarchy']
|
104
124
|
end
|
105
125
|
|
126
|
+
def definition_path_hierarchy_roots
|
127
|
+
cop_config['CheckDefinitionPathHierarchyRoots'] || []
|
128
|
+
end
|
129
|
+
|
106
130
|
def regex
|
107
131
|
cop_config['Regex']
|
108
132
|
end
|
@@ -126,7 +150,7 @@ module RuboCop
|
|
126
150
|
name = namespace.pop
|
127
151
|
|
128
152
|
on_node(%i[class module casgn], node) do |child|
|
129
|
-
next unless (const = child
|
153
|
+
next unless (const = find_definition(child))
|
130
154
|
|
131
155
|
const_namespace, const_name = *const
|
132
156
|
next if name != const_name && !match_acronym?(name, const_name)
|
@@ -138,6 +162,15 @@ module RuboCop
|
|
138
162
|
nil
|
139
163
|
end
|
140
164
|
|
165
|
+
def find_definition(node)
|
166
|
+
node.defined_module || defined_struct(node)
|
167
|
+
end
|
168
|
+
|
169
|
+
def defined_struct(node)
|
170
|
+
namespace, name = *struct_definition(node)
|
171
|
+
s(:const, namespace, name) if name
|
172
|
+
end
|
173
|
+
|
141
174
|
def match_namespace(node, namespace, expected)
|
142
175
|
match_partial = partial_matcher!(expected)
|
143
176
|
|
@@ -177,13 +210,13 @@ module RuboCop
|
|
177
210
|
allowed_acronyms.any? { |acronym| expected.gsub(acronym.capitalize, acronym) == name }
|
178
211
|
end
|
179
212
|
|
180
|
-
def to_namespace(path)
|
213
|
+
def to_namespace(path) # rubocop:disable Metrics/AbcSize
|
181
214
|
components = Pathname(path).each_filename.to_a
|
182
215
|
# To convert a pathname to a Ruby namespace, we need a starting point
|
183
216
|
# But RC can be run from any working directory, and can check any path
|
184
217
|
# We can't assume that the working directory, or any other, is the
|
185
218
|
# "starting point" to build a namespace.
|
186
|
-
start =
|
219
|
+
start = definition_path_hierarchy_roots
|
187
220
|
start_index = nil
|
188
221
|
|
189
222
|
# To find the closest namespace root take the path components, and
|
@@ -102,7 +102,8 @@ module RuboCop
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def use_ignored_method?(node)
|
105
|
-
|
105
|
+
send_parent = node.each_ancestor(:send).first
|
106
|
+
send_parent && ignored_method?(send_parent.method_name)
|
106
107
|
end
|
107
108
|
|
108
109
|
def unannotated_format?(node, detected_style)
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop flags uses of OpenStruct, as it is now officially discouraged
|
7
|
+
# to be used for performance, version compatibility, and potential security issues.
|
8
|
+
#
|
9
|
+
# @safety
|
10
|
+
#
|
11
|
+
# Note that this cop may flag false positives; for instance, the following legal
|
12
|
+
# use of a hand-rolled `OpenStruct` type would be considered an offense:
|
13
|
+
#
|
14
|
+
# ```
|
15
|
+
# module MyNamespace
|
16
|
+
# class OpenStruct # not the OpenStruct we're looking for
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# def new_struct
|
20
|
+
# OpenStruct.new # resolves to MyNamespace::OpenStruct
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
# ```
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
#
|
27
|
+
# # bad
|
28
|
+
# point = OpenStruct.new(x: 0, y: 1)
|
29
|
+
#
|
30
|
+
# # good
|
31
|
+
# Point = Struct.new(:x, :y)
|
32
|
+
# point = Point.new(0, 1)
|
33
|
+
#
|
34
|
+
# # also good
|
35
|
+
# point = { x: 0, y: 1 }
|
36
|
+
#
|
37
|
+
# # bad
|
38
|
+
# test_double = OpenStruct.new(a: 'b')
|
39
|
+
#
|
40
|
+
# # good (assumes test using rspec-mocks)
|
41
|
+
# test_double = double
|
42
|
+
# allow(test_double).to receive(:a).and_return('b')
|
43
|
+
#
|
44
|
+
class OpenStructUse < Base
|
45
|
+
MSG = 'Avoid using `OpenStruct`; use `Struct`, `Hash`, a class or test doubles instead.'
|
46
|
+
|
47
|
+
# @!method uses_open_struct?(node)
|
48
|
+
def_node_matcher :uses_open_struct?, <<-PATTERN
|
49
|
+
(const {nil? (cbase)} :OpenStruct)
|
50
|
+
PATTERN
|
51
|
+
|
52
|
+
def on_const(node)
|
53
|
+
return unless uses_open_struct?(node)
|
54
|
+
return if custom_class_or_module_definition?(node)
|
55
|
+
|
56
|
+
add_offense(node)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def custom_class_or_module_definition?(node)
|
62
|
+
parent = node.parent
|
63
|
+
|
64
|
+
(parent.class_type? || parent.module_type?) && node.left_siblings.empty?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -56,6 +56,7 @@ module RuboCop
|
|
56
56
|
class ParenthesesAroundCondition < Base
|
57
57
|
include SafeAssignment
|
58
58
|
include Parentheses
|
59
|
+
include RangeHelp
|
59
60
|
extend AutoCorrector
|
60
61
|
|
61
62
|
def on_if(node)
|
@@ -73,13 +74,14 @@ module RuboCop
|
|
73
74
|
|
74
75
|
# @!method control_op_condition(node)
|
75
76
|
def_node_matcher :control_op_condition, <<~PATTERN
|
76
|
-
(begin $_
|
77
|
+
(begin $_ $...)
|
77
78
|
PATTERN
|
78
79
|
|
79
80
|
def process_control_op(node)
|
80
81
|
cond = node.condition
|
81
82
|
|
82
|
-
control_op_condition(cond) do |first_child|
|
83
|
+
control_op_condition(cond) do |first_child, rest_children|
|
84
|
+
return if semicolon_separated_expressions?(first_child, rest_children)
|
83
85
|
return if modifier_op?(first_child)
|
84
86
|
return if parens_allowed?(cond)
|
85
87
|
|
@@ -90,6 +92,14 @@ module RuboCop
|
|
90
92
|
end
|
91
93
|
end
|
92
94
|
|
95
|
+
def semicolon_separated_expressions?(first_exp, rest_exps)
|
96
|
+
return false unless (second_exp = rest_exps.first)
|
97
|
+
|
98
|
+
range = range_between(first_exp.source_range.end_pos, second_exp.source_range.begin_pos)
|
99
|
+
|
100
|
+
range.source.include?(';')
|
101
|
+
end
|
102
|
+
|
93
103
|
def modifier_op?(node)
|
94
104
|
return false if node.if_type? && node.ternary?
|
95
105
|
return true if node.rescue_type?
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
46
46
|
|
47
47
|
message = style == :single_quotes ? MSG_SINGLE : MSG_DOUBLE
|
48
48
|
|
49
|
-
if wrong_quotes?(node)
|
49
|
+
if wrong_quotes?(node) || invalid_double_quotes?(node.source)
|
50
50
|
add_offense(node, message: message) do |corrector|
|
51
51
|
opposite_style_detected
|
52
52
|
autocorrect(corrector, node)
|
@@ -58,6 +58,16 @@ module RuboCop
|
|
58
58
|
|
59
59
|
private
|
60
60
|
|
61
|
+
def invalid_double_quotes?(source)
|
62
|
+
return false unless style == :double_quotes
|
63
|
+
|
64
|
+
# The string needs single quotes if:
|
65
|
+
# 1. It contains a double quote
|
66
|
+
# 2. It contains text that would become an escape sequence with double quotes
|
67
|
+
# 3. It contains text that would become an interpolation with double quotes
|
68
|
+
!/" | (?<!\\)\\[aAbcdefkMnprsStuUxzZ0-7] | \#[@{$]/x.match?(source)
|
69
|
+
end
|
70
|
+
|
61
71
|
def autocorrect(corrector, node)
|
62
72
|
str = if hash_colon_key?(node)
|
63
73
|
# strip quotes
|
@@ -23,12 +23,15 @@ module RuboCop
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
Summary = Struct.new(:offense_count, :inspected_files, :target_files, keyword_init: true)
|
27
|
+
FileOffenses = Struct.new(:path, :offenses, keyword_init: true)
|
28
|
+
|
26
29
|
attr_reader :files, :summary
|
27
30
|
|
28
31
|
def initialize(output, options = {})
|
29
32
|
super
|
30
33
|
@files = []
|
31
|
-
@summary =
|
34
|
+
@summary = Summary.new(offense_count: 0)
|
32
35
|
end
|
33
36
|
|
34
37
|
def started(target_files)
|
@@ -36,7 +39,7 @@ module RuboCop
|
|
36
39
|
end
|
37
40
|
|
38
41
|
def file_finished(file, offenses)
|
39
|
-
files <<
|
42
|
+
files << FileOffenses.new(path: file, offenses: offenses)
|
40
43
|
summary.offense_count += offenses.count
|
41
44
|
end
|
42
45
|
|
@@ -59,12 +59,15 @@ module RuboCop
|
|
59
59
|
end
|
60
60
|
|
61
61
|
# TODO: Consider better solution for Offense#real_column.
|
62
|
+
# The minimum value of `start_column: real_column` is 1.
|
63
|
+
# So, the minimum value of `last_column` should be 1.
|
64
|
+
# And non-zero value of `last_column` should be used as is.
|
62
65
|
def hash_for_location(offense)
|
63
66
|
{
|
64
67
|
start_line: offense.line,
|
65
68
|
start_column: offense.real_column,
|
66
69
|
last_line: offense.last_line,
|
67
|
-
last_column: offense.last_column,
|
70
|
+
last_column: offense.last_column.zero? ? 1 : offense.last_column,
|
68
71
|
length: offense.location.length,
|
69
72
|
# `line` and `column` exist for compatibility.
|
70
73
|
# Use `start_line` and `start_column` instead.
|
data/lib/rubocop/version.rb
CHANGED
@@ -23,7 +23,7 @@ module RuboCop
|
|
23
23
|
when Psych::Nodes::Mapping
|
24
24
|
tree.children.each_slice(2).with_object([]) do |(key, value), keys|
|
25
25
|
exist = keys.find { |key2| key2.value == key.value }
|
26
|
-
|
26
|
+
yield(exist, key) if exist
|
27
27
|
keys << key
|
28
28
|
traverse(value, &on_duplicated)
|
29
29
|
end
|
data/lib/rubocop.rb
CHANGED
@@ -83,6 +83,7 @@ require_relative 'rubocop/cop/mixin/enforce_superclass'
|
|
83
83
|
require_relative 'rubocop/cop/mixin/first_element_line_break'
|
84
84
|
require_relative 'rubocop/cop/mixin/frozen_string_literal'
|
85
85
|
require_relative 'rubocop/cop/mixin/gem_declaration'
|
86
|
+
require_relative 'rubocop/cop/mixin/gemspec_help'
|
86
87
|
require_relative 'rubocop/cop/mixin/hash_alignment_styles'
|
87
88
|
require_relative 'rubocop/cop/mixin/hash_transform_method'
|
88
89
|
require_relative 'rubocop/cop/mixin/ignored_pattern'
|
@@ -160,6 +161,7 @@ require_relative 'rubocop/cop/bundler/ordered_gems'
|
|
160
161
|
require_relative 'rubocop/cop/gemspec/date_assignment'
|
161
162
|
require_relative 'rubocop/cop/gemspec/duplicated_assignment'
|
162
163
|
require_relative 'rubocop/cop/gemspec/ordered_dependencies'
|
164
|
+
require_relative 'rubocop/cop/gemspec/require_mfa'
|
163
165
|
require_relative 'rubocop/cop/gemspec/required_ruby_version'
|
164
166
|
require_relative 'rubocop/cop/gemspec/ruby_version_globals_usage'
|
165
167
|
|
@@ -382,6 +384,7 @@ require_relative 'rubocop/cop/lint/useless_access_modifier'
|
|
382
384
|
require_relative 'rubocop/cop/lint/useless_assignment'
|
383
385
|
require_relative 'rubocop/cop/lint/useless_else_without_rescue'
|
384
386
|
require_relative 'rubocop/cop/lint/useless_method_definition'
|
387
|
+
require_relative 'rubocop/cop/lint/useless_ruby2_keywords'
|
385
388
|
require_relative 'rubocop/cop/lint/useless_setter_call'
|
386
389
|
require_relative 'rubocop/cop/lint/useless_times'
|
387
390
|
require_relative 'rubocop/cop/lint/void'
|
@@ -514,6 +517,7 @@ require_relative 'rubocop/cop/style/method_call_without_args_parentheses'
|
|
514
517
|
require_relative 'rubocop/cop/style/method_call_with_args_parentheses'
|
515
518
|
require_relative 'rubocop/cop/style/multiline_in_pattern_then'
|
516
519
|
require_relative 'rubocop/cop/style/numbered_parameters'
|
520
|
+
require_relative 'rubocop/cop/style/open_struct_use'
|
517
521
|
require_relative 'rubocop/cop/style/redundant_assignment'
|
518
522
|
require_relative 'rubocop/cop/style/redundant_fetch_block'
|
519
523
|
require_relative 'rubocop/cop/style/redundant_file_extension_in_require'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.23.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-11-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: parallel
|
@@ -250,6 +250,7 @@ files:
|
|
250
250
|
- lib/rubocop/cop/gemspec/date_assignment.rb
|
251
251
|
- lib/rubocop/cop/gemspec/duplicated_assignment.rb
|
252
252
|
- lib/rubocop/cop/gemspec/ordered_dependencies.rb
|
253
|
+
- lib/rubocop/cop/gemspec/require_mfa.rb
|
253
254
|
- lib/rubocop/cop/gemspec/required_ruby_version.rb
|
254
255
|
- lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb
|
255
256
|
- lib/rubocop/cop/generator.rb
|
@@ -493,6 +494,7 @@ files:
|
|
493
494
|
- lib/rubocop/cop/lint/useless_assignment.rb
|
494
495
|
- lib/rubocop/cop/lint/useless_else_without_rescue.rb
|
495
496
|
- lib/rubocop/cop/lint/useless_method_definition.rb
|
497
|
+
- lib/rubocop/cop/lint/useless_ruby2_keywords.rb
|
496
498
|
- lib/rubocop/cop/lint/useless_setter_call.rb
|
497
499
|
- lib/rubocop/cop/lint/useless_times.rb
|
498
500
|
- lib/rubocop/cop/lint/void.rb
|
@@ -538,6 +540,7 @@ files:
|
|
538
540
|
- lib/rubocop/cop/mixin/first_element_line_break.rb
|
539
541
|
- lib/rubocop/cop/mixin/frozen_string_literal.rb
|
540
542
|
- lib/rubocop/cop/mixin/gem_declaration.rb
|
543
|
+
- lib/rubocop/cop/mixin/gemspec_help.rb
|
541
544
|
- lib/rubocop/cop/mixin/hash_alignment_styles.rb
|
542
545
|
- lib/rubocop/cop/mixin/hash_transform_method.rb
|
543
546
|
- lib/rubocop/cop/mixin/heredoc.rb
|
@@ -740,6 +743,7 @@ files:
|
|
740
743
|
- lib/rubocop/cop/style/numeric_literals.rb
|
741
744
|
- lib/rubocop/cop/style/numeric_predicate.rb
|
742
745
|
- lib/rubocop/cop/style/one_line_conditional.rb
|
746
|
+
- lib/rubocop/cop/style/open_struct_use.rb
|
743
747
|
- lib/rubocop/cop/style/option_hash.rb
|
744
748
|
- lib/rubocop/cop/style/optional_arguments.rb
|
745
749
|
- lib/rubocop/cop/style/optional_boolean_parameter.rb
|
@@ -899,8 +903,9 @@ metadata:
|
|
899
903
|
homepage_uri: https://rubocop.org/
|
900
904
|
changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
|
901
905
|
source_code_uri: https://github.com/rubocop/rubocop/
|
902
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
906
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.23/
|
903
907
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
908
|
+
rubygems_mfa_required: 'true'
|
904
909
|
post_install_message:
|
905
910
|
rdoc_options: []
|
906
911
|
require_paths:
|