rubocop 1.22.2 → 1.24.1
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 -2
- data/config/default.yml +87 -5
- 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/date_assignment.rb +2 -10
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +1 -10
- data/lib/rubocop/cop/gemspec/require_mfa.rb +144 -0
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -10
- data/lib/rubocop/cop/generator.rb +1 -1
- data/lib/rubocop/cop/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/block_alignment.rb +3 -3
- data/lib/rubocop/cop/layout/comment_indentation.rb +31 -2
- data/lib/rubocop/cop/layout/dot_position.rb +9 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +22 -1
- data/lib/rubocop/cop/layout/hash_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/layout/space_in_lambda_literal.rb +11 -5
- data/lib/rubocop/cop/lint/ambiguous_range.rb +2 -2
- 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_constants.rb +3 -2
- 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 +4 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +5 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +7 -4
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +117 -0
- 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/parameter_lists.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/gemspec_help.rb +30 -0
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +4 -3
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +56 -0
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -5
- data/lib/rubocop/cop/naming/block_forwarding.rb +107 -0
- data/lib/rubocop/cop/naming/file_name.rb +37 -4
- 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/documentation.rb +1 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +10 -0
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- 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/format_string_token.rb +2 -1
- data/lib/rubocop/cop/style/hash_conversion.rb +2 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +22 -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/map_to_hash.rb +68 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +13 -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/open_struct_use.rb +69 -0
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +12 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +11 -1
- data/lib/rubocop/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/select_by_regexp.rb +4 -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/team.rb +1 -1
- data/lib/rubocop/cop/util.rb +9 -1
- data/lib/rubocop/formatter/html_formatter.rb +5 -2
- data/lib/rubocop/formatter/json_formatter.rb +4 -1
- data/lib/rubocop/options.rb +6 -1
- data/lib/rubocop/remote_config.rb +2 -4
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop/yaml_duplication_checker.rb +1 -1
- data/lib/rubocop.rb +11 -0
- metadata +18 -5
@@ -45,7 +45,7 @@ module RuboCop
|
|
45
45
|
|
46
46
|
message = message(node)
|
47
47
|
add_offense(node, message: message) do |corrector|
|
48
|
-
corrector
|
48
|
+
autocorrect(corrector, node)
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -55,55 +55,30 @@ module RuboCop
|
|
55
55
|
format(MSG, keyword: node.keyword)
|
56
56
|
end
|
57
57
|
|
58
|
-
def
|
58
|
+
def autocorrect(corrector, node)
|
59
59
|
if always_multiline? || cannot_replace_to_ternary?(node)
|
60
|
-
|
60
|
+
IfThenCorrector.new(node, indentation: indentation_width).call(corrector)
|
61
61
|
else
|
62
|
-
|
63
|
-
return replaced_node unless node.parent
|
64
|
-
return "(#{replaced_node})" if %i[and or].include?(node.parent.type)
|
65
|
-
return "(#{replaced_node})" if node.parent.send_type? && node.parent.operator_method?
|
66
|
-
|
67
|
-
replaced_node
|
62
|
+
corrector.replace(node, ternary_correction(node))
|
68
63
|
end
|
69
64
|
end
|
70
65
|
|
71
|
-
def
|
72
|
-
|
73
|
-
end
|
66
|
+
def ternary_correction(node)
|
67
|
+
replaced_node = ternary_replacement(node)
|
74
68
|
|
75
|
-
|
76
|
-
node.
|
77
|
-
|
69
|
+
return replaced_node unless node.parent
|
70
|
+
return "(#{replaced_node})" if %i[and or].include?(node.parent.type)
|
71
|
+
return "(#{replaced_node})" if node.parent.send_type? && node.parent.operator_method?
|
78
72
|
|
79
|
-
|
80
|
-
indentation = ' ' * node.source_range.column if indentation.nil?
|
81
|
-
if_branch_source = node.if_branch&.source || 'nil'
|
82
|
-
elsif_indentation = indentation if node.respond_to?(:elsif?) && node.elsif?
|
83
|
-
if_branch = <<~RUBY
|
84
|
-
#{elsif_indentation}#{node.keyword} #{node.condition.source}
|
85
|
-
#{indentation}#{branch_body_indentation}#{if_branch_source}
|
86
|
-
RUBY
|
87
|
-
else_branch = else_branch_to_multiline(node.else_branch, indentation)
|
88
|
-
if_branch + else_branch
|
73
|
+
replaced_node
|
89
74
|
end
|
90
75
|
|
91
|
-
def
|
92
|
-
|
93
|
-
'end'
|
94
|
-
elsif else_branch.if_type? && else_branch.elsif?
|
95
|
-
multiline_replacement(else_branch, indentation)
|
96
|
-
else
|
97
|
-
<<~RUBY.chomp
|
98
|
-
#{indentation}else
|
99
|
-
#{indentation}#{branch_body_indentation}#{else_branch.source}
|
100
|
-
#{indentation}end
|
101
|
-
RUBY
|
102
|
-
end
|
76
|
+
def always_multiline?
|
77
|
+
@config.for_cop('Style/OneLineConditional')['AlwaysCorrectToMultiline']
|
103
78
|
end
|
104
79
|
|
105
|
-
def
|
106
|
-
|
80
|
+
def cannot_replace_to_ternary?(node)
|
81
|
+
node.elsif_conditional?
|
107
82
|
end
|
108
83
|
|
109
84
|
def ternary_replacement(node)
|
@@ -141,6 +116,10 @@ module RuboCop
|
|
141
116
|
|
142
117
|
node.respond_to?(:arguments?) && node.arguments? && !node.parenthesized_call?
|
143
118
|
end
|
119
|
+
|
120
|
+
def indentation_width
|
121
|
+
@config.for_cop('Layout/IndentationWidth')['Width']
|
122
|
+
end
|
144
123
|
end
|
145
124
|
end
|
146
125
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop flags uses of OpenStruct, as it is now officially discouraged
|
7
|
+
# to be used for performance, version compatibility, and potential security issues.
|
8
|
+
#
|
9
|
+
# @safety
|
10
|
+
#
|
11
|
+
# Note that this cop may flag false positives; for instance, the following legal
|
12
|
+
# use of a hand-rolled `OpenStruct` type would be considered an offense:
|
13
|
+
#
|
14
|
+
# ```
|
15
|
+
# module MyNamespace
|
16
|
+
# class OpenStruct # not the OpenStruct we're looking for
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# def new_struct
|
20
|
+
# OpenStruct.new # resolves to MyNamespace::OpenStruct
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
# ```
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
#
|
27
|
+
# # bad
|
28
|
+
# point = OpenStruct.new(x: 0, y: 1)
|
29
|
+
#
|
30
|
+
# # good
|
31
|
+
# Point = Struct.new(:x, :y)
|
32
|
+
# point = Point.new(0, 1)
|
33
|
+
#
|
34
|
+
# # also good
|
35
|
+
# point = { x: 0, y: 1 }
|
36
|
+
#
|
37
|
+
# # bad
|
38
|
+
# test_double = OpenStruct.new(a: 'b')
|
39
|
+
#
|
40
|
+
# # good (assumes test using rspec-mocks)
|
41
|
+
# test_double = double
|
42
|
+
# allow(test_double).to receive(:a).and_return('b')
|
43
|
+
#
|
44
|
+
class OpenStructUse < Base
|
45
|
+
MSG = 'Avoid using `OpenStruct`; use `Struct`, `Hash`, a class or test doubles instead.'
|
46
|
+
|
47
|
+
# @!method uses_open_struct?(node)
|
48
|
+
def_node_matcher :uses_open_struct?, <<-PATTERN
|
49
|
+
(const {nil? (cbase)} :OpenStruct)
|
50
|
+
PATTERN
|
51
|
+
|
52
|
+
def on_const(node)
|
53
|
+
return unless uses_open_struct?(node)
|
54
|
+
return if custom_class_or_module_definition?(node)
|
55
|
+
|
56
|
+
add_offense(node)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def custom_class_or_module_definition?(node)
|
62
|
+
parent = node.parent
|
63
|
+
|
64
|
+
(parent.class_type? || parent.module_type?) && node.left_siblings.empty?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -56,6 +56,7 @@ module RuboCop
|
|
56
56
|
class ParenthesesAroundCondition < Base
|
57
57
|
include SafeAssignment
|
58
58
|
include Parentheses
|
59
|
+
include RangeHelp
|
59
60
|
extend AutoCorrector
|
60
61
|
|
61
62
|
def on_if(node)
|
@@ -73,13 +74,14 @@ module RuboCop
|
|
73
74
|
|
74
75
|
# @!method control_op_condition(node)
|
75
76
|
def_node_matcher :control_op_condition, <<~PATTERN
|
76
|
-
(begin $_
|
77
|
+
(begin $_ $...)
|
77
78
|
PATTERN
|
78
79
|
|
79
80
|
def process_control_op(node)
|
80
81
|
cond = node.condition
|
81
82
|
|
82
|
-
control_op_condition(cond) do |first_child|
|
83
|
+
control_op_condition(cond) do |first_child, rest_children|
|
84
|
+
return if semicolon_separated_expressions?(first_child, rest_children)
|
83
85
|
return if modifier_op?(first_child)
|
84
86
|
return if parens_allowed?(cond)
|
85
87
|
|
@@ -90,6 +92,14 @@ module RuboCop
|
|
90
92
|
end
|
91
93
|
end
|
92
94
|
|
95
|
+
def semicolon_separated_expressions?(first_exp, rest_exps)
|
96
|
+
return false unless (second_exp = rest_exps.first)
|
97
|
+
|
98
|
+
range = range_between(first_exp.source_range.end_pos, second_exp.source_range.begin_pos)
|
99
|
+
|
100
|
+
range.source.include?(';')
|
101
|
+
end
|
102
|
+
|
93
103
|
def modifier_op?(node)
|
94
104
|
return false if node.if_type? && node.ternary?
|
95
105
|
return true if node.rescue_type?
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
46
46
|
|
47
47
|
message = style == :single_quotes ? MSG_SINGLE : MSG_DOUBLE
|
48
48
|
|
49
|
-
if wrong_quotes?(node)
|
49
|
+
if wrong_quotes?(node) || invalid_double_quotes?(node.source)
|
50
50
|
add_offense(node, message: message) do |corrector|
|
51
51
|
opposite_style_detected
|
52
52
|
autocorrect(corrector, node)
|
@@ -58,6 +58,16 @@ module RuboCop
|
|
58
58
|
|
59
59
|
private
|
60
60
|
|
61
|
+
def invalid_double_quotes?(source)
|
62
|
+
return false unless style == :double_quotes
|
63
|
+
|
64
|
+
# The string needs single quotes if:
|
65
|
+
# 1. It contains a double quote
|
66
|
+
# 2. It contains text that would become an escape sequence with double quotes
|
67
|
+
# 3. It contains text that would become an interpolation with double quotes
|
68
|
+
!/" | (?<!\\)\\[aAbcdefkMnprsStuUxzZ0-7] | \#[@{$]/x.match?(source)
|
69
|
+
end
|
70
|
+
|
61
71
|
def autocorrect(corrector, node)
|
62
72
|
str = if hash_colon_key?(node)
|
63
73
|
# strip quotes
|
@@ -82,10 +82,20 @@ module RuboCop
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def autocorrect_single_variable_interpolation(corrector, embedded_node, node)
|
85
|
-
|
86
|
-
replacement = "#{variable_loc.expression.source}.to_s"
|
85
|
+
embedded_var = embedded_node.children.first
|
87
86
|
|
88
|
-
|
87
|
+
source = if require_parentheses?(embedded_var)
|
88
|
+
receiver = range_between(
|
89
|
+
embedded_var.loc.expression.begin_pos, embedded_var.loc.selector.end_pos
|
90
|
+
)
|
91
|
+
arguments = embedded_var.arguments.map(&:source).join(', ')
|
92
|
+
|
93
|
+
"#{receiver.source}(#{arguments})"
|
94
|
+
else
|
95
|
+
embedded_var.source
|
96
|
+
end
|
97
|
+
|
98
|
+
corrector.replace(node, "#{source}.to_s")
|
89
99
|
end
|
90
100
|
|
91
101
|
def autocorrect_other(corrector, embedded_node, node)
|
@@ -97,6 +107,10 @@ module RuboCop
|
|
97
107
|
corrector.replace(embedded_loc.begin, '(')
|
98
108
|
corrector.replace(embedded_loc.end, ').to_s')
|
99
109
|
end
|
110
|
+
|
111
|
+
def require_parentheses?(node)
|
112
|
+
node.send_type? && !node.arguments.count.zero? && !node.parenthesized_call?
|
113
|
+
end
|
100
114
|
end
|
101
115
|
end
|
102
116
|
end
|
@@ -80,7 +80,11 @@ module RuboCop
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def without_character_class(loc)
|
83
|
-
loc.source[1..-2]
|
83
|
+
without_character_class = loc.source[1..-2]
|
84
|
+
|
85
|
+
# Adds `\` to prevent auto-correction that changes to an interpolated string when `[#]`.
|
86
|
+
# e.g. From `/[#]{0}/` to `/#{0}/`
|
87
|
+
loc.source == '[#]' ? "\\#{without_character_class}" : without_character_class
|
84
88
|
end
|
85
89
|
|
86
90
|
def whitespace_in_free_space_mode?(node, elem)
|
@@ -218,11 +218,7 @@ module RuboCop
|
|
218
218
|
def find_matching_receiver_invocation(method_chain, checked_variable)
|
219
219
|
return nil unless method_chain
|
220
220
|
|
221
|
-
receiver =
|
222
|
-
method_chain.send_node.receiver
|
223
|
-
else
|
224
|
-
method_chain.receiver
|
225
|
-
end
|
221
|
+
receiver = method_chain.receiver
|
226
222
|
|
227
223
|
return receiver if receiver == checked_variable
|
228
224
|
|
@@ -85,7 +85,7 @@ module RuboCop
|
|
85
85
|
return unless (regexp_method_send_node = extract_send_node(block_node))
|
86
86
|
return if match_predicate_without_receiver?(regexp_method_send_node)
|
87
87
|
|
88
|
-
regexp = find_regexp(regexp_method_send_node)
|
88
|
+
regexp = find_regexp(regexp_method_send_node, block_node)
|
89
89
|
register_offense(node, block_node, regexp)
|
90
90
|
end
|
91
91
|
|
@@ -119,10 +119,11 @@ module RuboCop
|
|
119
119
|
regexp_method_send_node
|
120
120
|
end
|
121
121
|
|
122
|
-
def find_regexp(node)
|
122
|
+
def find_regexp(node, block)
|
123
123
|
return node.child_nodes.first if node.match_with_lvasgn_type?
|
124
124
|
|
125
|
-
if node.receiver.lvar_type?
|
125
|
+
if node.receiver.lvar_type? &&
|
126
|
+
(block.numblock_type? || node.receiver.source == block.arguments.first.source)
|
126
127
|
node.first_argument
|
127
128
|
elsif node.first_argument.lvar_type?
|
128
129
|
node.receiver
|
@@ -39,7 +39,7 @@ module RuboCop
|
|
39
39
|
return unless eligible_method?(node)
|
40
40
|
return unless eligible_arguments?(node)
|
41
41
|
|
42
|
-
method_name = node.
|
42
|
+
method_name = node.method_name
|
43
43
|
return if args_match?(method_name, node.arguments)
|
44
44
|
|
45
45
|
preferred_block_arguments = build_preferred_arguments_map(node, target_args(method_name))
|
@@ -81,7 +81,7 @@ module RuboCop
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def eligible_method?(node)
|
84
|
-
node.
|
84
|
+
node.receiver && method_names.include?(node.method_name)
|
85
85
|
end
|
86
86
|
|
87
87
|
def methods
|
@@ -82,7 +82,9 @@ module RuboCop
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def autocorrect(corrector, node, if_branch)
|
85
|
-
|
85
|
+
if node.condition.or_type? || node.condition.assignment?
|
86
|
+
corrector.wrap(node.condition, '(', ')')
|
87
|
+
end
|
86
88
|
|
87
89
|
correct_from_unless_to_if(corrector, node) if node.unless?
|
88
90
|
|
data/lib/rubocop/cop/team.rb
CHANGED
data/lib/rubocop/cop/util.rb
CHANGED
@@ -30,8 +30,15 @@ module RuboCop
|
|
30
30
|
node.loc.respond_to?(:end) && node.loc.end && node.loc.end.is?(')')
|
31
31
|
end
|
32
32
|
|
33
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
33
34
|
def add_parentheses(node, corrector)
|
34
|
-
if
|
35
|
+
if node.args_type?
|
36
|
+
arguments_range = node.source_range
|
37
|
+
args_with_space = range_with_surrounding_space(range: arguments_range, side: :left)
|
38
|
+
leading_space = range_between(args_with_space.begin_pos, arguments_range.begin_pos)
|
39
|
+
corrector.replace(leading_space, '(')
|
40
|
+
corrector.insert_after(arguments_range, ')')
|
41
|
+
elsif !node.respond_to?(:arguments)
|
35
42
|
corrector.wrap(node, '(', ')')
|
36
43
|
elsif node.arguments.empty?
|
37
44
|
corrector.insert_after(node, '()')
|
@@ -43,6 +50,7 @@ module RuboCop
|
|
43
50
|
corrector.insert_after(args_end(node), ')')
|
44
51
|
end
|
45
52
|
end
|
53
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
46
54
|
|
47
55
|
def args_begin(node)
|
48
56
|
loc = node.loc
|
@@ -23,12 +23,15 @@ module RuboCop
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
Summary = Struct.new(:offense_count, :inspected_files, :target_files, keyword_init: true)
|
27
|
+
FileOffenses = Struct.new(:path, :offenses, keyword_init: true)
|
28
|
+
|
26
29
|
attr_reader :files, :summary
|
27
30
|
|
28
31
|
def initialize(output, options = {})
|
29
32
|
super
|
30
33
|
@files = []
|
31
|
-
@summary =
|
34
|
+
@summary = Summary.new(offense_count: 0)
|
32
35
|
end
|
33
36
|
|
34
37
|
def started(target_files)
|
@@ -36,7 +39,7 @@ module RuboCop
|
|
36
39
|
end
|
37
40
|
|
38
41
|
def file_finished(file, offenses)
|
39
|
-
files <<
|
42
|
+
files << FileOffenses.new(path: file, offenses: offenses)
|
40
43
|
summary.offense_count += offenses.count
|
41
44
|
end
|
42
45
|
|
@@ -59,12 +59,15 @@ module RuboCop
|
|
59
59
|
end
|
60
60
|
|
61
61
|
# TODO: Consider better solution for Offense#real_column.
|
62
|
+
# The minimum value of `start_column: real_column` is 1.
|
63
|
+
# So, the minimum value of `last_column` should be 1.
|
64
|
+
# And non-zero value of `last_column` should be used as is.
|
62
65
|
def hash_for_location(offense)
|
63
66
|
{
|
64
67
|
start_line: offense.line,
|
65
68
|
start_column: offense.real_column,
|
66
69
|
last_line: offense.last_line,
|
67
|
-
last_column: offense.last_column,
|
70
|
+
last_column: offense.last_column.zero? ? 1 : offense.last_column,
|
68
71
|
length: offense.location.length,
|
69
72
|
# `line` and `column` exist for compatibility.
|
70
73
|
# Use `start_line` and `start_column` instead.
|
data/lib/rubocop/options.rb
CHANGED
@@ -15,7 +15,7 @@ module RuboCop
|
|
15
15
|
'root of the project. RuboCop will use this path to determine which ' \
|
16
16
|
'cops are enabled (via eg. Include/Exclude), and so that certain cops ' \
|
17
17
|
'like Naming/FileName can be checked.'
|
18
|
-
EXITING_OPTIONS = %i[version verbose_version show_cops].freeze
|
18
|
+
EXITING_OPTIONS = %i[version verbose_version show_cops show_docs_url].freeze
|
19
19
|
DEFAULT_MAXIMUM_EXCLUSION_ITEMS = 15
|
20
20
|
|
21
21
|
def initialize
|
@@ -188,6 +188,9 @@ module RuboCop
|
|
188
188
|
option(opts, '--show-cops [COP1,COP2,...]') do |list|
|
189
189
|
@options[:show_cops] = list.nil? ? [] : list.split(',')
|
190
190
|
end
|
191
|
+
option(opts, '--show-docs-url [COP1,COP2,...]') do |list|
|
192
|
+
@options[:show_docs_url] = list.nil? ? [] : list.split(',')
|
193
|
+
end
|
191
194
|
end
|
192
195
|
end
|
193
196
|
|
@@ -475,6 +478,8 @@ module RuboCop
|
|
475
478
|
show_cops: ['Shows the given cops, or all cops by',
|
476
479
|
'default, and their configurations for the',
|
477
480
|
'current directory.'],
|
481
|
+
show_docs_url: ['Display url to documentation for the given',
|
482
|
+
'cops, or base url by default.'],
|
478
483
|
fail_fast: ['Inspect files in order of modification',
|
479
484
|
'time and stop after the first file',
|
480
485
|
'containing offenses.'],
|
@@ -23,9 +23,7 @@ module RuboCop
|
|
23
23
|
next if response.is_a?(Net::HTTPNotModified)
|
24
24
|
next if response.is_a?(SocketError)
|
25
25
|
|
26
|
-
File.
|
27
|
-
io.write response.body
|
28
|
-
end
|
26
|
+
File.write(cache_path, response.body)
|
29
27
|
end
|
30
28
|
|
31
29
|
cache_path
|
@@ -33,7 +31,7 @@ module RuboCop
|
|
33
31
|
|
34
32
|
def inherit_from_remote(file, path)
|
35
33
|
new_uri = @uri.dup
|
36
|
-
new_uri.path.gsub!(%r{/[^/]*$}, "/#{file}")
|
34
|
+
new_uri.path.gsub!(%r{/[^/]*$}, "/#{file.delete_prefix('./')}")
|
37
35
|
RemoteConfig.new(new_uri.to_s, File.dirname(path))
|
38
36
|
end
|
39
37
|
|
data/lib/rubocop/result_cache.rb
CHANGED
@@ -179,7 +179,7 @@ module RuboCop
|
|
179
179
|
.select { |path| File.file?(path) }
|
180
180
|
.sort!
|
181
181
|
.each do |path|
|
182
|
-
content = File.
|
182
|
+
content = File.binread(path)
|
183
183
|
digest << Zlib.crc32(content).to_s # mtime not reliable
|
184
184
|
end
|
185
185
|
digest << RuboCop::Version::STRING << RuboCop::AST::Version::STRING
|
data/lib/rubocop/version.rb
CHANGED
@@ -23,7 +23,7 @@ module RuboCop
|
|
23
23
|
when Psych::Nodes::Mapping
|
24
24
|
tree.children.each_slice(2).with_object([]) do |(key, value), keys|
|
25
25
|
exist = keys.find { |key2| key2.value == key.value }
|
26
|
-
|
26
|
+
yield(exist, key) if exist
|
27
27
|
keys << key
|
28
28
|
traverse(value, &on_duplicated)
|
29
29
|
end
|
data/lib/rubocop.rb
CHANGED
@@ -83,6 +83,7 @@ require_relative 'rubocop/cop/mixin/enforce_superclass'
|
|
83
83
|
require_relative 'rubocop/cop/mixin/first_element_line_break'
|
84
84
|
require_relative 'rubocop/cop/mixin/frozen_string_literal'
|
85
85
|
require_relative 'rubocop/cop/mixin/gem_declaration'
|
86
|
+
require_relative 'rubocop/cop/mixin/gemspec_help'
|
86
87
|
require_relative 'rubocop/cop/mixin/hash_alignment_styles'
|
87
88
|
require_relative 'rubocop/cop/mixin/hash_transform_method'
|
88
89
|
require_relative 'rubocop/cop/mixin/ignored_pattern'
|
@@ -93,6 +94,7 @@ require_relative 'rubocop/cop/mixin/line_length_help'
|
|
93
94
|
require_relative 'rubocop/cop/mixin/match_range'
|
94
95
|
require_relative 'rubocop/cop/metrics/utils/repeated_csend_discount'
|
95
96
|
require_relative 'rubocop/cop/metrics/utils/repeated_attribute_discount'
|
97
|
+
require_relative 'rubocop/cop/mixin/hash_shorthand_syntax'
|
96
98
|
require_relative 'rubocop/cop/mixin/method_complexity'
|
97
99
|
require_relative 'rubocop/cop/mixin/method_preference'
|
98
100
|
require_relative 'rubocop/cop/mixin/min_body_length'
|
@@ -138,6 +140,7 @@ require_relative 'rubocop/cop/correctors/condition_corrector'
|
|
138
140
|
require_relative 'rubocop/cop/correctors/each_to_for_corrector'
|
139
141
|
require_relative 'rubocop/cop/correctors/empty_line_corrector'
|
140
142
|
require_relative 'rubocop/cop/correctors/for_to_each_corrector'
|
143
|
+
require_relative 'rubocop/cop/correctors/if_then_corrector'
|
141
144
|
require_relative 'rubocop/cop/correctors/lambda_literal_to_method_corrector'
|
142
145
|
require_relative 'rubocop/cop/correctors/line_break_corrector'
|
143
146
|
require_relative 'rubocop/cop/correctors/multiline_literal_brace_corrector'
|
@@ -160,6 +163,7 @@ require_relative 'rubocop/cop/bundler/ordered_gems'
|
|
160
163
|
require_relative 'rubocop/cop/gemspec/date_assignment'
|
161
164
|
require_relative 'rubocop/cop/gemspec/duplicated_assignment'
|
162
165
|
require_relative 'rubocop/cop/gemspec/ordered_dependencies'
|
166
|
+
require_relative 'rubocop/cop/gemspec/require_mfa'
|
163
167
|
require_relative 'rubocop/cop/gemspec/required_ruby_version'
|
164
168
|
require_relative 'rubocop/cop/gemspec/ruby_version_globals_usage'
|
165
169
|
|
@@ -382,6 +386,7 @@ require_relative 'rubocop/cop/lint/useless_access_modifier'
|
|
382
386
|
require_relative 'rubocop/cop/lint/useless_assignment'
|
383
387
|
require_relative 'rubocop/cop/lint/useless_else_without_rescue'
|
384
388
|
require_relative 'rubocop/cop/lint/useless_method_definition'
|
389
|
+
require_relative 'rubocop/cop/lint/useless_ruby2_keywords'
|
385
390
|
require_relative 'rubocop/cop/lint/useless_setter_call'
|
386
391
|
require_relative 'rubocop/cop/lint/useless_times'
|
387
392
|
require_relative 'rubocop/cop/lint/void'
|
@@ -402,6 +407,7 @@ require_relative 'rubocop/cop/metrics/perceived_complexity'
|
|
402
407
|
|
403
408
|
require_relative 'rubocop/cop/naming/accessor_method_name'
|
404
409
|
require_relative 'rubocop/cop/naming/ascii_identifiers'
|
410
|
+
require_relative 'rubocop/cop/naming/block_forwarding'
|
405
411
|
require_relative 'rubocop/cop/naming/block_parameter_name'
|
406
412
|
require_relative 'rubocop/cop/naming/class_and_module_camel_case'
|
407
413
|
require_relative 'rubocop/cop/naming/constant_name'
|
@@ -478,6 +484,8 @@ require_relative 'rubocop/cop/style/even_odd'
|
|
478
484
|
require_relative 'rubocop/cop/style/expand_path_arguments'
|
479
485
|
require_relative 'rubocop/cop/style/explicit_block_argument'
|
480
486
|
require_relative 'rubocop/cop/style/exponential_notation'
|
487
|
+
require_relative 'rubocop/cop/style/file_read'
|
488
|
+
require_relative 'rubocop/cop/style/file_write'
|
481
489
|
require_relative 'rubocop/cop/style/float_division'
|
482
490
|
require_relative 'rubocop/cop/style/for'
|
483
491
|
require_relative 'rubocop/cop/style/format_string'
|
@@ -510,10 +518,12 @@ require_relative 'rubocop/cop/style/keyword_parameters_order'
|
|
510
518
|
require_relative 'rubocop/cop/style/lambda'
|
511
519
|
require_relative 'rubocop/cop/style/lambda_call'
|
512
520
|
require_relative 'rubocop/cop/style/line_end_concatenation'
|
521
|
+
require_relative 'rubocop/cop/style/map_to_hash'
|
513
522
|
require_relative 'rubocop/cop/style/method_call_without_args_parentheses'
|
514
523
|
require_relative 'rubocop/cop/style/method_call_with_args_parentheses'
|
515
524
|
require_relative 'rubocop/cop/style/multiline_in_pattern_then'
|
516
525
|
require_relative 'rubocop/cop/style/numbered_parameters'
|
526
|
+
require_relative 'rubocop/cop/style/open_struct_use'
|
517
527
|
require_relative 'rubocop/cop/style/redundant_assignment'
|
518
528
|
require_relative 'rubocop/cop/style/redundant_fetch_block'
|
519
529
|
require_relative 'rubocop/cop/style/redundant_file_extension_in_require'
|
@@ -701,6 +711,7 @@ require_relative 'rubocop/cli/command/auto_genenerate_config'
|
|
701
711
|
require_relative 'rubocop/cli/command/execute_runner'
|
702
712
|
require_relative 'rubocop/cli/command/init_dotfile'
|
703
713
|
require_relative 'rubocop/cli/command/show_cops'
|
714
|
+
require_relative 'rubocop/cli/command/show_docs_url'
|
704
715
|
require_relative 'rubocop/cli/command/suggest_extensions'
|
705
716
|
require_relative 'rubocop/cli/command/version'
|
706
717
|
require_relative 'rubocop/config_regeneration'
|