rubocop 1.30.1 → 1.31.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +41 -8
  4. data/config/obsoletion.yml +2 -0
  5. data/exe/rubocop +15 -7
  6. data/lib/rubocop/cli/command/auto_genenerate_config.rb +1 -1
  7. data/lib/rubocop/cli/command/suggest_extensions.rb +3 -3
  8. data/lib/rubocop/config.rb +4 -0
  9. data/lib/rubocop/config_loader.rb +1 -0
  10. data/lib/rubocop/config_validator.rb +3 -3
  11. data/lib/rubocop/cop/base.rb +4 -0
  12. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
  13. data/lib/rubocop/cop/bundler/gem_filename.rb +4 -4
  14. data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -2
  15. data/lib/rubocop/cop/corrector.rb +2 -2
  16. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +3 -3
  17. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +1 -1
  18. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +31 -16
  19. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +1 -1
  20. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  21. data/lib/rubocop/cop/gemspec/require_mfa.rb +20 -20
  22. data/lib/rubocop/cop/generator.rb +1 -1
  23. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -5
  24. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  25. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
  26. data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
  27. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +25 -4
  28. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +17 -11
  29. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +49 -10
  30. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  31. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +68 -0
  32. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +130 -0
  33. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
  34. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +2 -2
  35. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -2
  36. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  37. data/lib/rubocop/cop/layout/space_around_operators.rb +1 -1
  38. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -1
  39. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
  40. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -3
  41. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  42. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +51 -0
  43. data/lib/rubocop/cop/lint/interpolation_check.rb +1 -1
  44. data/lib/rubocop/cop/lint/literal_as_condition.rb +5 -0
  45. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +122 -0
  46. data/lib/rubocop/cop/lint/number_conversion.rb +3 -3
  47. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  48. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +5 -5
  49. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  50. data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -1
  51. data/lib/rubocop/cop/lint/regexp_as_condition.rb +2 -2
  52. data/lib/rubocop/cop/lint/struct_new_override.rb +2 -2
  53. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
  54. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +44 -0
  55. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
  56. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +41 -12
  57. data/lib/rubocop/cop/mixin/range_help.rb +7 -3
  58. data/lib/rubocop/cop/style/accessor_grouping.rb +1 -1
  59. data/lib/rubocop/cop/style/arguments_forwarding.rb +1 -1
  60. data/lib/rubocop/cop/style/block_delimiters.rb +4 -2
  61. data/lib/rubocop/cop/style/commented_keyword.rb +1 -1
  62. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -0
  63. data/lib/rubocop/cop/style/empty_method.rb +16 -1
  64. data/lib/rubocop/cop/style/encoding.rb +1 -1
  65. data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
  66. data/lib/rubocop/cop/style/format_string_token.rb +48 -17
  67. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  68. data/lib/rubocop/cop/style/guard_clause.rb +8 -6
  69. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +1 -1
  70. data/lib/rubocop/cop/style/hash_except.rb +88 -8
  71. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  72. data/lib/rubocop/cop/style/implicit_runtime_error.rb +2 -2
  73. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
  74. data/lib/rubocop/cop/style/line_end_concatenation.rb +1 -1
  75. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  76. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -2
  77. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -2
  78. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
  79. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -3
  80. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
  81. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
  82. data/lib/rubocop/cop/style/multiline_when_then.rb +1 -3
  83. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  84. data/lib/rubocop/cop/style/nested_ternary_operator.rb +19 -7
  85. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  86. data/lib/rubocop/cop/style/not.rb +1 -1
  87. data/lib/rubocop/cop/style/redundant_argument.rb +1 -1
  88. data/lib/rubocop/cop/style/redundant_return.rb +1 -1
  89. data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -1
  90. data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -2
  91. data/lib/rubocop/cop/style/struct_inheritance.rb +2 -2
  92. data/lib/rubocop/cop/style/swap_values.rb +1 -1
  93. data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
  94. data/lib/rubocop/cop/style/unpack_first.rb +1 -1
  95. data/lib/rubocop/cop/util.rb +1 -1
  96. data/lib/rubocop/formatter/formatter_set.rb +20 -19
  97. data/lib/rubocop/formatter/git_hub_actions_formatter.rb +15 -2
  98. data/lib/rubocop/formatter/html_formatter.rb +0 -1
  99. data/lib/rubocop/formatter/offense_count_formatter.rb +2 -0
  100. data/lib/rubocop/formatter/simple_text_formatter.rb +6 -7
  101. data/lib/rubocop/formatter.rb +31 -0
  102. data/lib/rubocop/options.rb +24 -1
  103. data/lib/rubocop/rake_task.rb +30 -9
  104. data/lib/rubocop/server/cache.rb +109 -0
  105. data/lib/rubocop/server/cli.rb +104 -0
  106. data/lib/rubocop/server/client_command/base.rb +44 -0
  107. data/lib/rubocop/server/client_command/exec.rb +59 -0
  108. data/lib/rubocop/server/client_command/restart.rb +25 -0
  109. data/lib/rubocop/server/client_command/start.rb +43 -0
  110. data/lib/rubocop/server/client_command/status.rb +28 -0
  111. data/lib/rubocop/server/client_command/stop.rb +31 -0
  112. data/lib/rubocop/server/client_command.rb +26 -0
  113. data/lib/rubocop/server/core.rb +79 -0
  114. data/lib/rubocop/server/errors.rb +23 -0
  115. data/lib/rubocop/server/helper.rb +34 -0
  116. data/lib/rubocop/server/server_command/base.rb +50 -0
  117. data/lib/rubocop/server/server_command/exec.rb +34 -0
  118. data/lib/rubocop/server/server_command/stop.rb +24 -0
  119. data/lib/rubocop/server/server_command.rb +21 -0
  120. data/lib/rubocop/server/socket_reader.rb +65 -0
  121. data/lib/rubocop/server.rb +53 -0
  122. data/lib/rubocop/version.rb +15 -8
  123. data/lib/rubocop.rb +7 -26
  124. metadata +42 -5
  125. data/lib/rubocop/cop/gemspec/date_assignment.rb +0 -49
@@ -19,6 +19,9 @@ module RuboCop
19
19
  # {foo: 1, bar: 2, baz: 3}.reject {|k, v| k == :bar }
20
20
  # {foo: 1, bar: 2, baz: 3}.select {|k, v| k != :bar }
21
21
  # {foo: 1, bar: 2, baz: 3}.filter {|k, v| k != :bar }
22
+ # {foo: 1, bar: 2, baz: 3}.reject {|k, v| %i[foo bar].include?(k) }
23
+ # {foo: 1, bar: 2, baz: 3}.select {|k, v| !%i[foo bar].include?(k) }
24
+ # {foo: 1, bar: 2, baz: 3}.filter {|k, v| !%i[foo bar].include?(k) }
22
25
  #
23
26
  # # good
24
27
  # {foo: 1, bar: 2, baz: 3}.except(:bar)
@@ -33,15 +36,36 @@ module RuboCop
33
36
  MSG = 'Use `%<prefer>s` instead.'
34
37
  RESTRICT_ON_SEND = %i[reject select filter].freeze
35
38
 
36
- # @!method bad_method?(node)
37
- def_node_matcher :bad_method?, <<~PATTERN
39
+ # @!method bad_method_with_poro?(node)
40
+ def_node_matcher :bad_method_with_poro?, <<~PATTERN
38
41
  (block
39
42
  (send _ _)
40
43
  (args
41
44
  (arg _)
42
45
  (arg _))
43
- (send
44
- _ {:== :!= :eql?} _))
46
+ {
47
+ (send
48
+ _ {:== :!= :eql? :include?} _)
49
+ (send
50
+ (send
51
+ _ {:== :!= :eql? :include?} _) :!)
52
+ })
53
+ PATTERN
54
+
55
+ # @!method bad_method_with_active_support?(node)
56
+ def_node_matcher :bad_method_with_active_support?, <<~PATTERN
57
+ (block
58
+ (send _ _)
59
+ (args
60
+ (arg _)
61
+ (arg _))
62
+ {
63
+ (send
64
+ _ {:== :!= :eql? :in? :include? :exclude?} _)
65
+ (send
66
+ (send
67
+ _ {:== :!= :eql? :in? :include? :exclude?} _) :!)
68
+ })
45
69
  PATTERN
46
70
 
47
71
  def on_send(node)
@@ -52,7 +76,7 @@ module RuboCop
52
76
  return if except_key.nil? || !safe_to_register_offense?(block, except_key)
53
77
 
54
78
  range = offense_range(node)
55
- preferred_method = "except(#{except_key.source})"
79
+ preferred_method = "except(#{except_key_source(except_key)})"
56
80
 
57
81
  add_offense(range, message: format(MSG, prefer: preferred_method)) do |corrector|
58
82
  corrector.replace(range, preferred_method)
@@ -61,28 +85,84 @@ module RuboCop
61
85
 
62
86
  private
63
87
 
88
+ def bad_method?(block)
89
+ if active_support_extensions_enabled?
90
+ bad_method_with_active_support?(block)
91
+ else
92
+ bad_method_with_poro?(block)
93
+ end
94
+ end
95
+
64
96
  def semantically_except_method?(send, block)
65
97
  body = block.body
66
98
 
99
+ negated = body.method?('!')
100
+ body = body.receiver if negated
101
+
67
102
  case send.method_name
68
103
  when :reject
69
- body.method?('==') || body.method?('eql?')
104
+ body.method?('==') || body.method?('eql?') || included?(negated, body)
70
105
  when :select, :filter
71
- body.method?('!=')
106
+ body.method?('!=') || not_included?(negated, body)
72
107
  else
73
108
  false
74
109
  end
75
110
  end
76
111
 
112
+ def included?(negated, body)
113
+ body.method?('include?') || body.method?('in?') || (negated && body.method?('exclude?'))
114
+ end
115
+
116
+ def not_included?(negated, body)
117
+ body.method?('exclude?') || (negated && (body.method?('include?') || body.method?('in?')))
118
+ end
119
+
77
120
  def safe_to_register_offense?(block, except_key)
121
+ extracted = extract_body_if_nagated(block.body)
122
+ if extracted.method?('in?') || extracted.method?('include?') || \
123
+ extracted.method?('exclude?')
124
+ return true
125
+ end
78
126
  return true if block.body.method?('eql?')
79
127
 
80
128
  except_key.sym_type? || except_key.str_type?
81
129
  end
82
130
 
131
+ def extract_body_if_nagated(body)
132
+ return body unless body.method?('!')
133
+
134
+ body.receiver
135
+ end
136
+
137
+ def except_key_source(key)
138
+ if key.array_type?
139
+ key = if key.percent_literal?
140
+ key.each_value.map { |v| decorate_source(v) }
141
+ else
142
+ key.each_value.map(&:source)
143
+ end
144
+ return key.join(', ')
145
+ end
146
+
147
+ key.literal? ? key.source : "*#{key.source}"
148
+ end
149
+
150
+ def decorate_source(value)
151
+ return ":\"#{value.source}\"" if value.dsym_type?
152
+ return "\"#{value.source}\"" if value.dstr_type?
153
+ return ":#{value.source}" if value.sym_type?
154
+
155
+ "'#{value.source}'"
156
+ end
157
+
83
158
  def except_key(node)
84
159
  key_argument = node.argument_list.first.source
85
- lhs, _method_name, rhs = *node.body
160
+ body = extract_body_if_nagated(node.body)
161
+ lhs, _method_name, rhs = *body
162
+
163
+ return lhs if body.method?('include?')
164
+ return lhs if body.method?('exclude?')
165
+ return rhs if body.method?('in?')
86
166
  return if [lhs, rhs].map(&:source).none?(key_argument)
87
167
 
88
168
  [lhs, rhs].find { |operand| operand.source != key_argument }
@@ -223,7 +223,7 @@ module RuboCop
223
223
  operator = pair_node.loc.operator
224
224
 
225
225
  range = key.join(operator)
226
- range_with_surrounding_space(range: range, side: :right)
226
+ range_with_surrounding_space(range, side: :right)
227
227
  end
228
228
 
229
229
  def argument_without_space?(node)
@@ -235,7 +235,7 @@ module RuboCop
235
235
 
236
236
  key_with_hash_rocket = ":#{pair_node.key.source}#{pair_node.inverse_delimiter(true)}"
237
237
  corrector.replace(pair_node.key, key_with_hash_rocket)
238
- corrector.remove(range_with_surrounding_space(range: op))
238
+ corrector.remove(range_with_surrounding_space(op))
239
239
  end
240
240
 
241
241
  def autocorrect_no_mixed_keys(corrector, pair_node)
@@ -15,8 +15,8 @@ module RuboCop
15
15
  # # good
16
16
  # raise ArgumentError, 'Error message here'
17
17
  class ImplicitRuntimeError < Base
18
- MSG = 'Use `%<method>s` with an explicit exception class and message,' \
19
- ' rather than just a message.'
18
+ MSG = 'Use `%<method>s` with an explicit exception class and message, ' \
19
+ 'rather than just a message.'
20
20
  RESTRICT_ON_SEND = %i[raise fail].freeze
21
21
 
22
22
  # @!method implicit_runtime_error_raise_or_fail(node)
@@ -65,7 +65,7 @@ module RuboCop
65
65
 
66
66
  def remove_kwargs(kwarg_nodes, corrector)
67
67
  kwarg_nodes.each do |kwarg|
68
- with_space = range_with_surrounding_space(range: kwarg.source_range)
68
+ with_space = range_with_surrounding_space(kwarg.source_range)
69
69
  corrector.remove(range_with_surrounding_comma(with_space, :left))
70
70
  end
71
71
  end
@@ -70,7 +70,7 @@ module RuboCop
70
70
 
71
71
  def autocorrect(corrector, operator_range)
72
72
  # Include any trailing whitespace so we don't create a syntax error.
73
- operator_range = range_with_surrounding_space(range: operator_range,
73
+ operator_range = range_with_surrounding_space(operator_range,
74
74
  side: :right,
75
75
  newlines: false)
76
76
  one_more_char = operator_range.resize(operator_range.size + 1)
@@ -59,7 +59,7 @@ module RuboCop
59
59
  def autocorrect(corrector, to_h, map)
60
60
  removal_range = range_between(to_h.loc.dot.begin_pos, to_h.loc.selector.end_pos)
61
61
 
62
- corrector.remove(range_with_surrounding_space(range: removal_range, side: :left))
62
+ corrector.remove(range_with_surrounding_space(removal_range, side: :left))
63
63
  corrector.replace(map.loc.selector, 'to_h')
64
64
  end
65
65
  end
@@ -25,12 +25,12 @@ module RuboCop
25
25
  return if allowed_string_interpolation_method_call?(node)
26
26
 
27
27
  add_offense(offense_range(node), message: OMIT_MSG) do |corrector|
28
- auto_correct(corrector, node)
28
+ autocorrect(corrector, node)
29
29
  end
30
30
  end
31
31
  # rubocop:enable Metrics/PerceivedComplexity
32
32
 
33
- def auto_correct(corrector, node)
33
+ def autocorrect(corrector, node)
34
34
  if parentheses_at_the_end_of_multiline_call?(node)
35
35
  corrector.replace(args_begin(node), ' \\')
36
36
  else
@@ -19,8 +19,8 @@ module RuboCop
19
19
  include Alignment
20
20
  extend AutoCorrector
21
21
 
22
- MSG = 'Favor a normal %<keyword>s-statement over a modifier' \
23
- ' clause in a multiline statement.'
22
+ MSG = 'Favor a normal %<keyword>s-statement over a modifier ' \
23
+ 'clause in a multiline statement.'
24
24
 
25
25
  def on_if(node)
26
26
  return unless node.modifier_form? && node.body.multiline?
@@ -29,7 +29,7 @@ module RuboCop
29
29
  return unless non_modifier_then?(node)
30
30
 
31
31
  add_offense(node.loc.begin, message: format(MSG, keyword: node.keyword)) do |corrector|
32
- corrector.remove(range_with_surrounding_space(range: node.loc.begin, side: :left))
32
+ corrector.remove(range_with_surrounding_space(node.loc.begin, side: :left))
33
33
  end
34
34
  end
35
35
 
@@ -41,9 +41,7 @@ module RuboCop
41
41
 
42
42
  range = node.loc.begin
43
43
  add_offense(range) do |corrector|
44
- corrector.remove(
45
- range_with_surrounding_space(range: range, side: :left, newlines: false)
46
- )
44
+ corrector.remove(range_with_surrounding_space(range, side: :left, newlines: false))
47
45
  end
48
46
  end
49
47
 
@@ -59,7 +59,7 @@ module RuboCop
59
59
  node.first_argument.source_range.begin_pos, node.last_argument.source_range.end_pos
60
60
  )
61
61
 
62
- range_with_surrounding_space(range: range, side: :left)
62
+ range_with_surrounding_space(range, side: :left)
63
63
  end
64
64
 
65
65
  def opening_line(node)
@@ -73,7 +73,7 @@ module RuboCop
73
73
  end
74
74
 
75
75
  def enforce_single_line_ternary_operator?(node)
76
- SINGLE_LINE_TYPES.include?(node.parent.type) && !use_assignment_method?(node.parent)
76
+ SINGLE_LINE_TYPES.include?(node.parent&.type) && !use_assignment_method?(node.parent)
77
77
  end
78
78
 
79
79
  def use_assignment_method?(node)
@@ -39,9 +39,7 @@ module RuboCop
39
39
 
40
40
  range = node.loc.begin
41
41
  add_offense(range) do |corrector|
42
- corrector.remove(
43
- range_with_surrounding_space(range: range, side: :left, newlines: false)
44
- )
42
+ corrector.remove(range_with_surrounding_space(range, side: :left, newlines: false))
45
43
  end
46
44
  end
47
45
 
@@ -44,7 +44,7 @@ module RuboCop
44
44
  last_arg = nested.last_argument.source_range
45
45
 
46
46
  leading_space =
47
- range_with_surrounding_space(range: first_arg.begin,
47
+ range_with_surrounding_space(first_arg.begin,
48
48
  side: :left,
49
49
  whitespace: true,
50
50
  continuations: true)
@@ -17,6 +17,8 @@ module RuboCop
17
17
  # end
18
18
  class NestedTernaryOperator < Base
19
19
  extend AutoCorrector
20
+ include RangeHelp
21
+ include IgnoredNode
20
22
 
21
23
  MSG = 'Ternary operators must not be nested. Prefer `if` or `else` constructs instead.'
22
24
 
@@ -26,14 +28,10 @@ module RuboCop
26
28
  node.each_descendant(:if).select(&:ternary?).each do |nested_ternary|
27
29
  add_offense(nested_ternary) do |corrector|
28
30
  if_node = if_node(nested_ternary)
31
+ next if part_of_ignored_node?(if_node)
29
32
 
30
- corrector.replace(if_node, <<~RUBY.chop)
31
- if #{if_node.condition.source}
32
- #{remove_parentheses(if_node.if_branch.source)}
33
- else
34
- #{if_node.else_branch.source}
35
- end
36
- RUBY
33
+ autocorrect(corrector, if_node)
34
+ ignore_node(if_node)
37
35
  end
38
36
  end
39
37
  end
@@ -47,11 +45,25 @@ module RuboCop
47
45
  if_node(node)
48
46
  end
49
47
 
48
+ def autocorrect(corrector, if_node)
49
+ replace_loc_and_whitespace(corrector, if_node.loc.question, "\n")
50
+ replace_loc_and_whitespace(corrector, if_node.loc.colon, "\nelse\n")
51
+ corrector.replace(if_node.if_branch, remove_parentheses(if_node.if_branch.source))
52
+ corrector.wrap(if_node, 'if ', "\nend")
53
+ end
54
+
50
55
  def remove_parentheses(source)
51
56
  return source unless source.start_with?('(')
52
57
 
53
58
  source.delete_prefix('(').delete_suffix(')')
54
59
  end
60
+
61
+ def replace_loc_and_whitespace(corrector, range, replacement)
62
+ corrector.replace(
63
+ range_with_surrounding_space(range: range, whitespace: true),
64
+ replacement
65
+ )
66
+ end
55
67
  end
56
68
  end
57
69
  end
@@ -57,7 +57,7 @@ module RuboCop
57
57
 
58
58
  def autocorrect(corrector, node)
59
59
  range = if node.single_line?
60
- range_with_surrounding_space(range: node.body.loc.expression)
60
+ range_with_surrounding_space(node.body.loc.expression)
61
61
  else
62
62
  range_by_whole_lines(node.body.loc.expression, include_final_newline: true)
63
63
  end
@@ -33,7 +33,7 @@ module RuboCop
33
33
  return unless node.prefix_not?
34
34
 
35
35
  add_offense(node.loc.selector) do |corrector|
36
- range = range_with_surrounding_space(range: node.loc.selector, side: :right)
36
+ range = range_with_surrounding_space(node.loc.selector, side: :right)
37
37
 
38
38
  if opposite_method?(node.receiver)
39
39
  correct_opposite_method(corrector, range, node.receiver)
@@ -86,7 +86,7 @@ module RuboCop
86
86
  if node.parenthesized?
87
87
  range_between(node.loc.begin.begin_pos, node.loc.end.end_pos)
88
88
  else
89
- range_with_surrounding_space(range: node.first_argument.source_range, newlines: false)
89
+ range_with_surrounding_space(node.first_argument.source_range, newlines: false)
90
90
  end
91
91
  end
92
92
  end
@@ -76,7 +76,7 @@ module RuboCop
76
76
  corrector.replace(first_argument, first_argument.source.delete_prefix('*'))
77
77
  end
78
78
 
79
- keyword = range_with_surrounding_space(range: return_node.loc.keyword, side: :right)
79
+ keyword = range_with_surrounding_space(return_node.loc.keyword, side: :right)
80
80
  corrector.remove(keyword)
81
81
  end
82
82
 
@@ -32,7 +32,7 @@ module RuboCop
32
32
  include RangeHelp
33
33
  extend AutoCorrector
34
34
 
35
- MSG = 'Redundant self assignment detected. '\
35
+ MSG = 'Redundant self assignment detected. ' \
36
36
  'Method `%<method_name>s` modifies its receiver in place.'
37
37
 
38
38
  METHODS_RETURNING_SELF = %i[
@@ -138,7 +138,7 @@ module RuboCop
138
138
  corrector.insert_after(outer_condition, "#{and_operator}#{replace_condition(condition)}")
139
139
 
140
140
  range = range_between(if_branch.loc.keyword.begin_pos, condition.source_range.end_pos)
141
- corrector.remove(range_with_surrounding_space(range: range, newlines: false))
141
+ corrector.remove(range_with_surrounding_space(range, newlines: false))
142
142
  corrector.remove(if_branch.loc.keyword)
143
143
  end
144
144
 
@@ -157,7 +157,7 @@ module RuboCop
157
157
  "#{'!' if node.unless?}#{replace_condition(node.condition)} && ")
158
158
 
159
159
  corrector.remove(node.condition.loc.expression)
160
- corrector.remove(range_with_surrounding_space(range: node.loc.keyword, newlines: false))
160
+ corrector.remove(range_with_surrounding_space(node.loc.keyword, newlines: false))
161
161
  corrector.replace(if_branch.loc.keyword, 'if')
162
162
  end
163
163
 
@@ -34,7 +34,7 @@ module RuboCop
34
34
  return unless struct_constructor?(node.parent_class)
35
35
 
36
36
  add_offense(node.parent_class.source_range) do |corrector|
37
- corrector.remove(range_with_surrounding_space(range: node.loc.keyword, newlines: false))
37
+ corrector.remove(range_with_surrounding_space(node.loc.keyword, newlines: false))
38
38
  corrector.replace(node.loc.operator, '=')
39
39
 
40
40
  correct_parent(node.parent_class, corrector)
@@ -51,7 +51,7 @@ module RuboCop
51
51
 
52
52
  def correct_parent(parent, corrector)
53
53
  if parent.block_type?
54
- corrector.remove(range_with_surrounding_space(range: parent.loc.end, newlines: false))
54
+ corrector.remove(range_with_surrounding_space(parent.loc.end, newlines: false))
55
55
  elsif (class_node = parent.parent).body.nil?
56
56
  corrector.remove(range_for_empty_class_body(class_node, parent))
57
57
  else
@@ -22,7 +22,7 @@ module RuboCop
22
22
  include RangeHelp
23
23
  extend AutoCorrector
24
24
 
25
- MSG = 'Replace this and assignments at lines %<x_line>d '\
25
+ MSG = 'Replace this and assignments at lines %<x_line>d ' \
26
26
  'and %<y_line>d with `%<replacement>s`.'
27
27
 
28
28
  SIMPLE_ASSIGNMENT_TYPES = %i[lvasgn ivasgn cvasgn gvasgn casgn].to_set.freeze
@@ -152,7 +152,7 @@ module RuboCop
152
152
 
153
153
  def block_range_with_space(node)
154
154
  block_range = range_between(begin_pos_for_replacement(node), node.loc.end.end_pos)
155
- range_with_surrounding_space(range: block_range, side: :left)
155
+ range_with_surrounding_space(block_range, side: :left)
156
156
  end
157
157
 
158
158
  def begin_pos_for_replacement(node)
@@ -23,7 +23,7 @@ module RuboCop
23
23
 
24
24
  minimum_target_ruby_version 2.4
25
25
 
26
- MSG = 'Use `%<receiver>s.unpack1(%<format>s)` instead of '\
26
+ MSG = 'Use `%<receiver>s.unpack1(%<format>s)` instead of ' \
27
27
  '`%<receiver>s.unpack(%<format>s)%<method>s`.'
28
28
  RESTRICT_ON_SEND = %i[first [] slice at].freeze
29
29
 
@@ -34,7 +34,7 @@ module RuboCop
34
34
  def add_parentheses(node, corrector)
35
35
  if node.args_type?
36
36
  arguments_range = node.source_range
37
- args_with_space = range_with_surrounding_space(range: arguments_range, side: :left)
37
+ args_with_space = range_with_surrounding_space(arguments_range, side: :left)
38
38
  leading_space = range_between(args_with_space.begin_pos, arguments_range.begin_pos)
39
39
  corrector.replace(leading_space, '(')
40
40
  corrector.insert_after(arguments_range, ')')
@@ -9,23 +9,23 @@ module RuboCop
9
9
  # which invoke same method of each formatters.
10
10
  class FormatterSet < Array
11
11
  BUILTIN_FORMATTERS_FOR_KEYS = {
12
- '[a]utogenconf' => AutoGenConfigFormatter,
13
- '[c]lang' => ClangStyleFormatter,
14
- '[e]macs' => EmacsStyleFormatter,
15
- '[fi]les' => FileListFormatter,
16
- '[fu]ubar' => FuubarStyleFormatter,
17
- '[g]ithub' => GitHubActionsFormatter,
18
- '[h]tml' => HTMLFormatter,
19
- '[j]son' => JSONFormatter,
20
- '[ju]nit' => JUnitFormatter,
21
- '[m]arkdown' => MarkdownFormatter,
22
- '[o]ffenses' => OffenseCountFormatter,
23
- '[pa]cman' => PacmanFormatter,
24
- '[p]rogress' => ProgressFormatter,
25
- '[q]uiet' => QuietFormatter,
26
- '[s]imple' => SimpleTextFormatter,
27
- '[t]ap' => TapFormatter,
28
- '[w]orst' => WorstOffendersFormatter
12
+ '[a]utogenconf' => 'AutoGenConfigFormatter',
13
+ '[c]lang' => 'ClangStyleFormatter',
14
+ '[e]macs' => 'EmacsStyleFormatter',
15
+ '[fi]les' => 'FileListFormatter',
16
+ '[fu]ubar' => 'FuubarStyleFormatter',
17
+ '[g]ithub' => 'GitHubActionsFormatter',
18
+ '[h]tml' => 'HTMLFormatter',
19
+ '[j]son' => 'JSONFormatter',
20
+ '[ju]nit' => 'JUnitFormatter',
21
+ '[m]arkdown' => 'MarkdownFormatter',
22
+ '[o]ffenses' => 'OffenseCountFormatter',
23
+ '[pa]cman' => 'PacmanFormatter',
24
+ '[p]rogress' => 'ProgressFormatter',
25
+ '[q]uiet' => 'QuietFormatter',
26
+ '[s]imple' => 'SimpleTextFormatter',
27
+ '[t]ap' => 'TapFormatter',
28
+ '[w]orst' => 'WorstOffendersFormatter'
29
29
  }.freeze
30
30
 
31
31
  FORMATTER_APIS = %i[started finished].freeze
@@ -55,7 +55,7 @@ module RuboCop
55
55
  def add_formatter(formatter_type, output_path = nil)
56
56
  if output_path
57
57
  dir_path = File.dirname(output_path)
58
- FileUtils.mkdir_p(dir_path) unless File.exist?(dir_path)
58
+ FileUtils.mkdir_p(dir_path)
59
59
  output = File.open(output_path, 'w')
60
60
  else
61
61
  output = $stdout
@@ -92,7 +92,8 @@ module RuboCop
92
92
 
93
93
  raise %(Cannot determine formatter for "#{specified_key}") if matching_keys.size > 1
94
94
 
95
- BUILTIN_FORMATTERS_FOR_KEYS[matching_keys.first]
95
+ formatter_name = BUILTIN_FORMATTERS_FOR_KEYS[matching_keys.first]
96
+ RuboCop::Formatter.const_get(formatter_name)
96
97
  end
97
98
 
98
99
  def custom_formatter_class(specified_class_name)
@@ -7,8 +7,21 @@ module RuboCop
7
7
  class GitHubActionsFormatter < BaseFormatter
8
8
  ESCAPE_MAP = { '%' => '%25', "\n" => '%0A', "\r" => '%0D' }.freeze
9
9
 
10
+ def started(_target_files)
11
+ @offenses_for_files = {}
12
+ end
13
+
10
14
  def file_finished(file, offenses)
11
- offenses.each { |offense| report_offense(file, offense) }
15
+ @offenses_for_files[file] = offenses unless offenses.empty?
16
+ end
17
+
18
+ def finished(_inspected_files)
19
+ @offenses_for_files.each do |file, offenses|
20
+ offenses.each do |offense|
21
+ report_offense(file, offense)
22
+ end
23
+ end
24
+ output.puts
12
25
  end
13
26
 
14
27
  private
@@ -31,7 +44,7 @@ module RuboCop
31
44
 
32
45
  def report_offense(file, offense)
33
46
  output.printf(
34
- "\n::%<severity>s file=%<file>s,line=%<line>d,col=%<column>d::%<message>s\n",
47
+ "\n::%<severity>s file=%<file>s,line=%<line>d,col=%<column>d::%<message>s",
35
48
  severity: github_severity(offense),
36
49
  file: PathUtil.smart_path(file),
37
50
  line: offense.line,
@@ -4,7 +4,6 @@ require 'cgi'
4
4
  require 'erb'
5
5
  require 'ostruct'
6
6
  require 'base64'
7
- require_relative 'text_util'
8
7
 
9
8
  module RuboCop
10
9
  module Formatter
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ruby-progressbar'
4
+
3
5
  module RuboCop
4
6
  module Formatter
5
7
  # This formatter displays the list of offended cops with a count of how
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'colorizable'
4
- require_relative 'text_util'
5
4
 
6
5
  module RuboCop
7
6
  module Formatter
@@ -63,7 +62,7 @@ module RuboCop
63
62
  rainbow,
64
63
  # :safe_autocorrect is a derived option based on several command-line
65
64
  # arguments - see Rubocop::Options#add_autocorrection_options
66
- safe_auto_correct: @options[:safe_autocorrect])
65
+ safe_autocorrect: @options[:safe_autocorrect])
67
66
 
68
67
  output.puts
69
68
  output.puts report.summary
@@ -110,22 +109,22 @@ module RuboCop
110
109
  # rubocop:disable Metrics/ParameterLists
111
110
  def initialize(
112
111
  file_count, offense_count, correction_count, correctable_count, rainbow,
113
- safe_auto_correct: false
112
+ safe_autocorrect: false
114
113
  )
115
114
  @file_count = file_count
116
115
  @offense_count = offense_count
117
116
  @correction_count = correction_count
118
117
  @correctable_count = correctable_count
119
118
  @rainbow = rainbow
120
- @safe_auto_correct = safe_auto_correct
119
+ @safe_autocorrect = safe_autocorrect
121
120
  end
122
121
  # rubocop:enable Metrics/ParameterLists
123
122
 
124
123
  def summary
125
124
  if @correction_count.positive?
126
125
  if @correctable_count.positive?
127
- "#{files} inspected, #{offenses} detected, #{corrections} corrected,"\
128
- " #{correctable}"
126
+ "#{files} inspected, #{offenses} detected, #{corrections} corrected, " \
127
+ "#{correctable}"
129
128
  else
130
129
  "#{files} inspected, #{offenses} detected, #{corrections} corrected"
131
130
  end
@@ -159,7 +158,7 @@ module RuboCop
159
158
  end
160
159
 
161
160
  def correctable
162
- if @safe_auto_correct
161
+ if @safe_autocorrect
163
162
  text = pluralize(@correctable_count, 'more offense')
164
163
  "#{colorize(text, :yellow)} can be corrected with `rubocop -A`"
165
164
  else