rubocop 1.23.0 → 1.25.1
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/LICENSE.txt +1 -1
- data/README.md +2 -3
- data/config/default.yml +60 -12
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +1 -1
- data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
- data/lib/rubocop/cli/command/show_docs_url.rb +48 -0
- data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
- data/lib/rubocop/cli.rb +1 -0
- data/lib/rubocop/config_loader_resolver.rb +1 -1
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/if_then_corrector.rb +55 -0
- data/lib/rubocop/cop/documentation.rb +19 -2
- data/lib/rubocop/cop/gemspec/require_mfa.rb +8 -10
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +10 -3
- data/lib/rubocop/cop/generator.rb +4 -3
- data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +47 -0
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +3 -1
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +36 -9
- data/lib/rubocop/cop/layout/comment_indentation.rb +31 -2
- data/lib/rubocop/cop/layout/dot_position.rb +4 -0
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +5 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +7 -2
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_first_arg.rb +4 -0
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +5 -1
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +16 -4
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +6 -0
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +10 -5
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +7 -4
- data/lib/rubocop/cop/metrics/block_length.rb +1 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -9
- data/lib/rubocop/cop/metrics/method_length.rb +1 -0
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +1 -1
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +5 -0
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +4 -3
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +82 -0
- data/lib/rubocop/cop/naming/block_forwarding.rb +121 -0
- data/lib/rubocop/cop/naming/method_parameter_name.rb +1 -1
- data/lib/rubocop/cop/security/open.rb +11 -1
- data/lib/rubocop/cop/style/character_literal.rb +8 -1
- data/lib/rubocop/cop/style/collection_compact.rb +31 -13
- data/lib/rubocop/cop/style/combinable_loops.rb +2 -2
- data/lib/rubocop/cop/style/empty_case_condition.rb +10 -0
- data/lib/rubocop/cop/style/file_read.rb +112 -0
- data/lib/rubocop/cop/style/file_write.rb +124 -0
- data/lib/rubocop/cop/style/hash_conversion.rb +2 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +36 -0
- data/lib/rubocop/cop/style/hash_transform_keys.rb +6 -6
- data/lib/rubocop/cop/style/hash_transform_values.rb +6 -6
- data/lib/rubocop/cop/style/if_inside_else.rb +15 -0
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
- data/lib/rubocop/cop/style/map_to_hash.rb +68 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +20 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -1
- data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -13
- data/lib/rubocop/cop/style/numeric_literals.rb +10 -1
- data/lib/rubocop/cop/style/one_line_conditional.rb +18 -39
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -6
- data/lib/rubocop/cop/style/redundant_interpolation.rb +17 -3
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +5 -1
- data/lib/rubocop/cop/style/redundant_self.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +1 -5
- data/lib/rubocop/cop/style/sample.rb +5 -3
- data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -1
- data/lib/rubocop/cop/style/swap_values.rb +2 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +16 -2
- data/lib/rubocop/cop/team.rb +1 -1
- data/lib/rubocop/cop/util.rb +9 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +16 -2
- data/lib/rubocop/options.rb +6 -1
- data/lib/rubocop/remote_config.rb +1 -3
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +7 -0
- metadata +15 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54b88752efa8bb84dc034391460b9071f31179dcb279550a209d31829e7b8c93
|
4
|
+
data.tar.gz: 31115cff5fdbf562dee62cf7e07033205d150b61ac5fd11476708f21e67000cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acdaf069659a775853b20e05734e85cd65c0c8734b09e568d4360dc9a7440a49ec8e47928b0da78866e1326a588638d18f2564e6e94023bb17b2f39493555027
|
7
|
+
data.tar.gz: 2765d9c9c10966c485be6cd70190b69a25aa99800c8d483bd67c1fdfe3dc5d13bb97cb1ca7f9f663776869acda5a426bc797f3b40adda17e0241ff8b62a374f1
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -9,7 +9,6 @@
|
|
9
9
|
[](https://github.com/rubocop/rubocop/actions?query=workflow%3ACI)
|
10
10
|
[](https://codeclimate.com/github/rubocop/rubocop/test_coverage)
|
11
11
|
[](https://codeclimate.com/github/rubocop/rubocop/maintainability)
|
12
|
-
[](https://dependabot.com/compatibility-score.html?dependency-name=rubocop&package-manager=bundler&version-scheme=semver)
|
13
12
|
[](https://discord.gg/wJjWvGRDmm)
|
14
13
|
|
15
14
|
> Role models are important. <br/>
|
@@ -54,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
54
53
|
in your `Gemfile`:
|
55
54
|
|
56
55
|
```rb
|
57
|
-
gem 'rubocop', '~> 1.
|
56
|
+
gem 'rubocop', '~> 1.25', require: false
|
58
57
|
```
|
59
58
|
|
60
59
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
@@ -245,5 +244,5 @@ RuboCop's changelog is available [here](CHANGELOG.md).
|
|
245
244
|
|
246
245
|
## Copyright
|
247
246
|
|
248
|
-
Copyright (c) 2012-
|
247
|
+
Copyright (c) 2012-2022 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for
|
249
248
|
further details.
|
data/config/default.yml
CHANGED
@@ -78,6 +78,8 @@ AllCops:
|
|
78
78
|
# When specifying style guide URLs, any paths and/or fragments will be
|
79
79
|
# evaluated relative to the base URL.
|
80
80
|
StyleGuideBaseURL: https://rubystyle.guide
|
81
|
+
# Documentation URLs will be constructed using the base URL.
|
82
|
+
DocumentationBaseURL: https://docs.rubocop.org/rubocop
|
81
83
|
# Extra details are not displayed in offense messages by default. Change
|
82
84
|
# behavior by overriding ExtraDetails, or by giving the
|
83
85
|
# `-E/--extra-details` option.
|
@@ -428,13 +430,13 @@ Layout/ClassStructure:
|
|
428
430
|
- prepend
|
429
431
|
- extend
|
430
432
|
ExpectedOrder:
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
433
|
+
- module_inclusion
|
434
|
+
- constants
|
435
|
+
- public_class_methods
|
436
|
+
- initializer
|
437
|
+
- public_methods
|
438
|
+
- protected_methods
|
439
|
+
- private_methods
|
438
440
|
|
439
441
|
Layout/ClosingHeredocIndentation:
|
440
442
|
Description: 'Checks the indentation of here document closings.'
|
@@ -449,7 +451,11 @@ Layout/ClosingParenthesisIndentation:
|
|
449
451
|
Layout/CommentIndentation:
|
450
452
|
Description: 'Indentation of comments.'
|
451
453
|
Enabled: true
|
454
|
+
# When true, allows comments to have extra indentation if that aligns them
|
455
|
+
# with a comment on the preceding line.
|
456
|
+
AllowForAlignment: false
|
452
457
|
VersionAdded: '0.49'
|
458
|
+
VersionChanged: '1.24'
|
453
459
|
|
454
460
|
Layout/ConditionPosition:
|
455
461
|
Description: >-
|
@@ -1796,7 +1802,9 @@ Lint/ImplicitStringConcatenation:
|
|
1796
1802
|
Lint/IncompatibleIoSelectWithFiberScheduler:
|
1797
1803
|
Description: 'Checks for `IO.select` that is incompatible with Fiber Scheduler.'
|
1798
1804
|
Enabled: pending
|
1805
|
+
SafeAutoCorrect: false
|
1799
1806
|
VersionAdded: '1.21'
|
1807
|
+
VersionChanged: '1.24'
|
1800
1808
|
|
1801
1809
|
Lint/IneffectiveAccessModifier:
|
1802
1810
|
Description: >-
|
@@ -1892,7 +1900,7 @@ Lint/NestedPercentLiteral:
|
|
1892
1900
|
VersionAdded: '0.52'
|
1893
1901
|
|
1894
1902
|
Lint/NextWithoutAccumulator:
|
1895
|
-
Description:
|
1903
|
+
Description: >-
|
1896
1904
|
Do not omit the accumulator when calling `next`
|
1897
1905
|
in a `reduce`/`inject` block.
|
1898
1906
|
Enabled: true
|
@@ -2479,6 +2487,17 @@ Naming/BinaryOperatorParameterName:
|
|
2479
2487
|
VersionAdded: '0.50'
|
2480
2488
|
VersionChanged: '1.2'
|
2481
2489
|
|
2490
|
+
Naming/BlockForwarding:
|
2491
|
+
Description: 'Use anonymous block forwarding.'
|
2492
|
+
StyleGuide: '#block-forwarding'
|
2493
|
+
Enabled: pending
|
2494
|
+
VersionAdded: '1.24'
|
2495
|
+
EnforcedStyle: anonymous
|
2496
|
+
SupportedStyles:
|
2497
|
+
- anonymous
|
2498
|
+
- explicit
|
2499
|
+
BlockForwardingName: block
|
2500
|
+
|
2482
2501
|
Naming/BlockParameterName:
|
2483
2502
|
Description: >-
|
2484
2503
|
Checks for block parameter names that contain capital letters,
|
@@ -3134,7 +3153,7 @@ Style/ClassMethodsDefinitions:
|
|
3134
3153
|
StyleGuide: '#def-self-class-methods'
|
3135
3154
|
Enabled: false
|
3136
3155
|
VersionAdded: '0.89'
|
3137
|
-
EnforcedStyle:
|
3156
|
+
EnforcedStyle: def_self
|
3138
3157
|
SupportedStyles:
|
3139
3158
|
- def_self
|
3140
3159
|
- self_class
|
@@ -3492,6 +3511,18 @@ Style/ExponentialNotation:
|
|
3492
3511
|
- engineering
|
3493
3512
|
- integral
|
3494
3513
|
|
3514
|
+
Style/FileRead:
|
3515
|
+
Description: 'Favor `File.(bin)read` convenience methods.'
|
3516
|
+
StyleGuide: '#file-read'
|
3517
|
+
Enabled: pending
|
3518
|
+
VersionAdded: '1.24'
|
3519
|
+
|
3520
|
+
Style/FileWrite:
|
3521
|
+
Description: 'Favor `File.(bin)write` convenience methods.'
|
3522
|
+
StyleGuide: '#file-write'
|
3523
|
+
Enabled: pending
|
3524
|
+
VersionAdded: '1.24'
|
3525
|
+
|
3495
3526
|
Style/FloatDivision:
|
3496
3527
|
Description: 'For performing float division, coerce one side only.'
|
3497
3528
|
StyleGuide: '#float-division'
|
@@ -3650,7 +3681,7 @@ Style/HashSyntax:
|
|
3650
3681
|
StyleGuide: '#hash-literals'
|
3651
3682
|
Enabled: true
|
3652
3683
|
VersionAdded: '0.9'
|
3653
|
-
VersionChanged: '
|
3684
|
+
VersionChanged: '1.24'
|
3654
3685
|
EnforcedStyle: ruby19
|
3655
3686
|
SupportedStyles:
|
3656
3687
|
# checks for 1.9 syntax (e.g. {a: 1}) for all symbol keys
|
@@ -3661,6 +3692,15 @@ Style/HashSyntax:
|
|
3661
3692
|
- no_mixed_keys
|
3662
3693
|
# enforces both ruby19 and no_mixed_keys styles
|
3663
3694
|
- ruby19_no_mixed_keys
|
3695
|
+
# Force hashes that have a hash value omission
|
3696
|
+
EnforcedShorthandSyntax: always
|
3697
|
+
SupportedShorthandSyntax:
|
3698
|
+
# forces use of the 3.1 syntax (e.g. {foo:}) when the hash key and value are the same.
|
3699
|
+
- always
|
3700
|
+
# forces use of explicit hash literal value.
|
3701
|
+
- never
|
3702
|
+
# accepts both shorthand and explicit use of hash literal value.
|
3703
|
+
- either
|
3664
3704
|
# Force hashes that have a symbol value to use hash rockets
|
3665
3705
|
UseHashRocketsWithSymbolValues: false
|
3666
3706
|
# Do not suggest { a?: 1 } over { :a? => 1 } in ruby19 style
|
@@ -3775,8 +3815,8 @@ Style/InverseMethods:
|
|
3775
3815
|
:>: :<=
|
3776
3816
|
# `ActiveSupport` defines some common inverse methods. They are listed below,
|
3777
3817
|
# and not enabled by default.
|
3778
|
-
|
3779
|
-
|
3818
|
+
# :present?: :blank?,
|
3819
|
+
# :include?: :exclude?
|
3780
3820
|
# `InverseBlocks` are methods that are inverted by inverting the return
|
3781
3821
|
# of the block that is passed to the method
|
3782
3822
|
InverseBlocks:
|
@@ -3837,6 +3877,12 @@ Style/LineEndConcatenation:
|
|
3837
3877
|
VersionAdded: '0.18'
|
3838
3878
|
VersionChanged: '0.64'
|
3839
3879
|
|
3880
|
+
Style/MapToHash:
|
3881
|
+
Description: 'Prefer `to_h` with a block over `map.to_h`.'
|
3882
|
+
Enabled: pending
|
3883
|
+
VersionAdded: '1.24'
|
3884
|
+
Safe: false
|
3885
|
+
|
3840
3886
|
Style/MethodCallWithArgsParentheses:
|
3841
3887
|
Description: 'Use parentheses for method calls with arguments.'
|
3842
3888
|
StyleGuide: '#method-invocation-parens'
|
@@ -4205,6 +4251,8 @@ Style/NumericLiterals:
|
|
4205
4251
|
VersionChanged: '0.48'
|
4206
4252
|
MinDigits: 5
|
4207
4253
|
Strict: false
|
4254
|
+
# You can specify allowed numbers. (e.g. port number 3000, 8080, and etc)
|
4255
|
+
AllowedNumbers: []
|
4208
4256
|
|
4209
4257
|
Style/NumericPredicate:
|
4210
4258
|
Description: >-
|
@@ -124,7 +124,7 @@ module RuboCop
|
|
124
124
|
lines = /\S/.match?(rubocop_yml_contents) ? rubocop_yml_contents.split("\n", -1) : []
|
125
125
|
doc_start_index = lines.index { |line| YAML_OPTIONAL_DOC_START.match?(line) } || -1
|
126
126
|
lines.insert(doc_start_index + 1, "inherit_from:#{file_string}\n")
|
127
|
-
File.
|
127
|
+
File.write(file_name, lines.join("\n"))
|
128
128
|
end
|
129
129
|
end
|
130
130
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
class CLI
|
5
|
+
module Command
|
6
|
+
# Prints out url to documentation of provided cops
|
7
|
+
# or documentation base url by default.
|
8
|
+
# @api private
|
9
|
+
class ShowDocsUrl < Base
|
10
|
+
self.command_name = :show_docs_url
|
11
|
+
|
12
|
+
def initialize(env)
|
13
|
+
super
|
14
|
+
|
15
|
+
@config = @config_store.for(Dir.pwd)
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
print_documentation_url
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def print_documentation_url
|
25
|
+
puts Cop::Documentation.default_base_url if cops_array.empty?
|
26
|
+
|
27
|
+
cops_array.each do |cop_name|
|
28
|
+
cop = registry_hash[cop_name]
|
29
|
+
|
30
|
+
next if cop.empty?
|
31
|
+
|
32
|
+
puts Cop::Documentation.url_for(cop.first, @config)
|
33
|
+
end
|
34
|
+
|
35
|
+
puts
|
36
|
+
end
|
37
|
+
|
38
|
+
def cops_array
|
39
|
+
@cops_array ||= @options[:show_docs_url]
|
40
|
+
end
|
41
|
+
|
42
|
+
def registry_hash
|
43
|
+
@registry_hash ||= Cop::Registry.global.to_h
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -22,7 +22,7 @@ module RuboCop
|
|
22
22
|
'RuboCop extension libraries might be helpful:'
|
23
23
|
|
24
24
|
extensions.sort.each do |extension|
|
25
|
-
puts " * #{extension} (https://
|
25
|
+
puts " * #{extension} (https://rubygems.org/gems/#{extension})"
|
26
26
|
end
|
27
27
|
|
28
28
|
puts
|
data/lib/rubocop/cli.rb
CHANGED
@@ -74,7 +74,7 @@ module RuboCop
|
|
74
74
|
# Merges the given configuration with the default one. If
|
75
75
|
# AllCops:DisabledByDefault is true, it changes the Enabled params so that
|
76
76
|
# only cops from user configuration are enabled. If
|
77
|
-
# AllCops
|
77
|
+
# AllCops:EnabledByDefault is true, it changes the Enabled params so that
|
78
78
|
# only cops explicitly disabled in user configuration are disabled.
|
79
79
|
def merge_with_default(config, config_file, unset_nil:)
|
80
80
|
default_configuration = ConfigLoader.default_configuration
|
@@ -68,7 +68,7 @@ module RuboCop
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def conditional_declaration?(nodes)
|
71
|
-
parent = nodes[0].
|
71
|
+
parent = nodes[0].each_ancestor.find { |ancestor| !ancestor.begin_type? }
|
72
72
|
return false unless parent&.if_type? || parent&.when_type?
|
73
73
|
|
74
74
|
root_conditional_node = parent.if_type? ? parent : parent.parent
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This class auto-corrects `if...then` structures to a multiline `if` statement
|
6
|
+
class IfThenCorrector
|
7
|
+
DEFAULT_INDENTATION_WIDTH = 2
|
8
|
+
|
9
|
+
def initialize(if_node, indentation: nil)
|
10
|
+
@if_node = if_node
|
11
|
+
@indentation = indentation || DEFAULT_INDENTATION_WIDTH
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(corrector)
|
15
|
+
corrector.replace(if_node, replacement)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :if_node, :indentation
|
21
|
+
|
22
|
+
def replacement(node = if_node, indentation = nil)
|
23
|
+
indentation = ' ' * node.source_range.column if indentation.nil?
|
24
|
+
if_branch_source = node.if_branch&.source || 'nil'
|
25
|
+
elsif_indentation = indentation if node.respond_to?(:elsif?) && node.elsif?
|
26
|
+
|
27
|
+
if_branch = <<~RUBY
|
28
|
+
#{elsif_indentation}#{node.keyword} #{node.condition.source}
|
29
|
+
#{indentation}#{branch_body_indentation}#{if_branch_source}
|
30
|
+
RUBY
|
31
|
+
|
32
|
+
else_branch = rewrite_else_branch(node.else_branch, indentation)
|
33
|
+
if_branch + else_branch
|
34
|
+
end
|
35
|
+
|
36
|
+
def rewrite_else_branch(else_branch, indentation)
|
37
|
+
if else_branch.nil?
|
38
|
+
'end'
|
39
|
+
elsif else_branch.if_type? && else_branch.elsif?
|
40
|
+
replacement(else_branch, indentation)
|
41
|
+
else
|
42
|
+
<<~RUBY.chomp
|
43
|
+
#{indentation}else
|
44
|
+
#{indentation}#{branch_body_indentation}#{else_branch.source}
|
45
|
+
#{indentation}end
|
46
|
+
RUBY
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def branch_body_indentation
|
51
|
+
@branch_body_indentation ||= (' ' * indentation).freeze
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -12,10 +12,27 @@ module RuboCop
|
|
12
12
|
end
|
13
13
|
|
14
14
|
# @api private
|
15
|
-
def url_for(cop_class)
|
15
|
+
def url_for(cop_class, config = nil)
|
16
16
|
base = department_to_basename(cop_class.department)
|
17
17
|
fragment = cop_class.cop_name.downcase.gsub(/[^a-z]/, '')
|
18
|
-
|
18
|
+
base_url = base_url_for(cop_class, config)
|
19
|
+
|
20
|
+
"#{base_url}/#{base}.html##{fragment}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# @api private
|
24
|
+
def base_url_for(cop_class, config)
|
25
|
+
return default_base_url unless config
|
26
|
+
|
27
|
+
department_name = cop_class.department.to_s
|
28
|
+
|
29
|
+
config.for_department(department_name)['DocumentationBaseURL'] ||
|
30
|
+
config.for_all_cops['DocumentationBaseURL']
|
31
|
+
end
|
32
|
+
|
33
|
+
# @api private
|
34
|
+
def default_base_url
|
35
|
+
'https://docs.rubocop.org/rubocop'
|
19
36
|
end
|
20
37
|
end
|
21
38
|
end
|
@@ -6,18 +6,18 @@ module RuboCop
|
|
6
6
|
# Requires a gemspec to have `rubygems_mfa_required` metadata set.
|
7
7
|
#
|
8
8
|
# This setting tells RubyGems that MFA is required for accounts to
|
9
|
-
# be able perform
|
9
|
+
# be able perform privileged operations, such as (see
|
10
|
+
# RubyGems' documentation for the full list of privileged operations):
|
10
11
|
#
|
11
|
-
# * gem push
|
12
|
-
# * gem yank
|
13
|
-
# * gem owner --add/remove
|
12
|
+
# * `gem push`
|
13
|
+
# * `gem yank`
|
14
|
+
# * `gem owner --add/remove`
|
14
15
|
# * adding or removing owners using gem ownership page
|
15
16
|
#
|
16
17
|
# This helps make your gem more secure, as users can be more
|
17
18
|
# confident that gem updates were pushed by maintainers.
|
18
19
|
#
|
19
20
|
# @example
|
20
|
-
#
|
21
21
|
# # bad
|
22
22
|
# Gem::Specification.new do |spec|
|
23
23
|
# # no `rubygems_mfa_required` metadata specified
|
@@ -117,7 +117,7 @@ module RuboCop
|
|
117
117
|
|
118
118
|
correct_metadata(corrector, metadata)
|
119
119
|
else
|
120
|
-
|
120
|
+
insert_mfa_required(corrector, node, block_var)
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
@@ -129,11 +129,9 @@ module RuboCop
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
def
|
132
|
+
def insert_mfa_required(corrector, node, block_var)
|
133
133
|
corrector.insert_before(node.loc.end, <<~RUBY)
|
134
|
-
#{block_var}.metadata =
|
135
|
-
'rubygems_mfa_required' => 'true'
|
136
|
-
}
|
134
|
+
#{block_var}.metadata['rubygems_mfa_required'] = 'true'
|
137
135
|
RUBY
|
138
136
|
end
|
139
137
|
|
@@ -68,8 +68,11 @@ module RuboCop
|
|
68
68
|
|
69
69
|
# @!method defined_ruby_version(node)
|
70
70
|
def_node_matcher :defined_ruby_version, <<~PATTERN
|
71
|
-
{
|
72
|
-
|
71
|
+
{
|
72
|
+
$(str _)
|
73
|
+
$(array (str _) (str _))
|
74
|
+
(send (const (const nil? :Gem) :Requirement) :new $str+)
|
75
|
+
}
|
73
76
|
PATTERN
|
74
77
|
|
75
78
|
def on_new_investigation
|
@@ -97,7 +100,11 @@ module RuboCop
|
|
97
100
|
def extract_ruby_version(required_ruby_version)
|
98
101
|
return unless required_ruby_version
|
99
102
|
|
100
|
-
if required_ruby_version.
|
103
|
+
if required_ruby_version.is_a?(Array)
|
104
|
+
required_ruby_version = required_ruby_version.detect do |v|
|
105
|
+
/[>=]/.match?(v.str_content)
|
106
|
+
end
|
107
|
+
elsif required_ruby_version.array_type?
|
101
108
|
required_ruby_version = required_ruby_version.children.detect do |v|
|
102
109
|
/[>=]/.match?(v.str_content)
|
103
110
|
end
|
@@ -182,7 +182,8 @@ module RuboCop
|
|
182
182
|
end
|
183
183
|
|
184
184
|
def generate(template)
|
185
|
-
format(template, department: badge.department,
|
185
|
+
format(template, department: badge.department.to_s.gsub('/', '::'),
|
186
|
+
cop_name: badge.cop_name)
|
186
187
|
end
|
187
188
|
|
188
189
|
def spec_path
|
@@ -209,8 +210,8 @@ module RuboCop
|
|
209
210
|
return 'rspec' if camel_case_string == 'RSpec'
|
210
211
|
|
211
212
|
camel_case_string
|
212
|
-
.gsub(
|
213
|
-
.gsub(
|
213
|
+
.gsub(%r{([^A-Z/])([A-Z]+)}, '\1_\2')
|
214
|
+
.gsub(%r{([A-Z])([A-Z][^A-Z\d/]+)}, '\1_\2')
|
214
215
|
.downcase
|
215
216
|
end
|
216
217
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Checks for redundant `send_node` method dispatch node.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# node.send_node.method_name
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# node.method_name
|
15
|
+
#
|
16
|
+
# # bad
|
17
|
+
# node.send_node.receiver
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# node.receiver
|
21
|
+
#
|
22
|
+
class RedundantMethodDispatchNode < Base
|
23
|
+
include RangeHelp
|
24
|
+
extend AutoCorrector
|
25
|
+
|
26
|
+
MSG = 'Remove the redundant `send_node`.'
|
27
|
+
RESTRICT_ON_SEND = %i[method_name receiver].freeze
|
28
|
+
|
29
|
+
# @!method dispatch_method(node)
|
30
|
+
def_node_matcher :dispatch_method, <<~PATTERN
|
31
|
+
(send $(send _ :send_node) _)
|
32
|
+
PATTERN
|
33
|
+
|
34
|
+
def on_send(node)
|
35
|
+
return unless (dispatch_node = dispatch_method(node))
|
36
|
+
return unless (dot = dispatch_node.loc.dot)
|
37
|
+
|
38
|
+
range = range_between(dot.begin_pos, dispatch_node.loc.selector.end_pos)
|
39
|
+
|
40
|
+
add_offense(range) do |corrector|
|
41
|
+
corrector.remove(range)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -14,7 +14,9 @@ module RuboCop
|
|
14
14
|
|
15
15
|
# @!method cop_class_def(node)
|
16
16
|
def_node_search :cop_class_def, <<~PATTERN
|
17
|
-
(class _
|
17
|
+
(class _
|
18
|
+
(const {nil? (const nil? :Cop) (const (const {cbase nil?} :RuboCop) :Cop)}
|
19
|
+
{:Base :Cop}) ...)
|
18
20
|
PATTERN
|
19
21
|
|
20
22
|
# @!method cop_config_accessor?(node)
|
@@ -13,6 +13,7 @@ require_relative 'internal_affairs/redundant_described_class_as_subject'
|
|
13
13
|
require_relative 'internal_affairs/redundant_let_rubocop_config_new'
|
14
14
|
require_relative 'internal_affairs/redundant_location_argument'
|
15
15
|
require_relative 'internal_affairs/redundant_message_argument'
|
16
|
+
require_relative 'internal_affairs/redundant_method_dispatch_node'
|
16
17
|
require_relative 'internal_affairs/style_detected_api_use'
|
17
18
|
require_relative 'internal_affairs/undefined_config'
|
18
19
|
require_relative 'internal_affairs/useless_message_assertion'
|
@@ -53,23 +53,50 @@ module RuboCop
|
|
53
53
|
'following the first line of a multi-line method call.'
|
54
54
|
|
55
55
|
def on_send(node)
|
56
|
-
|
57
|
-
return if !multiple_arguments?(node, first_arg) || (node.send_type? && node.method?(:[]=))
|
56
|
+
return if !multiple_arguments?(node) || (node.send_type? && node.method?(:[]=))
|
58
57
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
else
|
63
|
-
check_alignment(node.arguments, base_column(node, first_arg))
|
64
|
-
end
|
58
|
+
items = flattened_arguments(node)
|
59
|
+
|
60
|
+
check_alignment(items, base_column(node, items.first))
|
65
61
|
end
|
62
|
+
|
66
63
|
alias on_csend on_send
|
67
64
|
|
68
65
|
private
|
69
66
|
|
70
|
-
def
|
67
|
+
def flattened_arguments(node)
|
68
|
+
if fixed_indentation?
|
69
|
+
arguments_with_last_arg_pairs(node)
|
70
|
+
else
|
71
|
+
arguments_or_first_arg_pairs(node)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def arguments_with_last_arg_pairs(node)
|
76
|
+
items = node.arguments[0..-2]
|
77
|
+
last_arg = node.arguments.last
|
78
|
+
|
79
|
+
if last_arg.hash_type? && !last_arg.braces?
|
80
|
+
items += last_arg.pairs
|
81
|
+
else
|
82
|
+
items << last_arg
|
83
|
+
end
|
84
|
+
items
|
85
|
+
end
|
86
|
+
|
87
|
+
def arguments_or_first_arg_pairs(node)
|
88
|
+
first_arg = node.first_argument
|
89
|
+
if first_arg.hash_type? && !first_arg.braces?
|
90
|
+
first_arg.pairs
|
91
|
+
else
|
92
|
+
node.arguments
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def multiple_arguments?(node)
|
71
97
|
return true if node.arguments.size >= 2
|
72
98
|
|
99
|
+
first_argument = node.first_argument
|
73
100
|
first_argument&.hash_type? && first_argument.pairs.count >= 2
|
74
101
|
end
|
75
102
|
|