rubocop 1.23.0 → 1.25.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Actions Status](https://github.com/rubocop/rubocop/workflows/CI/badge.svg?branch=master)](https://github.com/rubocop/rubocop/actions?query=workflow%3ACI)
|
10
10
|
[![Test Coverage](https://api.codeclimate.com/v1/badges/d2d67f728e88ea84ac69/test_coverage)](https://codeclimate.com/github/rubocop/rubocop/test_coverage)
|
11
11
|
[![Maintainability](https://api.codeclimate.com/v1/badges/d2d67f728e88ea84ac69/maintainability)](https://codeclimate.com/github/rubocop/rubocop/maintainability)
|
12
|
-
[![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=rubocop&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=rubocop&package-manager=bundler&version-scheme=semver)
|
13
12
|
[![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](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
|
|