rubocop 1.25.1 → 1.26.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 +1 -1
- data/config/default.yml +14 -4
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/cop/badge.rb +7 -1
- data/lib/rubocop/cop/gemspec/require_mfa.rb +4 -3
- data/lib/rubocop/cop/generator.rb +2 -7
- data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +46 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +7 -8
- data/lib/rubocop/cop/lint/inherit_exception.rb +19 -28
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -2
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +5 -0
- data/lib/rubocop/cop/lint/useless_times.rb +13 -9
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +1 -1
- data/lib/rubocop/cop/security/yaml_load.rb +9 -3
- data/lib/rubocop/cop/style/def_with_parentheses.rb +16 -11
- data/lib/rubocop/cop/style/for.rb +4 -0
- data/lib/rubocop/cop/style/lambda_call.rb +12 -20
- data/lib/rubocop/cop/style/nested_file_dirname.rb +66 -0
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +3 -2
- data/lib/rubocop/cop/style/string_concatenation.rb +7 -1
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +1 -1
- data/lib/rubocop/cop/variable_force.rb +1 -5
- data/lib/rubocop/cops_documentation_generator.rb +2 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -2
- data/lib/rubocop/options.rb +8 -2
- data/lib/rubocop/rspec/shared_contexts.rb +4 -0
- data/lib/rubocop/runner.rb +1 -1
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +1 -0
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f5e4905006f7a87c34929888b4f93424dfd0695f95542fcf04db5091e76f2b4
|
4
|
+
data.tar.gz: ca36431854888608b6f57b36eb5a1e04569b7c513585579f30e121f30b231705
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76d8ae5e1506313617a01d9c7ddd4061b0ced25ad6a47287e199489dee9fe76126907a4193a2ec6b70e5fef1f0274af3b017557d2c2f904d931f9d41805f98cb
|
7
|
+
data.tar.gz: 78b0442c8baa4ae704a19e37df8e4490801238989ab880f888d1c355a7b488bab7086f68d1a8f5f3bafd691998b25d9c9dabcafb921b87b6ba5b781a9efba624
|
data/README.md
CHANGED
@@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
53
53
|
in your `Gemfile`:
|
54
54
|
|
55
55
|
```rb
|
56
|
-
gem 'rubocop', '~> 1.
|
56
|
+
gem 'rubocop', '~> 1.26', 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
@@ -262,7 +262,7 @@ Gemspec/OrderedDependencies:
|
|
262
262
|
- '**/*.gemspec'
|
263
263
|
|
264
264
|
Gemspec/RequireMFA:
|
265
|
-
Description: 'Checks that the gemspec has metadata to require
|
265
|
+
Description: 'Checks that the gemspec has metadata to require Multi-Factor Authentication from RubyGems.'
|
266
266
|
Enabled: pending
|
267
267
|
VersionAdded: '1.23'
|
268
268
|
Reference:
|
@@ -1816,12 +1816,14 @@ Lint/IneffectiveAccessModifier:
|
|
1816
1816
|
Lint/InheritException:
|
1817
1817
|
Description: 'Avoid inheriting from the `Exception` class.'
|
1818
1818
|
Enabled: true
|
1819
|
+
SafeAutoCorrect: false
|
1819
1820
|
VersionAdded: '0.41'
|
1821
|
+
VersionChanged: '1.26'
|
1820
1822
|
# The default base class in favour of `Exception`.
|
1821
|
-
EnforcedStyle:
|
1823
|
+
EnforcedStyle: standard_error
|
1822
1824
|
SupportedStyles:
|
1823
|
-
- runtime_error
|
1824
1825
|
- standard_error
|
1826
|
+
- runtime_error
|
1825
1827
|
|
1826
1828
|
Lint/InterpolationCheck:
|
1827
1829
|
Description: 'Raise warning for interpolation in single q strs.'
|
@@ -2011,6 +2013,8 @@ Lint/RedundantDirGlobSort:
|
|
2011
2013
|
Description: 'Checks for redundant `sort` method to `Dir.glob` and `Dir[]`.'
|
2012
2014
|
Enabled: pending
|
2013
2015
|
VersionAdded: '1.8'
|
2016
|
+
VersionChanged: '1.26'
|
2017
|
+
SafeAutoCorrect: false
|
2014
2018
|
|
2015
2019
|
Lint/RedundantRequireStatement:
|
2016
2020
|
Description: 'Checks for unnecessary `require` statement.'
|
@@ -3542,8 +3546,9 @@ Style/For:
|
|
3542
3546
|
Description: 'Checks use of for or each in multiline loops.'
|
3543
3547
|
StyleGuide: '#no-for-loops'
|
3544
3548
|
Enabled: true
|
3549
|
+
SafeAutoCorrect: false
|
3545
3550
|
VersionAdded: '0.13'
|
3546
|
-
VersionChanged: '
|
3551
|
+
VersionChanged: '1.26'
|
3547
3552
|
EnforcedStyle: each
|
3548
3553
|
SupportedStyles:
|
3549
3554
|
- each
|
@@ -4122,6 +4127,11 @@ Style/NegatedWhile:
|
|
4122
4127
|
Enabled: true
|
4123
4128
|
VersionAdded: '0.20'
|
4124
4129
|
|
4130
|
+
Style/NestedFileDirname:
|
4131
|
+
Description: 'Checks for nested `File.dirname`.'
|
4132
|
+
Enabled: pending
|
4133
|
+
VersionAdded: '1.26'
|
4134
|
+
|
4125
4135
|
Style/NestedModifier:
|
4126
4136
|
Description: 'Avoid using nested modifiers.'
|
4127
4137
|
StyleGuide: '#no-nested-modifiers'
|
data/lib/rubocop/cli.rb
CHANGED
data/lib/rubocop/cop/badge.rb
CHANGED
@@ -19,7 +19,13 @@ module RuboCop
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.parse(identifier)
|
22
|
-
new(identifier.split('/'))
|
22
|
+
new(identifier.split('/').map { |i| camel_case(i) })
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.camel_case(name_part)
|
26
|
+
return 'RSpec' if name_part == 'rspec'
|
27
|
+
|
28
|
+
name_part.gsub(/^\w|_\w/) { |match| match[-1, 1].upcase }
|
23
29
|
end
|
24
30
|
|
25
31
|
def initialize(class_name_parts)
|
@@ -5,9 +5,10 @@ module RuboCop
|
|
5
5
|
module Gemspec
|
6
6
|
# Requires a gemspec to have `rubygems_mfa_required` metadata set.
|
7
7
|
#
|
8
|
-
# This setting tells RubyGems that MFA
|
9
|
-
# be able perform privileged operations, such as
|
10
|
-
# RubyGems' documentation for the full list of privileged
|
8
|
+
# This setting tells RubyGems that MFA (Multi-Factor Authentication) is
|
9
|
+
# required for accounts to be able perform privileged operations, such as
|
10
|
+
# (see RubyGems' documentation for the full list of privileged
|
11
|
+
# operations):
|
11
12
|
#
|
12
13
|
# * `gem push`
|
13
14
|
# * `gem yank`
|
@@ -8,13 +8,7 @@ module RuboCop
|
|
8
8
|
# and spec file when given a valid qualified cop name.
|
9
9
|
# @api private
|
10
10
|
class Generator
|
11
|
-
|
12
|
-
# https://github.com/rubocop/rubocop/issues/7043
|
13
|
-
#
|
14
|
-
# The following `String#gsub` can be replaced with
|
15
|
-
# squiggly heredoc when RuboCop supports Ruby 2.5 or higher
|
16
|
-
# (RDoc 6.0 or higher).
|
17
|
-
SOURCE_TEMPLATE = <<-RUBY.gsub(/^ {8}/, '')
|
11
|
+
SOURCE_TEMPLATE = <<~RUBY
|
18
12
|
# frozen_string_literal: true
|
19
13
|
|
20
14
|
module RuboCop
|
@@ -68,6 +62,7 @@ module RuboCop
|
|
68
62
|
# For example
|
69
63
|
MSG = 'Use `#good_method` instead of `#bad_method`.'
|
70
64
|
|
65
|
+
# @!method bad_method?(node)
|
71
66
|
def_node_matcher :bad_method?, <<~PATTERN
|
72
67
|
(send nil? :bad_method ...)
|
73
68
|
PATTERN
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Checks for redundant `:config` parameter in the `context` arguments.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# context 'foo', :config do
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# context 'foo' do
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
class RedundantContextConfigParameter < Base
|
19
|
+
include RangeHelp
|
20
|
+
extend AutoCorrector
|
21
|
+
|
22
|
+
MSG = 'Remove the redundant `:config` parameter.'
|
23
|
+
RESTRICT_ON_SEND = %i[context].freeze
|
24
|
+
|
25
|
+
def on_send(node)
|
26
|
+
arguments = node.arguments
|
27
|
+
config_node = arguments.detect { |argument| argument.source == ':config' }
|
28
|
+
return unless config_node
|
29
|
+
|
30
|
+
add_offense(config_node) do |corrector|
|
31
|
+
dup_arguments = arguments.dup
|
32
|
+
dup_arguments.delete(config_node)
|
33
|
+
|
34
|
+
corrector.replace(offense_range(arguments), dup_arguments.map(&:source).join(', '))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def offense_range(arguments)
|
41
|
+
range_between(arguments.first.source_range.begin_pos, arguments.last.source_range.end_pos)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -9,6 +9,7 @@ require_relative 'internal_affairs/node_destructuring'
|
|
9
9
|
require_relative 'internal_affairs/node_matcher_directive'
|
10
10
|
require_relative 'internal_affairs/node_type_predicate'
|
11
11
|
require_relative 'internal_affairs/offense_location_keyword'
|
12
|
+
require_relative 'internal_affairs/redundant_context_config_parameter'
|
12
13
|
require_relative 'internal_affairs/redundant_described_class_as_subject'
|
13
14
|
require_relative 'internal_affairs/redundant_let_rubocop_config_new'
|
14
15
|
require_relative 'internal_affairs/redundant_location_argument'
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Layout
|
6
|
-
# This cop checks how the `when` and
|
6
|
+
# This cop checks how the `when` and ``in``s of a `case` expression
|
7
7
|
# are indented in relation to its `case` or `end` keyword.
|
8
8
|
#
|
9
9
|
# It will register a separate offense for each misaligned `when` and `in`.
|
@@ -3,27 +3,26 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Layout
|
6
|
-
# This cop checks the indentation of the right hand side operand in
|
7
|
-
#
|
6
|
+
# This cop checks the indentation of the right hand side operand in binary operations that
|
7
|
+
# span more than one line.
|
8
8
|
#
|
9
|
-
# The `aligned` style checks that operators are aligned if they are part
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# style.
|
9
|
+
# The `aligned` style checks that operators are aligned if they are part of an `if` or `while`
|
10
|
+
# condition, an explicit `return` statement, etc. In other contexts, the second operand should
|
11
|
+
# be indented regardless of enforced style.
|
13
12
|
#
|
14
13
|
# @example EnforcedStyle: aligned (default)
|
15
14
|
# # bad
|
16
15
|
# if a +
|
17
16
|
# b
|
18
17
|
# something &&
|
19
|
-
#
|
18
|
+
# something_else
|
20
19
|
# end
|
21
20
|
#
|
22
21
|
# # good
|
23
22
|
# if a +
|
24
23
|
# b
|
25
24
|
# something &&
|
26
|
-
#
|
25
|
+
# something_else
|
27
26
|
# end
|
28
27
|
#
|
29
28
|
# @example EnforcedStyle: indented
|
@@ -3,12 +3,16 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# This cop looks for error classes inheriting from `Exception
|
7
|
-
#
|
8
|
-
# `
|
9
|
-
# `RuntimeError` (default) or `StandardError` instead.
|
6
|
+
# This cop looks for error classes inheriting from `Exception`.
|
7
|
+
# It is configurable to suggest using either `StandardError` (default) or
|
8
|
+
# `RuntimeError` instead.
|
10
9
|
#
|
11
|
-
# @
|
10
|
+
# @safety
|
11
|
+
# This cop's autocorrection is unsafe because `rescue` that omit
|
12
|
+
# exception class handle `StandardError` and its subclasses,
|
13
|
+
# but not `Exception` and its subclasses.
|
14
|
+
#
|
15
|
+
# @example EnforcedStyle: standard_error (default)
|
12
16
|
# # bad
|
13
17
|
#
|
14
18
|
# class C < Exception; end
|
@@ -17,11 +21,11 @@ module RuboCop
|
|
17
21
|
#
|
18
22
|
# # good
|
19
23
|
#
|
20
|
-
# class C <
|
24
|
+
# class C < StandardError; end
|
21
25
|
#
|
22
|
-
# C = Class.new(
|
26
|
+
# C = Class.new(StandardError)
|
23
27
|
#
|
24
|
-
# @example EnforcedStyle:
|
28
|
+
# @example EnforcedStyle: runtime_error
|
25
29
|
# # bad
|
26
30
|
#
|
27
31
|
# class C < Exception; end
|
@@ -30,31 +34,18 @@ module RuboCop
|
|
30
34
|
#
|
31
35
|
# # good
|
32
36
|
#
|
33
|
-
# class C <
|
37
|
+
# class C < RuntimeError; end
|
34
38
|
#
|
35
|
-
# C = Class.new(
|
39
|
+
# C = Class.new(RuntimeError)
|
36
40
|
class InheritException < Base
|
37
41
|
include ConfigurableEnforcedStyle
|
38
42
|
extend AutoCorrector
|
39
43
|
|
40
|
-
MSG = 'Inherit from `%<prefer>s` instead of
|
44
|
+
MSG = 'Inherit from `%<prefer>s` instead of `Exception`.'
|
41
45
|
PREFERRED_BASE_CLASS = {
|
42
46
|
runtime_error: 'RuntimeError',
|
43
47
|
standard_error: 'StandardError'
|
44
48
|
}.freeze
|
45
|
-
ILLEGAL_CLASSES = %w[
|
46
|
-
Exception
|
47
|
-
SystemStackError
|
48
|
-
NoMemoryError
|
49
|
-
SecurityError
|
50
|
-
NotImplementedError
|
51
|
-
LoadError
|
52
|
-
SyntaxError
|
53
|
-
ScriptError
|
54
|
-
Interrupt
|
55
|
-
SignalException
|
56
|
-
SystemExit
|
57
|
-
].freeze
|
58
49
|
|
59
50
|
RESTRICT_ON_SEND = %i[new].freeze
|
60
51
|
|
@@ -66,7 +57,7 @@ module RuboCop
|
|
66
57
|
PATTERN
|
67
58
|
|
68
59
|
def on_class(node)
|
69
|
-
return unless node.parent_class &&
|
60
|
+
return unless node.parent_class && exception_class?(node.parent_class)
|
70
61
|
|
71
62
|
message = message(node.parent_class)
|
72
63
|
|
@@ -77,7 +68,7 @@ module RuboCop
|
|
77
68
|
|
78
69
|
def on_send(node)
|
79
70
|
constant = class_new_call?(node)
|
80
|
-
return unless constant &&
|
71
|
+
return unless constant && exception_class?(constant)
|
81
72
|
|
82
73
|
message = message(constant)
|
83
74
|
|
@@ -92,8 +83,8 @@ module RuboCop
|
|
92
83
|
format(MSG, prefer: preferred_base_class, current: node.const_name)
|
93
84
|
end
|
94
85
|
|
95
|
-
def
|
96
|
-
|
86
|
+
def exception_class?(class_node)
|
87
|
+
class_node.const_name == 'Exception'
|
97
88
|
end
|
98
89
|
|
99
90
|
def preferred_base_class
|
@@ -19,7 +19,7 @@ module RuboCop
|
|
19
19
|
include RangeHelp
|
20
20
|
extend AutoCorrector
|
21
21
|
|
22
|
-
MSG = '`
|
22
|
+
MSG = '`%<argument>s` interpreted as grouped expression.'
|
23
23
|
|
24
24
|
def on_send(node)
|
25
25
|
return if valid_context?(node)
|
@@ -28,8 +28,9 @@ module RuboCop
|
|
28
28
|
return unless space_length.positive?
|
29
29
|
|
30
30
|
range = space_range(node.first_argument.source_range, space_length)
|
31
|
+
message = format(MSG, argument: node.first_argument.source)
|
31
32
|
|
32
|
-
add_offense(range) { |corrector| corrector.remove(range) }
|
33
|
+
add_offense(range, message: message) { |corrector| corrector.remove(range) }
|
33
34
|
end
|
34
35
|
alias on_csend on_send
|
35
36
|
|
@@ -6,6 +6,11 @@ module RuboCop
|
|
6
6
|
# Sort globbed results by default in Ruby 3.0.
|
7
7
|
# This cop checks for redundant `sort` method to `Dir.glob` and `Dir[]`.
|
8
8
|
#
|
9
|
+
# @safety
|
10
|
+
# This cop is unsafe, in case of having a file and a directory with
|
11
|
+
# identical names, since directory will be loaded before the file, which
|
12
|
+
# will break `exe/files.rb` that rely on `exe.rb` file.
|
13
|
+
#
|
9
14
|
# @example
|
10
15
|
#
|
11
16
|
# # bad
|
@@ -51,20 +51,24 @@ module RuboCop
|
|
51
51
|
node = node.block_node if node.block_literal?
|
52
52
|
|
53
53
|
add_offense(node, message: format(MSG, count: count)) do |corrector|
|
54
|
-
next
|
55
|
-
|
56
|
-
|
57
|
-
remove_node(corrector, node)
|
58
|
-
elsif !proc_name.empty?
|
59
|
-
autocorrect_block_pass(corrector, node, proc_name)
|
60
|
-
else
|
61
|
-
autocorrect_block(corrector, node)
|
62
|
-
end
|
54
|
+
next if !own_line?(node) || node.parent&.send_type?
|
55
|
+
|
56
|
+
autocorrect(corrector, count, node, proc_name)
|
63
57
|
end
|
64
58
|
end
|
65
59
|
|
66
60
|
private
|
67
61
|
|
62
|
+
def autocorrect(corrector, count, node, proc_name)
|
63
|
+
if never_process?(count, node)
|
64
|
+
remove_node(corrector, node)
|
65
|
+
elsif !proc_name.empty?
|
66
|
+
autocorrect_block_pass(corrector, node, proc_name)
|
67
|
+
else
|
68
|
+
autocorrect_block(corrector, node)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
68
72
|
def never_process?(count, node)
|
69
73
|
count < 1 || (node.block_type? && node.body.nil?)
|
70
74
|
end
|
@@ -41,7 +41,7 @@ module RuboCop
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def require_hash_value?(hash_key_source, node)
|
44
|
-
return true if require_hash_value_for_around_hash_literal?(node)
|
44
|
+
return true if !node.key.sym_type? || require_hash_value_for_around_hash_literal?(node)
|
45
45
|
|
46
46
|
hash_value = node.value
|
47
47
|
return true unless hash_value.send_type? || hash_value.lvar_type?
|
@@ -7,17 +7,21 @@ module RuboCop
|
|
7
7
|
# potential security issues leading to remote code execution when
|
8
8
|
# loading from an untrusted source.
|
9
9
|
#
|
10
|
+
# NOTE: Ruby 3.1+ (Psych 4) uses `Psych.load` as `Psych.safe_load` by default.
|
11
|
+
#
|
10
12
|
# @safety
|
11
13
|
# The behaviour of the code might change depending on what was
|
12
14
|
# in the YAML payload, since `YAML.safe_load` is more restrictive.
|
13
15
|
#
|
14
16
|
# @example
|
15
17
|
# # bad
|
16
|
-
# YAML.load("---
|
18
|
+
# YAML.load("--- !ruby/object:Foo {}") # Psych 3 is unsafe by default
|
17
19
|
#
|
18
20
|
# # good
|
19
|
-
# YAML.safe_load("---
|
20
|
-
# YAML.
|
21
|
+
# YAML.safe_load("--- !ruby/object:Foo {}", [Foo]) # Ruby 2.5 (Psych 3)
|
22
|
+
# YAML.safe_load("--- !ruby/object:Foo {}", permitted_classes: [Foo]) # Ruby 3.0- (Psych 3)
|
23
|
+
# YAML.load("--- !ruby/object:Foo {}", permitted_classes: [Foo]) # Ruby 3.1+ (Psych 4)
|
24
|
+
# YAML.dump(foo)
|
21
25
|
#
|
22
26
|
class YAMLLoad < Base
|
23
27
|
extend AutoCorrector
|
@@ -31,6 +35,8 @@ module RuboCop
|
|
31
35
|
PATTERN
|
32
36
|
|
33
37
|
def on_send(node)
|
38
|
+
return if target_ruby_version >= 3.1
|
39
|
+
|
34
40
|
yaml_load(node) do
|
35
41
|
add_offense(node.loc.selector) do |corrector|
|
36
42
|
corrector.replace(node.loc.selector, 'safe_load')
|
@@ -11,27 +11,33 @@ module RuboCop
|
|
11
11
|
#
|
12
12
|
# # bad
|
13
13
|
# def foo()
|
14
|
-
#
|
14
|
+
# do_something
|
15
15
|
# end
|
16
16
|
#
|
17
17
|
# # good
|
18
18
|
# def foo
|
19
|
-
#
|
19
|
+
# do_something
|
20
20
|
# end
|
21
21
|
#
|
22
|
-
# #
|
23
|
-
# def foo()
|
22
|
+
# # bad
|
23
|
+
# def foo() = do_something
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# def foo = do_something
|
27
|
+
#
|
28
|
+
# # good (without parentheses it's a syntax error)
|
29
|
+
# def foo() do_something end
|
24
30
|
#
|
25
31
|
# @example
|
26
32
|
#
|
27
33
|
# # bad
|
28
34
|
# def Baz.foo()
|
29
|
-
#
|
35
|
+
# do_something
|
30
36
|
# end
|
31
37
|
#
|
32
38
|
# # good
|
33
39
|
# def Baz.foo
|
34
|
-
#
|
40
|
+
# do_something
|
35
41
|
# end
|
36
42
|
class DefWithParentheses < Base
|
37
43
|
extend AutoCorrector
|
@@ -39,12 +45,11 @@ module RuboCop
|
|
39
45
|
MSG = "Omit the parentheses in defs when the method doesn't accept any arguments."
|
40
46
|
|
41
47
|
def on_def(node)
|
42
|
-
return if node.single_line?
|
43
|
-
return unless !node.arguments? && (
|
48
|
+
return if node.single_line? && !node.endless?
|
49
|
+
return unless !node.arguments? && (node_arguments = node.arguments.source_range)
|
44
50
|
|
45
|
-
add_offense(
|
46
|
-
corrector.remove(
|
47
|
-
corrector.remove(node.arguments.loc.end)
|
51
|
+
add_offense(node_arguments) do |corrector|
|
52
|
+
corrector.remove(node_arguments)
|
48
53
|
end
|
49
54
|
end
|
50
55
|
alias on_defs on_def
|
@@ -22,45 +22,37 @@ module RuboCop
|
|
22
22
|
include ConfigurableEnforcedStyle
|
23
23
|
extend AutoCorrector
|
24
24
|
|
25
|
+
MSG = 'Prefer the use of `%<prefer>s` over `%<current>s`.'
|
25
26
|
RESTRICT_ON_SEND = %i[call].freeze
|
26
27
|
|
27
28
|
def on_send(node)
|
28
29
|
return unless node.receiver
|
29
30
|
|
30
31
|
if offense?(node)
|
31
|
-
|
32
|
+
prefer = prefer(node)
|
33
|
+
current = node.source
|
34
|
+
|
35
|
+
add_offense(node, message: format(MSG, prefer: prefer, current: current)) do |corrector|
|
32
36
|
opposite_style_detected
|
33
|
-
|
37
|
+
corrector.replace(node, prefer)
|
34
38
|
end
|
35
39
|
else
|
36
40
|
correct_style_detected
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
40
|
-
def autocorrect(corrector, node)
|
41
|
-
if explicit_style?
|
42
|
-
receiver = node.receiver.source
|
43
|
-
replacement = node.source.sub("#{receiver}.", "#{receiver}.call")
|
44
|
-
|
45
|
-
corrector.replace(node, replacement)
|
46
|
-
else
|
47
|
-
add_parentheses(node, corrector) unless node.parenthesized?
|
48
|
-
corrector.remove(node.loc.selector)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
44
|
private
|
53
45
|
|
54
46
|
def offense?(node)
|
55
47
|
(explicit_style? && node.implicit_call?) || (implicit_style? && !node.implicit_call?)
|
56
48
|
end
|
57
49
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
50
|
+
def prefer(node)
|
51
|
+
receiver = node.receiver.source
|
52
|
+
arguments = node.arguments.map(&:source).join(', ')
|
53
|
+
method = explicit_style? ? "call(#{arguments})" : "(#{arguments})"
|
54
|
+
|
55
|
+
"#{receiver}.#{method}"
|
64
56
|
end
|
65
57
|
|
66
58
|
def implicit_style?
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for nested `File.dirname`.
|
7
|
+
# It replaces nested `File.dirname` with the level argument introduced in Ruby 3.1.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# File.dirname(File.dirname(path))
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# File.dirname(path, 2)
|
16
|
+
#
|
17
|
+
class NestedFileDirname < Base
|
18
|
+
include RangeHelp
|
19
|
+
extend AutoCorrector
|
20
|
+
extend TargetRubyVersion
|
21
|
+
|
22
|
+
MSG = 'Use `dirname(%<path>s, %<level>s)` instead.'
|
23
|
+
RESTRICT_ON_SEND = %i[dirname].freeze
|
24
|
+
|
25
|
+
minimum_target_ruby_version 3.1
|
26
|
+
|
27
|
+
# @!method file_dirname?(node)
|
28
|
+
def_node_matcher :file_dirname?, <<~PATTERN
|
29
|
+
(send
|
30
|
+
(const {cbase nil?} :File) :dirname ...)
|
31
|
+
PATTERN
|
32
|
+
|
33
|
+
def on_send(node)
|
34
|
+
return if file_dirname?(node.parent) || !file_dirname?(node.first_argument)
|
35
|
+
|
36
|
+
path, level = path_with_dir_level(node, 1)
|
37
|
+
return if level < 2
|
38
|
+
|
39
|
+
message = format(MSG, path: path, level: level)
|
40
|
+
range = offense_range(node)
|
41
|
+
|
42
|
+
add_offense(range, message: message) do |corrector|
|
43
|
+
corrector.replace(range, "dirname(#{path}, #{level})")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def path_with_dir_level(node, level)
|
50
|
+
first_argument = node.first_argument
|
51
|
+
|
52
|
+
if file_dirname?(first_argument)
|
53
|
+
level += 1
|
54
|
+
path_with_dir_level(first_argument, level)
|
55
|
+
else
|
56
|
+
[first_argument.source, level]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def offense_range(node)
|
61
|
+
range_between(node.loc.selector.begin_pos, node.source_range.end_pos)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -54,8 +54,9 @@ module RuboCop
|
|
54
54
|
private
|
55
55
|
|
56
56
|
def format_message(argument)
|
57
|
-
|
58
|
-
|
57
|
+
replacement = "#{argument.name}: #{argument.default_value.source}"
|
58
|
+
|
59
|
+
format(MSG, original: argument.source, replacement: replacement)
|
59
60
|
end
|
60
61
|
end
|
61
62
|
end
|
@@ -134,7 +134,13 @@ module RuboCop
|
|
134
134
|
end
|
135
135
|
|
136
136
|
def uncorrectable?(part)
|
137
|
-
part.multiline? || (part
|
137
|
+
part.multiline? || heredoc?(part) || part.each_descendant(:block).any?
|
138
|
+
end
|
139
|
+
|
140
|
+
def heredoc?(node)
|
141
|
+
return false unless node.str_type? || node.dstr_type?
|
142
|
+
|
143
|
+
node.heredoc?
|
138
144
|
end
|
139
145
|
|
140
146
|
def corrected_ancestor?(node)
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
# last item of all non-empty, multiline array literals.
|
11
11
|
# * `comma`: Requires a comma after last item in an array,
|
12
12
|
# but only when each item is on its own line.
|
13
|
-
# * `no_comma`: Does not
|
13
|
+
# * `no_comma`: Does not require a comma after the
|
14
14
|
# last item in an array
|
15
15
|
#
|
16
16
|
# @example EnforcedStyleForMultiline: consistent_comma
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
# last item of all non-empty, multiline hash literals.
|
11
11
|
# * `comma`: Requires a comma after the last item in a hash,
|
12
12
|
# but only when each item is on its own line.
|
13
|
-
# * `no_comma`: Does not
|
13
|
+
# * `no_comma`: Does not require a comma after the
|
14
14
|
# last item in a hash
|
15
15
|
#
|
16
16
|
# @example EnforcedStyleForMultiline: consistent_comma
|
@@ -186,11 +186,7 @@ module RuboCop
|
|
186
186
|
end
|
187
187
|
|
188
188
|
def regexp_captured_names(node)
|
189
|
-
|
190
|
-
child.children.first
|
191
|
-
end.join || ''
|
192
|
-
|
193
|
-
regexp = Regexp.new(regexp_string)
|
189
|
+
regexp = node.to_regexp
|
194
190
|
|
195
191
|
regexp.named_captures.keys
|
196
192
|
end
|
@@ -191,8 +191,8 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
191
191
|
|
192
192
|
def wrap_backtick(value)
|
193
193
|
if value.is_a?(String)
|
194
|
-
# Use `+` to prevent text like `**/*.gemspec` from being bold.
|
195
|
-
value.
|
194
|
+
# Use `+` to prevent text like `**/*.gemspec`, `spec/**/*` from being bold.
|
195
|
+
value.include?('*') ? "`+#{value}+`" : "`#{value}`"
|
196
196
|
else
|
197
197
|
"`#{value}`"
|
198
198
|
end
|
@@ -124,9 +124,9 @@ module RuboCop
|
|
124
124
|
default_cfg = default_config(cop_name)
|
125
125
|
|
126
126
|
if supports_safe_auto_correct?(cop_class, default_cfg)
|
127
|
-
output_buffer.puts '#
|
127
|
+
output_buffer.puts '# This cop supports safe auto-correction (--auto-correct).'
|
128
128
|
elsif supports_unsafe_autocorrect?(cop_class, default_cfg)
|
129
|
-
output_buffer.puts '#
|
129
|
+
output_buffer.puts '# This cop supports unsafe auto-correction (--auto-correct-all).'
|
130
130
|
end
|
131
131
|
|
132
132
|
return unless default_cfg
|
data/lib/rubocop/options.rb
CHANGED
@@ -467,8 +467,14 @@ module RuboCop
|
|
467
467
|
'This option applies to the previously',
|
468
468
|
'specified --format, or the default format',
|
469
469
|
'if no format is specified.'],
|
470
|
-
fail_level: ['Minimum severity
|
471
|
-
'
|
470
|
+
fail_level: ['Minimum severity for exit with error code.',
|
471
|
+
' [A] autocorrect',
|
472
|
+
' [I] info',
|
473
|
+
' [R] refactor',
|
474
|
+
' [C] convention',
|
475
|
+
' [W] warning',
|
476
|
+
' [E] error',
|
477
|
+
' [F] fatal'],
|
472
478
|
display_time: 'Display elapsed time in seconds.',
|
473
479
|
display_only_failed: ['Only output offense messages. Omit passing',
|
474
480
|
'cops. Only valid for --format junit.'],
|
data/lib/rubocop/runner.rb
CHANGED
@@ -8,7 +8,7 @@ module RuboCop
|
|
8
8
|
class Runner # rubocop:disable Metrics/ClassLength
|
9
9
|
# An exception indicating that the inspection loop got stuck correcting
|
10
10
|
# offenses back and forth.
|
11
|
-
class InfiniteCorrectionLoop <
|
11
|
+
class InfiniteCorrectionLoop < StandardError
|
12
12
|
attr_reader :offenses
|
13
13
|
|
14
14
|
def initialize(path, offenses_by_iteration, loop_start: -1)
|
data/lib/rubocop/target_ruby.rb
CHANGED
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
# The kind of Ruby that code inspected by RuboCop is written in.
|
5
5
|
# @api private
|
6
6
|
class TargetRuby
|
7
|
-
KNOWN_RUBIES = [2.5, 2.6, 2.7, 3.0, 3.1].freeze
|
7
|
+
KNOWN_RUBIES = [2.5, 2.6, 2.7, 3.0, 3.1, 3.2].freeze
|
8
8
|
DEFAULT_VERSION = KNOWN_RUBIES.first
|
9
9
|
|
10
10
|
OBSOLETE_RUBIES = {
|
data/lib/rubocop/version.rb
CHANGED
data/lib/rubocop.rb
CHANGED
@@ -552,6 +552,7 @@ require_relative 'rubocop/cop/style/negated_if'
|
|
552
552
|
require_relative 'rubocop/cop/style/negated_if_else_condition'
|
553
553
|
require_relative 'rubocop/cop/style/negated_unless'
|
554
554
|
require_relative 'rubocop/cop/style/negated_while'
|
555
|
+
require_relative 'rubocop/cop/style/nested_file_dirname'
|
555
556
|
require_relative 'rubocop/cop/style/nested_modifier'
|
556
557
|
require_relative 'rubocop/cop/style/nested_parenthesized_calls'
|
557
558
|
require_relative 'rubocop/cop/style/nested_ternary_operator'
|
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.26.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: 2022-
|
13
|
+
date: 2022-03-09 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: parallel
|
@@ -100,7 +100,7 @@ dependencies:
|
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 1.
|
103
|
+
version: 1.16.0
|
104
104
|
- - "<"
|
105
105
|
- !ruby/object:Gem::Version
|
106
106
|
version: '2.0'
|
@@ -110,7 +110,7 @@ dependencies:
|
|
110
110
|
requirements:
|
111
111
|
- - ">="
|
112
112
|
- !ruby/object:Gem::Version
|
113
|
-
version: 1.
|
113
|
+
version: 1.16.0
|
114
114
|
- - "<"
|
115
115
|
- !ruby/object:Gem::Version
|
116
116
|
version: '2.0'
|
@@ -269,6 +269,7 @@ files:
|
|
269
269
|
- lib/rubocop/cop/internal_affairs/node_matcher_directive.rb
|
270
270
|
- lib/rubocop/cop/internal_affairs/node_type_predicate.rb
|
271
271
|
- lib/rubocop/cop/internal_affairs/offense_location_keyword.rb
|
272
|
+
- lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb
|
272
273
|
- lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb
|
273
274
|
- lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb
|
274
275
|
- lib/rubocop/cop/internal_affairs/redundant_location_argument.rb
|
@@ -737,6 +738,7 @@ files:
|
|
737
738
|
- lib/rubocop/cop/style/negated_if_else_condition.rb
|
738
739
|
- lib/rubocop/cop/style/negated_unless.rb
|
739
740
|
- lib/rubocop/cop/style/negated_while.rb
|
741
|
+
- lib/rubocop/cop/style/nested_file_dirname.rb
|
740
742
|
- lib/rubocop/cop/style/nested_modifier.rb
|
741
743
|
- lib/rubocop/cop/style/nested_parenthesized_calls.rb
|
742
744
|
- lib/rubocop/cop/style/nested_ternary_operator.rb
|
@@ -911,7 +913,7 @@ metadata:
|
|
911
913
|
homepage_uri: https://rubocop.org/
|
912
914
|
changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
|
913
915
|
source_code_uri: https://github.com/rubocop/rubocop/
|
914
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
916
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.26/
|
915
917
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
916
918
|
rubygems_mfa_required: 'true'
|
917
919
|
post_install_message:
|