rubocop 1.28.2 → 1.29.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/README.md +3 -3
- data/config/default.yml +36 -21
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/gemspec/dependency_version.rb +156 -0
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +3 -6
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +80 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_range.rb +2 -2
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/loop.rb +1 -1
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +5 -5
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
- data/lib/rubocop/cop/lint/raise_exception.rb +1 -1
- data/lib/rubocop/cop/lint/return_in_void_context.rb +5 -17
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/mixin/duplication.rb +1 -1
- data/lib/rubocop/cop/mixin/preferred_delimiters.rb +2 -2
- data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +1 -1
- data/lib/rubocop/cop/naming/inclusive_language.rb +3 -2
- data/lib/rubocop/cop/naming/predicate_name.rb +2 -2
- data/lib/rubocop/cop/naming/variable_name.rb +9 -0
- data/lib/rubocop/cop/naming/variable_number.rb +10 -0
- data/lib/rubocop/cop/security/yaml_load.rb +1 -1
- data/lib/rubocop/cop/style/alias.rb +3 -3
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/bisected_attr_accessor/macro.rb +1 -1
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/character_literal.rb +1 -1
- data/lib/rubocop/cop/style/collection_compact.rb +3 -3
- data/lib/rubocop/cop/style/date_time.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +28 -2
- data/lib/rubocop/cop/style/empty_case_condition.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/env_home.rb +56 -0
- data/lib/rubocop/cop/style/fetch_env_var.rb +240 -11
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +2 -2
- data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -1
- data/lib/rubocop/cop/style/next.rb +1 -1
- data/lib/rubocop/cop/style/optional_arguments.rb +1 -1
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +1 -1
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +4 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +108 -11
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
- data/lib/rubocop/cop/style/string_chars.rb +1 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +7 -8
- data/lib/rubocop/cops_documentation_generator.rb +1 -1
- data/lib/rubocop/formatter/formatter_set.rb +1 -0
- data/lib/rubocop/formatter/html_formatter.rb +2 -9
- data/lib/rubocop/formatter/markdown_formatter.rb +76 -0
- data/lib/rubocop/magic_comment.rb +4 -3
- data/lib/rubocop/options.rb +4 -3
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/parallel_formatter.rb +1 -1
- data/lib/rubocop/rspec/shared_contexts.rb +1 -1
- data/lib/rubocop/runner.rb +1 -1
- data/lib/rubocop/string_interpreter.rb +4 -4
- data/lib/rubocop/target_ruby.rb +7 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +3 -1
- metadata +16 -7
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +0 -45
@@ -40,12 +40,12 @@ module RuboCop
|
|
40
40
|
context_node = non_void_context(return_node)
|
41
41
|
|
42
42
|
return unless context_node&.def_type?
|
43
|
+
return unless context_node&.void_context?
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
add_offense(return_node.loc.keyword, message: format(message, method: method_name))
|
45
|
+
add_offense(
|
46
|
+
return_node.loc.keyword,
|
47
|
+
message: format(message, method: context_node.method_name)
|
48
|
+
)
|
49
49
|
end
|
50
50
|
|
51
51
|
private
|
@@ -53,18 +53,6 @@ module RuboCop
|
|
53
53
|
def non_void_context(return_node)
|
54
54
|
return_node.each_ancestor(:block, :def, :defs).first
|
55
55
|
end
|
56
|
-
|
57
|
-
def method_name(context_node)
|
58
|
-
context_node.children.first
|
59
|
-
end
|
60
|
-
|
61
|
-
def void_context_method?(method_name)
|
62
|
-
method_name == :initialize || setter_method?(method_name)
|
63
|
-
end
|
64
|
-
|
65
|
-
def setter_method?(method_name)
|
66
|
-
method_name.to_s.end_with?('=') && !AST::Node::COMPARISON_OPERATORS.include?(method_name)
|
67
|
-
end
|
68
56
|
end
|
69
57
|
end
|
70
58
|
end
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
# @param [Array] collection an array to return consecutive duplicates for
|
30
30
|
# @return [Array] the consecutive duplicates
|
31
31
|
def consecutive_duplicates(collection)
|
32
|
-
grouped_duplicates(collection).flat_map { |items| items[1
|
32
|
+
grouped_duplicates(collection).flat_map { |items| items[1..] }
|
33
33
|
end
|
34
34
|
|
35
35
|
# Returns a hash of grouped duplicates. The key will be the first
|
@@ -33,9 +33,9 @@ module RuboCop
|
|
33
33
|
ensure_valid_preferred_delimiters
|
34
34
|
|
35
35
|
if preferred_delimiters_config.key?('default')
|
36
|
-
PERCENT_LITERAL_TYPES.
|
36
|
+
PERCENT_LITERAL_TYPES.to_h do |type|
|
37
37
|
[type, preferred_delimiters_config[type] || preferred_delimiters_config['default']]
|
38
|
-
end
|
38
|
+
end
|
39
39
|
else
|
40
40
|
preferred_delimiters_config
|
41
41
|
end
|
@@ -159,7 +159,7 @@ module RuboCop
|
|
159
159
|
def autocorrect_range(item)
|
160
160
|
expr = item.source_range
|
161
161
|
ix = expr.source.rindex("\n") || 0
|
162
|
-
ix += expr.source[ix
|
162
|
+
ix += expr.source[ix..] =~ /\S/
|
163
163
|
|
164
164
|
range_between(expr.begin_pos + ix, expr.end_pos)
|
165
165
|
end
|
@@ -70,7 +70,7 @@ module RuboCop
|
|
70
70
|
if style == :anonymous
|
71
71
|
!explicit_block_argument?(last_argument) ||
|
72
72
|
use_kwarg_in_method_definition?(node) ||
|
73
|
-
use_block_argument_as_local_variable?(node, last_argument.source[1
|
73
|
+
use_block_argument_as_local_variable?(node, last_argument.source[1..])
|
74
74
|
else
|
75
75
|
!anonymous_block_argument?(last_argument)
|
76
76
|
end
|
@@ -214,13 +214,14 @@ module RuboCop
|
|
214
214
|
end
|
215
215
|
|
216
216
|
def mask_input(str)
|
217
|
-
return str if @allowed_regex.nil?
|
218
|
-
|
219
217
|
safe_str = if str.valid_encoding?
|
220
218
|
str
|
221
219
|
else
|
222
220
|
str.encode('UTF-8', invalid: :replace, undef: :replace)
|
223
221
|
end
|
222
|
+
|
223
|
+
return safe_str if @allowed_regex.nil?
|
224
|
+
|
224
225
|
safe_str.gsub(@allowed_regex) { |match| '*' * match.size }
|
225
226
|
end
|
226
227
|
|
@@ -70,7 +70,7 @@ module RuboCop
|
|
70
70
|
!(method_name.start_with?(prefix) && # cheap check to avoid allocating Regexp
|
71
71
|
method_name.match?(/^#{prefix}[^0-9]/)) ||
|
72
72
|
method_name == expected_name(method_name, prefix) ||
|
73
|
-
method_name.end_with?('=') ||
|
73
|
+
method_name.end_with?('=') || # rubocop:todo InternalAffairs/MethodNameEndWith
|
74
74
|
allowed_method?(method_name)
|
75
75
|
end
|
76
76
|
|
@@ -80,7 +80,7 @@ module RuboCop
|
|
80
80
|
else
|
81
81
|
method_name.dup
|
82
82
|
end
|
83
|
-
new_name << '?' unless method_name.end_with?('?')
|
83
|
+
new_name << '?' unless method_name.end_with?('?') # rubocop:todo InternalAffairs/MethodNameEndWith
|
84
84
|
new_name
|
85
85
|
end
|
86
86
|
|
@@ -19,12 +19,21 @@ module RuboCop
|
|
19
19
|
#
|
20
20
|
# # good
|
21
21
|
# fooBar = 1
|
22
|
+
#
|
23
|
+
# @example AllowedPatterns: ['_v\d+\z']
|
24
|
+
# # good
|
25
|
+
# :release_v1
|
22
26
|
class VariableName < Base
|
23
27
|
include AllowedIdentifiers
|
24
28
|
include ConfigurableNaming
|
29
|
+
include AllowedPattern
|
25
30
|
|
26
31
|
MSG = 'Use %<style>s for variable names.'
|
27
32
|
|
33
|
+
def valid_name?(node, name, given_style = style)
|
34
|
+
super || matches_allowed_pattern?(name)
|
35
|
+
end
|
36
|
+
|
28
37
|
def on_lvasgn(node)
|
29
38
|
name, = *node
|
30
39
|
return unless name
|
@@ -96,12 +96,21 @@ module RuboCop
|
|
96
96
|
# # good
|
97
97
|
# expect(Open3).to receive(:capture3)
|
98
98
|
#
|
99
|
+
# @example AllowedPatterns: ['_v\d+\z']
|
100
|
+
# # good
|
101
|
+
# :some_sym_v1
|
102
|
+
#
|
99
103
|
class VariableNumber < Base
|
100
104
|
include AllowedIdentifiers
|
101
105
|
include ConfigurableNumbering
|
106
|
+
include AllowedPattern
|
102
107
|
|
103
108
|
MSG = 'Use %<style>s for %<identifier_type>s numbers.'
|
104
109
|
|
110
|
+
def valid_name?(node, name, given_style = style)
|
111
|
+
super || matches_allowed_pattern?(name)
|
112
|
+
end
|
113
|
+
|
105
114
|
def on_arg(node)
|
106
115
|
@node = node
|
107
116
|
name, = *node
|
@@ -112,6 +121,7 @@ module RuboCop
|
|
112
121
|
alias on_lvasgn on_arg
|
113
122
|
alias on_ivasgn on_arg
|
114
123
|
alias on_cvasgn on_arg
|
124
|
+
alias on_gvasgn on_arg
|
115
125
|
|
116
126
|
def on_def(node)
|
117
127
|
@node = node
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
# NOTE: Ruby 3.1+ (Psych 4) uses `Psych.load` as `Psych.safe_load` by default.
|
11
11
|
#
|
12
12
|
# @safety
|
13
|
-
# The
|
13
|
+
# The behavior of the code might change depending on what was
|
14
14
|
# in the YAML payload, since `YAML.safe_load` is more restrictive.
|
15
15
|
#
|
16
16
|
# @example
|
@@ -76,7 +76,7 @@ module RuboCop
|
|
76
76
|
|
77
77
|
def add_offense_for_args(node, &block)
|
78
78
|
existing_args = node.children.map(&:source).join(' ')
|
79
|
-
preferred_args = node.children.map { |a| a.source[1
|
79
|
+
preferred_args = node.children.map { |a| a.source[1..] }.join(' ')
|
80
80
|
arg_ranges = node.children.map(&:source_range)
|
81
81
|
msg = format(MSG_SYMBOL_ARGS, prefer: preferred_args, current: existing_args)
|
82
82
|
add_offense(arg_ranges.reduce(&:join), message: msg, &block)
|
@@ -134,8 +134,8 @@ module RuboCop
|
|
134
134
|
end
|
135
135
|
|
136
136
|
def correct_alias_with_symbol_args(corrector, node)
|
137
|
-
corrector.replace(node.new_identifier, node.new_identifier.source[1
|
138
|
-
corrector.replace(node.old_identifier, node.old_identifier.source[1
|
137
|
+
corrector.replace(node.new_identifier, node.new_identifier.source[1..])
|
138
|
+
corrector.replace(node.old_identifier, node.old_identifier.source[1..])
|
139
139
|
end
|
140
140
|
|
141
141
|
# @!method identifier(node)
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
# @safety
|
11
11
|
# Auto-correction is unsafe because there is a different operator precedence
|
12
12
|
# between logical operators (`&&` and `||`) and semantic operators (`and` and `or`),
|
13
|
-
# and that might change the
|
13
|
+
# and that might change the behavior.
|
14
14
|
#
|
15
15
|
# @example EnforcedStyle: always
|
16
16
|
# # bad
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
9
9
|
# @safety
|
10
10
|
# This cop is unsafe. `case` statements use `===` for equality,
|
11
11
|
# so if the original conditional used a different equality operator, the
|
12
|
-
#
|
12
|
+
# behavior may be different.
|
13
13
|
#
|
14
14
|
# @example
|
15
15
|
# # bad
|
@@ -70,7 +70,7 @@ module RuboCop
|
|
70
70
|
def on_send(node)
|
71
71
|
return unless (range = offense_range(node))
|
72
72
|
|
73
|
-
good = good_method_name(node
|
73
|
+
good = good_method_name(node)
|
74
74
|
message = format(MSG, good: good, bad: range.source)
|
75
75
|
|
76
76
|
add_offense(range, message: message) { |corrector| corrector.replace(range, good) }
|
@@ -94,8 +94,8 @@ module RuboCop
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
-
def good_method_name(
|
98
|
-
if
|
97
|
+
def good_method_name(node)
|
98
|
+
if node.bang_method?
|
99
99
|
'compact!'
|
100
100
|
else
|
101
101
|
'compact'
|
@@ -11,7 +11,7 @@ module RuboCop
|
|
11
11
|
#
|
12
12
|
# @safety
|
13
13
|
# Autocorrection is not safe, because `DateTime` and `Time` do not have
|
14
|
-
# exactly the same
|
14
|
+
# exactly the same behavior, although in most cases the autocorrection
|
15
15
|
# will be fine.
|
16
16
|
#
|
17
17
|
# @example
|
@@ -37,11 +37,27 @@ module RuboCop
|
|
37
37
|
# !!return_value
|
38
38
|
# end
|
39
39
|
#
|
40
|
+
# define_method :foo? do
|
41
|
+
# !!return_value
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# define_singleton_method :foo? do
|
45
|
+
# !!return_value
|
46
|
+
# end
|
47
|
+
#
|
40
48
|
# @example EnforcedStyle: forbidden
|
41
49
|
# # bad
|
42
50
|
# def foo?
|
43
51
|
# !!return_value
|
44
52
|
# end
|
53
|
+
#
|
54
|
+
# define_method :foo? do
|
55
|
+
# !!return_value
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# define_singleton_method :foo? do
|
59
|
+
# !!return_value
|
60
|
+
# end
|
45
61
|
class DoubleNegation < Base
|
46
62
|
include ConfigurableEnforcedStyle
|
47
63
|
extend AutoCorrector
|
@@ -73,22 +89,32 @@ module RuboCop
|
|
73
89
|
return false unless (def_node = find_def_node_from_ascendant(node))
|
74
90
|
|
75
91
|
conditional_node = find_conditional_node_from_ascendant(node)
|
76
|
-
last_child = find_last_child(def_node.body)
|
92
|
+
last_child = find_last_child(def_node.send_type? ? def_node : def_node.body)
|
77
93
|
|
78
94
|
if conditional_node
|
79
95
|
double_negative_condition_return_value?(node, last_child, conditional_node)
|
80
96
|
else
|
81
|
-
last_child.last_line
|
97
|
+
last_child.last_line <= node.last_line
|
82
98
|
end
|
83
99
|
end
|
84
100
|
|
85
101
|
def find_def_node_from_ascendant(node)
|
86
102
|
return unless (parent = node.parent)
|
87
103
|
return parent if parent.def_type? || parent.defs_type?
|
104
|
+
return node.parent.child_nodes.first if define_mehod?(parent)
|
88
105
|
|
89
106
|
find_def_node_from_ascendant(node.parent)
|
90
107
|
end
|
91
108
|
|
109
|
+
def define_mehod?(node)
|
110
|
+
return false unless node.block_type?
|
111
|
+
|
112
|
+
child = node.child_nodes.first
|
113
|
+
return false unless child.send_type?
|
114
|
+
|
115
|
+
child.method?(:define_method) || child.method?(:define_singleton_method)
|
116
|
+
end
|
117
|
+
|
92
118
|
def find_conditional_node_from_ascendant(node)
|
93
119
|
return unless (parent = node.parent)
|
94
120
|
return parent if parent.conditional?
|
@@ -119,7 +119,7 @@ module RuboCop
|
|
119
119
|
# because the braces are interpreted as a block. We will have
|
120
120
|
# to rewrite the arguments to wrap them in parenthesis.
|
121
121
|
args = node.parent.arguments
|
122
|
-
"(#{args[1
|
122
|
+
"(#{args[1..].map(&:source).unshift('{}').join(', ')})"
|
123
123
|
else
|
124
124
|
'{}'
|
125
125
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for consistent usage of `ENV['HOME']`. If `nil` is used as
|
7
|
+
# the second argument of `ENV.fetch`, it is treated as a bad case like `ENV[]`.
|
8
|
+
#
|
9
|
+
# @safety
|
10
|
+
# The cop is unsafe because the result when `nil` is assigned to `ENV['HOME']` changes:
|
11
|
+
#
|
12
|
+
# [source,ruby]
|
13
|
+
# ----
|
14
|
+
# ENV['HOME'] = nil
|
15
|
+
# ENV['HOME'] # => nil
|
16
|
+
# Dir.home # => '/home/foo'
|
17
|
+
# ----
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
#
|
21
|
+
# # bad
|
22
|
+
# ENV['HOME']
|
23
|
+
# ENV.fetch('HOME', nil)
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# Dir.home
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# ENV.fetch('HOME', default)
|
30
|
+
#
|
31
|
+
class EnvHome < Base
|
32
|
+
extend AutoCorrector
|
33
|
+
|
34
|
+
MSG = 'Use `Dir.home` instead.'
|
35
|
+
RESTRICT_ON_SEND = %i[[] fetch].freeze
|
36
|
+
|
37
|
+
# @!method env_home?(node)
|
38
|
+
def_node_matcher :env_home?, <<~PATTERN
|
39
|
+
(send
|
40
|
+
(const {cbase nil?} :ENV) {:[] :fetch}
|
41
|
+
(str "HOME")
|
42
|
+
...)
|
43
|
+
PATTERN
|
44
|
+
|
45
|
+
def on_send(node)
|
46
|
+
return unless env_home?(node)
|
47
|
+
return if node.arguments.count == 2 && !node.arguments[1].nil_type?
|
48
|
+
|
49
|
+
add_offense(node) do |corrector|
|
50
|
+
corrector.replace(node, 'Dir.home')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|