rubocop 1.19.0 → 1.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (187) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +86 -14
  4. data/lib/rubocop/config.rb +5 -0
  5. data/lib/rubocop/config_loader.rb +4 -2
  6. data/lib/rubocop/config_validator.rb +9 -1
  7. data/lib/rubocop/cop/base.rb +3 -3
  8. data/lib/rubocop/cop/bundler/gem_filename.rb +103 -0
  9. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +45 -21
  10. data/lib/rubocop/cop/bundler/ordered_gems.rb +3 -12
  11. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +2 -2
  12. data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
  13. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +11 -10
  14. data/lib/rubocop/cop/documentation.rb +1 -1
  15. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +3 -12
  16. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
  17. data/lib/rubocop/cop/generator.rb +14 -8
  18. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  19. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
  20. data/lib/rubocop/cop/layout/class_structure.rb +2 -1
  21. data/lib/rubocop/cop/layout/dot_position.rb +25 -2
  22. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  23. data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
  24. data/lib/rubocop/cop/layout/line_length.rb +8 -6
  25. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
  26. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +3 -0
  27. data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -0
  28. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +5 -4
  29. data/lib/rubocop/cop/layout/single_line_block_chain.rb +15 -4
  30. data/lib/rubocop/cop/layout/space_after_not.rb +1 -0
  31. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +2 -1
  32. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
  33. data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -0
  34. data/lib/rubocop/cop/layout/space_inside_parens.rb +74 -24
  35. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -1
  36. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +111 -0
  37. data/lib/rubocop/cop/lint/ambiguous_range.rb +8 -8
  38. data/lib/rubocop/cop/lint/assignment_in_condition.rb +7 -5
  39. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +18 -5
  40. data/lib/rubocop/cop/lint/boolean_symbol.rb +5 -0
  41. data/lib/rubocop/cop/lint/debugger.rb +2 -4
  42. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
  43. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +24 -1
  44. data/lib/rubocop/cop/lint/else_layout.rb +9 -5
  45. data/lib/rubocop/cop/lint/empty_in_pattern.rb +1 -1
  46. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  47. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
  48. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +12 -3
  49. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +67 -0
  50. data/lib/rubocop/cop/lint/interpolation_check.rb +5 -0
  51. data/lib/rubocop/cop/lint/loop.rb +4 -3
  52. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +5 -1
  53. data/lib/rubocop/cop/lint/number_conversion.rb +12 -1
  54. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  55. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +4 -2
  56. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +17 -0
  57. data/lib/rubocop/cop/lint/percent_string_array.rb +10 -0
  58. data/lib/rubocop/cop/lint/raise_exception.rb +4 -0
  59. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +5 -4
  60. data/lib/rubocop/cop/lint/require_relative_self_path.rb +49 -0
  61. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -1
  62. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  63. data/lib/rubocop/cop/lint/triple_quotes.rb +1 -1
  64. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +8 -3
  65. data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -3
  66. data/lib/rubocop/cop/lint/useless_method_definition.rb +3 -2
  67. data/lib/rubocop/cop/lint/useless_setter_call.rb +7 -4
  68. data/lib/rubocop/cop/lint/useless_times.rb +4 -3
  69. data/lib/rubocop/cop/metrics/abc_size.rb +6 -0
  70. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  71. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  72. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
  73. data/lib/rubocop/cop/mixin/annotation_comment.rb +57 -34
  74. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  75. data/lib/rubocop/cop/mixin/documentation_comment.rb +5 -2
  76. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +23 -1
  77. data/lib/rubocop/cop/mixin/heredoc.rb +1 -3
  78. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -2
  79. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +9 -1
  80. data/lib/rubocop/cop/mixin/percent_array.rb +11 -3
  81. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +9 -1
  82. data/lib/rubocop/cop/naming/ascii_identifiers.rb +0 -3
  83. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  84. data/lib/rubocop/cop/naming/constant_name.rb +1 -1
  85. data/lib/rubocop/cop/naming/inclusive_language.rb +9 -9
  86. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +5 -4
  87. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +7 -0
  88. data/lib/rubocop/cop/security/io_methods.rb +49 -0
  89. data/lib/rubocop/cop/security/json_load.rb +8 -7
  90. data/lib/rubocop/cop/security/open.rb +4 -0
  91. data/lib/rubocop/cop/security/yaml_load.rb +4 -0
  92. data/lib/rubocop/cop/style/accessor_grouping.rb +2 -2
  93. data/lib/rubocop/cop/style/and_or.rb +5 -0
  94. data/lib/rubocop/cop/style/arguments_forwarding.rb +13 -2
  95. data/lib/rubocop/cop/style/array_coercion.rb +21 -3
  96. data/lib/rubocop/cop/style/ascii_comments.rb +0 -3
  97. data/lib/rubocop/cop/style/block_delimiters.rb +23 -6
  98. data/lib/rubocop/cop/style/case_equality.rb +6 -9
  99. data/lib/rubocop/cop/style/case_like_if.rb +5 -0
  100. data/lib/rubocop/cop/style/class_and_module_children.rb +9 -0
  101. data/lib/rubocop/cop/style/collection_compact.rb +7 -5
  102. data/lib/rubocop/cop/style/collection_methods.rb +8 -6
  103. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  104. data/lib/rubocop/cop/style/comment_annotation.rb +25 -39
  105. data/lib/rubocop/cop/style/commented_keyword.rb +4 -1
  106. data/lib/rubocop/cop/style/date_time.rb +5 -0
  107. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
  108. data/lib/rubocop/cop/style/documentation.rb +23 -8
  109. data/lib/rubocop/cop/style/double_negation.rb +27 -6
  110. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  111. data/lib/rubocop/cop/style/encoding.rb +26 -15
  112. data/lib/rubocop/cop/style/explicit_block_argument.rb +21 -11
  113. data/lib/rubocop/cop/style/float_division.rb +10 -2
  114. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +7 -2
  115. data/lib/rubocop/cop/style/global_std_stream.rb +4 -0
  116. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +11 -0
  117. data/lib/rubocop/cop/style/hash_each_methods.rb +5 -0
  118. data/lib/rubocop/cop/style/hash_except.rb +4 -3
  119. data/lib/rubocop/cop/style/hash_transform_keys.rb +4 -6
  120. data/lib/rubocop/cop/style/hash_transform_values.rb +4 -6
  121. data/lib/rubocop/cop/style/identical_conditional_branches.rb +18 -16
  122. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +18 -4
  123. data/lib/rubocop/cop/style/infinite_loop.rb +4 -3
  124. data/lib/rubocop/cop/style/inverse_methods.rb +9 -2
  125. data/lib/rubocop/cop/style/lambda_call.rb +1 -1
  126. data/lib/rubocop/cop/style/line_end_concatenation.rb +13 -0
  127. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +6 -6
  128. data/lib/rubocop/cop/style/module_function.rb +8 -9
  129. data/lib/rubocop/cop/style/mutable_constant.rb +73 -6
  130. data/lib/rubocop/cop/style/negated_if.rb +1 -1
  131. data/lib/rubocop/cop/style/negated_unless.rb +1 -1
  132. data/lib/rubocop/cop/style/non_nil_check.rb +2 -2
  133. data/lib/rubocop/cop/style/not.rb +2 -2
  134. data/lib/rubocop/cop/style/numbered_parameters.rb +46 -0
  135. data/lib/rubocop/cop/style/numbered_parameters_limit.rb +50 -0
  136. data/lib/rubocop/cop/style/numeric_literals.rb +7 -8
  137. data/lib/rubocop/cop/style/numeric_predicate.rb +5 -0
  138. data/lib/rubocop/cop/style/optional_arguments.rb +4 -0
  139. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +14 -4
  140. data/lib/rubocop/cop/style/parallel_assignment.rb +1 -1
  141. data/lib/rubocop/cop/style/percent_q_literals.rb +2 -2
  142. data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -4
  143. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  144. data/lib/rubocop/cop/style/redundant_argument.rb +14 -7
  145. data/lib/rubocop/cop/style/redundant_begin.rb +25 -0
  146. data/lib/rubocop/cop/style/redundant_condition.rb +2 -3
  147. data/lib/rubocop/cop/style/redundant_fetch_block.rb +4 -0
  148. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +12 -3
  149. data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
  150. data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
  151. data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -3
  152. data/lib/rubocop/cop/style/redundant_self.rb +10 -0
  153. data/lib/rubocop/cop/style/redundant_self_assignment.rb +4 -3
  154. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +23 -28
  155. data/lib/rubocop/cop/style/redundant_sort.rb +51 -18
  156. data/lib/rubocop/cop/style/regexp_literal.rb +3 -3
  157. data/lib/rubocop/cop/style/return_nil.rb +2 -1
  158. data/lib/rubocop/cop/style/safe_navigation.rb +13 -2
  159. data/lib/rubocop/cop/style/select_by_regexp.rb +106 -0
  160. data/lib/rubocop/cop/style/single_argument_dig.rb +5 -0
  161. data/lib/rubocop/cop/style/slicing_with_range.rb +13 -0
  162. data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -0
  163. data/lib/rubocop/cop/style/special_global_vars.rb +4 -0
  164. data/lib/rubocop/cop/style/static_class.rb +5 -5
  165. data/lib/rubocop/cop/style/string_chars.rb +4 -2
  166. data/lib/rubocop/cop/style/string_concatenation.rb +5 -1
  167. data/lib/rubocop/cop/style/string_hash_keys.rb +4 -0
  168. data/lib/rubocop/cop/style/struct_inheritance.rb +4 -0
  169. data/lib/rubocop/cop/style/swap_values.rb +4 -2
  170. data/lib/rubocop/cop/style/symbol_array.rb +3 -3
  171. data/lib/rubocop/cop/style/symbol_proc.rb +26 -0
  172. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +19 -0
  173. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  174. data/lib/rubocop/cop/style/word_array.rb +3 -3
  175. data/lib/rubocop/cop/style/yoda_condition.rb +24 -7
  176. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -0
  177. data/lib/rubocop/cop/util.rb +2 -2
  178. data/lib/rubocop/cops_documentation_generator.rb +17 -5
  179. data/lib/rubocop/magic_comment.rb +44 -15
  180. data/lib/rubocop/options.rb +126 -112
  181. data/lib/rubocop/result_cache.rb +1 -1
  182. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  183. data/lib/rubocop/rspec/expect_offense.rb +6 -2
  184. data/lib/rubocop/runner.rb +1 -2
  185. data/lib/rubocop/version.rb +1 -1
  186. data/lib/rubocop.rb +10 -2
  187. metadata +13 -5
@@ -7,6 +7,11 @@ module RuboCop
7
7
  class MagicComment
8
8
  # @see https://git.io/vMC1C IRB's pattern for matching magic comment tokens
9
9
  TOKEN = /[[:alnum:]\-_]+/.freeze
10
+ KEYWORDS = {
11
+ encoding: '(?:en)?coding',
12
+ frozen_string_literal: 'frozen[_-]string[_-]literal',
13
+ shareable_constant_value: 'shareable[_-]constant[_-]value'
14
+ }.freeze
10
15
 
11
16
  # Detect magic comment format and pass it to the appropriate wrapper.
12
17
  #
@@ -15,8 +20,8 @@ module RuboCop
15
20
  # @return [RuboCop::MagicComment]
16
21
  def self.parse(comment)
17
22
  case comment
18
- when EmacsComment::FORMAT then EmacsComment.new(comment)
19
- when VimComment::FORMAT then VimComment.new(comment)
23
+ when EmacsComment::REGEXP then EmacsComment.new(comment)
24
+ when VimComment::REGEXP then VimComment.new(comment)
20
25
  else
21
26
  SimpleComment.new(comment)
22
27
  end
@@ -30,6 +35,10 @@ module RuboCop
30
35
  frozen_string_literal_specified? || encoding_specified? || shareable_constant_value_specified?
31
36
  end
32
37
 
38
+ def valid?
39
+ @comment.start_with?('#') && any?
40
+ end
41
+
33
42
  # Does the magic comment enable the frozen string literal feature.
34
43
  #
35
44
  # Test whether the frozen string literal value is `true`. Cannot
@@ -111,6 +120,18 @@ module RuboCop
111
120
  #
112
121
  # @abstract
113
122
  class EditorComment < MagicComment
123
+ def encoding
124
+ match(self.class::KEYWORDS[:encoding])
125
+ end
126
+
127
+ # Rewrite the comment without a given token type
128
+ def without(type)
129
+ remaining = tokens.grep_v(/\A#{self.class::KEYWORDS[type.to_sym]}/)
130
+ return '' if remaining.empty?
131
+
132
+ self.class::FORMAT % remaining.join(self.class::SEPARATOR)
133
+ end
134
+
114
135
  private
115
136
 
116
137
  # Find a token starting with the provided keyword and extract its value.
@@ -135,7 +156,7 @@ module RuboCop
135
156
  #
136
157
  # @return [Array<String>]
137
158
  def tokens
138
- extract(self.class::FORMAT).split(self.class::SEPARATOR).map(&:strip)
159
+ extract(self.class::REGEXP).split(self.class::SEPARATOR).map(&:strip)
139
160
  end
140
161
  end
141
162
 
@@ -151,22 +172,19 @@ module RuboCop
151
172
  # @see https://www.gnu.org/software/emacs/manual/html_node/emacs/Specify-Coding.html
152
173
  # @see https://git.io/vMCXh Emacs handling in Ruby's parse.y
153
174
  class EmacsComment < EditorComment
154
- FORMAT = /-\*-(.+)-\*-/.freeze
175
+ REGEXP = /-\*-(.+)-\*-/.freeze
176
+ FORMAT = '# -*- %s -*-'
155
177
  SEPARATOR = ';'
156
178
  OPERATOR = ':'
157
179
 
158
- def encoding
159
- match('(?:en)?coding')
160
- end
161
-
162
180
  private
163
181
 
164
182
  def extract_frozen_string_literal
165
- match('frozen[_-]string[_-]literal')
183
+ match(KEYWORDS[:frozen_string_literal])
166
184
  end
167
185
 
168
186
  def extract_shareable_constant_value
169
- match('shareable[_-]constant[_-]values')
187
+ match(KEYWORDS[:shareable_constant_value])
170
188
  end
171
189
  end
172
190
 
@@ -179,9 +197,11 @@ module RuboCop
179
197
  #
180
198
  # comment.encoding # => 'ascii-8bit'
181
199
  class VimComment < EditorComment
182
- FORMAT = /#\s*vim:\s*(.+)/.freeze
200
+ REGEXP = /#\s*vim:\s*(.+)/.freeze
201
+ FORMAT = '# vim: %s'
183
202
  SEPARATOR = ', '
184
203
  OPERATOR = '='
204
+ KEYWORDS = MagicComment::KEYWORDS.merge(encoding: 'fileencoding').freeze
185
205
 
186
206
  # For some reason the fileencoding keyword only works if there
187
207
  # is at least one other token included in the string. For example
@@ -193,7 +213,7 @@ module RuboCop
193
213
  # # vim: foo=bar, fileencoding=ascii-8bit
194
214
  #
195
215
  def encoding
196
- match('fileencoding') if tokens.size > 1
216
+ super if tokens.size > 1
197
217
  end
198
218
 
199
219
  # Vim comments cannot specify frozen string literal behavior.
@@ -219,7 +239,16 @@ module RuboCop
219
239
  class SimpleComment < MagicComment
220
240
  # Match `encoding` or `coding`
221
241
  def encoding
222
- extract(/\A\s*\#.*\b(?:en)?coding: (#{TOKEN})/io)
242
+ extract(/\A\s*\#.*\b#{KEYWORDS[:encoding]}: (#{TOKEN})/io)
243
+ end
244
+
245
+ # Rewrite the comment without a given token type
246
+ def without(type)
247
+ if @comment.match?(/\A#\s*#{self.class::KEYWORDS[type.to_sym]}/)
248
+ ''
249
+ else
250
+ @comment
251
+ end
223
252
  end
224
253
 
225
254
  private
@@ -232,11 +261,11 @@ module RuboCop
232
261
  # Case-insensitive and dashes/underscores are acceptable.
233
262
  # @see https://git.io/vM7Mg
234
263
  def extract_frozen_string_literal
235
- extract(/\A\s*#\s*frozen[_-]string[_-]literal:\s*(#{TOKEN})\s*\z/io)
264
+ extract(/\A\s*#\s*#{KEYWORDS[:frozen_string_literal]}:\s*(#{TOKEN})\s*\z/io)
236
265
  end
237
266
 
238
267
  def extract_shareable_constant_value
239
- extract(/\A\s*#\s*shareable[_-]constant[_-]value:\s*(#{TOKEN})\s*\z/io)
268
+ extract(/\A\s*#\s*#{KEYWORDS[:shareable_constant_value]}:\s*(#{TOKEN})\s*\z/io)
240
269
  end
241
270
  end
242
271
  end
@@ -59,86 +59,111 @@ module RuboCop
59
59
 
60
60
  def define_options
61
61
  OptionParser.new do |opts|
62
- opts.banner = 'Usage: rubocop [options] [file1, file2, ...]'
62
+ opts.banner = rainbow.wrap('Usage: rubocop [options] [file1, file2, ...]').bright
63
63
 
64
- add_list_options(opts)
65
- add_only_options(opts)
66
- add_configuration_options(opts)
67
- add_formatting_options(opts)
68
-
69
- option(opts, '-r', '--require FILE') { |f| require_feature(f) }
70
-
71
- add_severity_option(opts)
72
- add_flags_with_optional_args(opts)
64
+ add_check_options(opts)
73
65
  add_cache_options(opts)
74
- add_boolean_flags(opts)
75
- add_aliases(opts)
66
+ add_output_options(opts)
67
+ add_autocorrection_options(opts)
68
+ add_config_generation_options(opts)
69
+ add_additional_modes(opts)
70
+ add_general_options(opts)
71
+ end
72
+ end
76
73
 
74
+ def add_check_options(opts) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
75
+ section(opts, 'Basic Options') do
76
+ option(opts, '-l', '--lint') do
77
+ @options[:only] ||= []
78
+ @options[:only] << 'Lint'
79
+ end
80
+ option(opts, '-x', '--fix-layout') do
81
+ @options[:only] ||= []
82
+ @options[:only] << 'Layout'
83
+ @options[:auto_correct] = true
84
+ end
85
+ option(opts, '--safe')
86
+ add_cop_selection_csv_option('except', opts)
87
+ add_cop_selection_csv_option('only', opts)
88
+ option(opts, '--only-guide-cops')
89
+ option(opts, '-F', '--fail-fast')
90
+ option(opts, '--disable-pending-cops')
91
+ option(opts, '--enable-pending-cops')
92
+ option(opts, '--ignore-disable-comments')
93
+ option(opts, '--force-exclusion')
94
+ option(opts, '--only-recognized-file-types')
95
+ option(opts, '--ignore-parent-exclusion')
96
+ option(opts, '--force-default-config')
77
97
  option(opts, '-s', '--stdin FILE')
98
+ option(opts, '-P', '--[no-]parallel')
99
+ add_severity_option(opts)
78
100
  end
79
101
  end
80
102
 
81
- def add_only_options(opts)
82
- add_cop_selection_csv_option('except', opts)
83
- add_cop_selection_csv_option('only', opts)
84
- option(opts, '--only-guide-cops')
85
- end
103
+ def add_output_options(opts) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
104
+ section(opts, 'Output Options') do
105
+ option(opts, '-f', '--format FORMATTER') do |key|
106
+ @options[:formatters] ||= []
107
+ @options[:formatters] << [key]
108
+ end
86
109
 
87
- def add_cop_selection_csv_option(option, opts)
88
- option(opts, "--#{option} [COP1,COP2,...]") do |list|
89
- unless list
90
- message = "--#{option} argument should be [COP1,COP2,...]."
110
+ option(opts, '-D', '--[no-]display-cop-names')
111
+ option(opts, '-E', '--extra-details')
112
+ option(opts, '-S', '--display-style-guide')
91
113
 
92
- raise OptionArgumentError, message
114
+ option(opts, '-o', '--out FILE') do |path|
115
+ if @options[:formatters]
116
+ @options[:formatters].last << path
117
+ else
118
+ @options[:output_path] = path
119
+ end
93
120
  end
94
121
 
95
- @options[:"#{option}"] = list.empty? ? [''] : list.split(',')
122
+ option(opts, '--stderr')
123
+ option(opts, '--display-time')
124
+ option(opts, '--display-only-failed')
125
+ option(opts, '--display-only-fail-level-offenses')
96
126
  end
97
127
  end
98
128
 
99
- def add_configuration_options(opts)
100
- option(opts, '-c', '--config FILE')
101
- option(opts, '--force-exclusion')
102
- option(opts, '--only-recognized-file-types')
103
- option(opts, '--ignore-parent-exclusion')
104
- option(opts, '--force-default-config')
105
- add_auto_gen_options(opts)
106
- end
107
-
108
- def add_auto_gen_options(opts)
109
- option(opts, '--auto-gen-config')
110
-
111
- option(opts, '--regenerate-todo') do
112
- @options.replace(ConfigRegeneration.new.options.merge(@options))
129
+ def add_autocorrection_options(opts)
130
+ section(opts, 'Auto-correction') do
131
+ option(opts, '-a', '--auto-correct') { @options[:safe_auto_correct] = true }
132
+ option(opts, '--safe-auto-correct') do
133
+ warn '--safe-auto-correct is deprecated; use --auto-correct'
134
+ @options[:safe_auto_correct] = @options[:auto_correct] = true
135
+ end
136
+ option(opts, '-A', '--auto-correct-all') { @options[:auto_correct] = true }
137
+ option(opts, '--disable-uncorrectable')
113
138
  end
139
+ end
114
140
 
115
- option(opts, '--exclude-limit COUNT') { @validator.validate_exclude_limit_option }
141
+ def add_config_generation_options(opts)
142
+ section(opts, 'Config Generation') do
143
+ option(opts, '--auto-gen-config')
116
144
 
117
- option(opts, '--disable-uncorrectable')
145
+ option(opts, '--regenerate-todo') do
146
+ @options.replace(ConfigRegeneration.new.options.merge(@options))
147
+ end
118
148
 
119
- option(opts, '--[no-]offense-counts')
120
- option(opts, '--[no-]auto-gen-only-exclude')
121
- option(opts, '--[no-]auto-gen-timestamp')
149
+ option(opts, '--exclude-limit COUNT') { @validator.validate_exclude_limit_option }
122
150
 
123
- option(opts, '--init')
151
+ option(opts, '--[no-]offense-counts')
152
+ option(opts, '--[no-]auto-gen-only-exclude')
153
+ option(opts, '--[no-]auto-gen-timestamp')
154
+ end
124
155
  end
125
156
 
126
- def add_formatting_options(opts)
127
- option(opts, '-f', '--format FORMATTER') do |key|
128
- @options[:formatters] ||= []
129
- @options[:formatters] << [key]
130
- end
157
+ def add_cop_selection_csv_option(option, opts)
158
+ option(opts, "--#{option} [COP1,COP2,...]") do |list|
159
+ unless list
160
+ message = "--#{option} argument should be [COP1,COP2,...]."
131
161
 
132
- option(opts, '-o', '--out FILE') do |path|
133
- if @options[:formatters]
134
- @options[:formatters].last << path
135
- else
136
- @options[:output_path] = path
162
+ raise OptionArgumentError, message
137
163
  end
138
- end
139
164
 
140
- option(opts, '--display-time')
141
- option(opts, '--display-only-failed')
165
+ @options[:"#{option}"] = list.empty? ? [''] : list.split(',')
166
+ end
142
167
  end
143
168
 
144
169
  def add_severity_option(opts)
@@ -148,62 +173,50 @@ module RuboCop
148
173
  table) do |severity|
149
174
  @options[:fail_level] = severity
150
175
  end
151
- option(opts, '--display-only-fail-level-offenses')
152
176
  end
153
177
 
154
- def add_flags_with_optional_args(opts)
155
- option(opts, '--show-cops [COP1,COP2,...]') do |list|
156
- @options[:show_cops] = list.nil? ? [] : list.split(',')
178
+ def add_cache_options(opts)
179
+ section(opts, 'Caching') do
180
+ option(opts, '-C', '--cache FLAG')
181
+ option(opts, '--cache-root DIR') { @validator.validate_cache_enabled_for_cache_root }
157
182
  end
158
183
  end
159
184
 
160
- def add_cache_options(opts)
161
- option(opts, '-C', '--cache FLAG')
162
- option(opts, '--cache-root DIR') { @validator.validate_cache_enabled_for_cache_root }
163
- end
164
-
165
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
166
- def add_boolean_flags(opts)
167
- option(opts, '-F', '--fail-fast')
168
- option(opts, '-d', '--debug')
169
- option(opts, '-D', '--[no-]display-cop-names')
170
- option(opts, '-E', '--extra-details')
171
- option(opts, '-S', '--display-style-guide')
172
- option(opts, '-a', '--auto-correct') { @options[:safe_auto_correct] = true }
173
- option(opts, '--safe-auto-correct') do
174
- warn '--safe-auto-correct is deprecated; use --auto-correct'
175
- @options[:safe_auto_correct] = @options[:auto_correct] = true
185
+ def add_additional_modes(opts)
186
+ section(opts, 'Additional Modes') do
187
+ option(opts, '-L', '--list-target-files')
188
+ option(opts, '--show-cops [COP1,COP2,...]') do |list|
189
+ @options[:show_cops] = list.nil? ? [] : list.split(',')
190
+ end
176
191
  end
177
- option(opts, '-A', '--auto-correct-all') { @options[:auto_correct] = true }
178
- option(opts, '--disable-pending-cops')
179
- option(opts, '--enable-pending-cops')
180
- option(opts, '--ignore-disable-comments')
181
-
182
- option(opts, '--safe')
183
-
184
- option(opts, '--stderr')
185
- option(opts, '--[no-]color')
186
-
187
- option(opts, '-v', '--version')
188
- option(opts, '-V', '--verbose-version')
189
- option(opts, '-P', '--[no-]parallel')
190
192
  end
191
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
192
193
 
193
- def add_aliases(opts)
194
- option(opts, '-l', '--lint') do
195
- @options[:only] ||= []
196
- @options[:only] << 'Lint'
194
+ def add_general_options(opts)
195
+ section(opts, 'General Options') do
196
+ option(opts, '--init')
197
+ option(opts, '-c', '--config FILE')
198
+ option(opts, '-d', '--debug')
199
+ option(opts, '-r', '--require FILE') { |f| require_feature(f) }
200
+ option(opts, '--[no-]color')
201
+ option(opts, '-v', '--version')
202
+ option(opts, '-V', '--verbose-version')
197
203
  end
198
- option(opts, '-x', '--fix-layout') do
199
- @options[:only] ||= []
200
- @options[:only] << 'Layout'
201
- @options[:auto_correct] = true
204
+ end
205
+
206
+ def rainbow
207
+ @rainbow ||= begin
208
+ rainbow = Rainbow.new
209
+ rainbow.enabled = false if ARGV.include?('--no-color')
210
+ rainbow
202
211
  end
203
212
  end
204
213
 
205
- def add_list_options(opts)
206
- option(opts, '-L', '--list-target-files')
214
+ # Creates a section of options in order to separate them visually when
215
+ # using `--help`.
216
+ def section(opts, heading, &_block)
217
+ heading = rainbow.wrap(heading).bright
218
+ opts.separator("\n#{heading}:\n")
219
+ yield
207
220
  end
208
221
 
209
222
  # Sets a value in the @options hash, based on the given long option and its
@@ -403,7 +416,7 @@ module RuboCop
403
416
  only: 'Run only the given cop(s).',
404
417
  only_guide_cops: ['Run only cops for rules that link to a',
405
418
  'style guide.'],
406
- except: 'Disable the given cop(s).',
419
+ except: 'Exclude the given cop(s).',
407
420
  require: 'Require Ruby file.',
408
421
  config: 'Specify configuration file.',
409
422
  auto_gen_config: ['Generate a configuration file acting as a',
@@ -422,29 +435,30 @@ module RuboCop
422
435
  'when running --auto-gen-config, except if the',
423
436
  'number of files with offenses is bigger than',
424
437
  'exclude-limit. Default is false.'],
425
- exclude_limit: ['Used together with --auto-gen-config to',
426
- 'set the limit for how many Exclude',
427
- "properties to generate. Default is #{MAX_EXCL}."],
438
+ exclude_limit: ['Set the limit for how many files to explicitly exclude.',
439
+ 'If there are more files than the limit, the cop will',
440
+ "be disabled instead. Default is #{MAX_EXCL}."],
428
441
  disable_uncorrectable: ['Used with --auto-correct to annotate any',
429
442
  'offenses that do not support autocorrect',
430
443
  'with `rubocop:todo` comments.'],
431
- force_exclusion: ['Force excluding files specified in the',
432
- 'configuration `Exclude` even if they are',
433
- 'explicitly passed as arguments.'],
444
+ force_exclusion: ['Any files excluded by `Exclude` in configuration',
445
+ 'files will be excluded, even if given explicitly',
446
+ 'as arguments.'],
434
447
  only_recognized_file_types: ['Inspect files given on the command line only if',
435
- 'they are listed in AllCops/Include parameters',
448
+ 'they are listed in `AllCops/Include` parameters',
436
449
  'of user configuration or default configuration.'],
437
450
  ignore_disable_comments: ['Run cops even when they are disabled locally',
438
- 'with a comment.'],
439
- ignore_parent_exclusion: ['Prevent from inheriting AllCops/Exclude from',
451
+ 'by a `rubocop:disable` directive.'],
452
+ ignore_parent_exclusion: ['Prevent from inheriting `AllCops/Exclude` from',
440
453
  'parent folders.'],
441
454
  force_default_config: ['Use default configuration even if configuration',
442
455
  'files are present in the directory tree.'],
443
456
  format: ['Choose an output formatter. This option',
444
457
  'can be specified multiple times to enable',
445
458
  'multiple formatters at the same time.',
446
- '[p]rogress is used by default',
447
- *FORMATTER_OPTION_LIST.map { |item| " #{item}" },
459
+ *FORMATTER_OPTION_LIST.map do |item|
460
+ " #{item}#{' (default)' if item == '[p]rogress'}"
461
+ end,
448
462
  ' custom formatter class name'],
449
463
  out: ['Write output to a file instead of STDOUT.',
450
464
  'This option applies to the previously',
@@ -45,7 +45,7 @@ module RuboCop
45
45
  def remove_oldest_files(files, dirs, cache_root, verbose)
46
46
  # Add 1 to half the number of files, so that we remove the file if
47
47
  # there's only 1 left.
48
- remove_count = 1 + files.length / 2
48
+ remove_count = 1 + (files.length / 2)
49
49
  puts "Removing the #{remove_count} oldest files from #{cache_root}" if verbose
50
50
  sorted = files.sort_by { |path| File.mtime(path) }
51
51
  remove_files(sorted, dirs, remove_count)
@@ -49,7 +49,7 @@ module CopHelper
49
49
  team = RuboCop::Cop::Team.new([cop], nil, raise_error: true)
50
50
  report = team.investigate(processed_source)
51
51
  @last_corrector = report.correctors.first || RuboCop::Cop::Corrector.new(processed_source)
52
- report.offenses
52
+ report.offenses.reject(&:disabled?)
53
53
  end
54
54
  end
55
55
 
@@ -126,7 +126,7 @@ module RuboCop
126
126
  @offenses
127
127
  end
128
128
 
129
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
129
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
130
130
  def expect_correction(correction, loop: true, source: nil)
131
131
  if source
132
132
  expected_annotations = parse_annotations(source, raise_error: false)
@@ -136,6 +136,8 @@ module RuboCop
136
136
 
137
137
  raise '`expect_correction` must follow `expect_offense`' unless @processed_source
138
138
 
139
+ source = @processed_source.raw_source
140
+
139
141
  iteration = 0
140
142
  new_source = loop do
141
143
  iteration += 1
@@ -155,9 +157,11 @@ module RuboCop
155
157
  _investigate(cop, @processed_source)
156
158
  end
157
159
 
160
+ raise 'Use `expect_no_corrections` if the code will not change' if new_source == source
161
+
158
162
  expect(new_source).to eq(correction)
159
163
  end
160
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
164
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
161
165
 
162
166
  def expect_no_corrections
163
167
  raise '`expect_no_corrections` must follow `expect_offense`' unless @processed_source
@@ -216,8 +216,7 @@ module RuboCop
216
216
  def cached_run?
217
217
  @cached_run ||=
218
218
  (@options[:cache] == 'true' ||
219
- @options[:cache] != 'false' &&
220
- @config_store.for_pwd.for_all_cops['UseCache']) &&
219
+ (@options[:cache] != 'false' && @config_store.for_pwd.for_all_cops['UseCache'])) &&
221
220
  # When running --auto-gen-config, there's some processing done in the
222
221
  # cops related to calculating the Max parameters for Metrics cops. We
223
222
  # need to do that processing and cannot use caching.
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.19.0'
6
+ STRING = '1.22.0'
7
7
 
8
8
  MSG = '%<version>s (using Parser %<parser_version>s, '\
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
data/lib/rubocop.rb CHANGED
@@ -57,7 +57,6 @@ require_relative 'rubocop/cop/variable_force/reference'
57
57
  require_relative 'rubocop/cop/variable_force/scope'
58
58
  require_relative 'rubocop/cop/variable_force/variable_table'
59
59
 
60
- require_relative 'rubocop/cop/mixin/annotation_comment'
61
60
  require_relative 'rubocop/cop/mixin/array_min_size'
62
61
  require_relative 'rubocop/cop/mixin/array_syntax'
63
62
  require_relative 'rubocop/cop/mixin/alignment'
@@ -76,6 +75,7 @@ require_relative 'rubocop/cop/mixin/def_node'
76
75
  require_relative 'rubocop/cop/mixin/documentation_comment'
77
76
  require_relative 'rubocop/cop/mixin/duplication'
78
77
  require_relative 'rubocop/cop/mixin/range_help'
78
+ require_relative 'rubocop/cop/mixin/annotation_comment' # relies on range
79
79
  require_relative 'rubocop/cop/mixin/empty_lines_around_body' # relies on range
80
80
  require_relative 'rubocop/cop/mixin/empty_parameter'
81
81
  require_relative 'rubocop/cop/mixin/end_keyword_alignment'
@@ -152,6 +152,7 @@ require_relative 'rubocop/cop/correctors/unused_arg_corrector'
152
152
 
153
153
  require_relative 'rubocop/cop/bundler/duplicated_gem'
154
154
  require_relative 'rubocop/cop/bundler/gem_comment'
155
+ require_relative 'rubocop/cop/bundler/gem_filename'
155
156
  require_relative 'rubocop/cop/bundler/gem_version'
156
157
  require_relative 'rubocop/cop/bundler/insecure_protocol_source'
157
158
  require_relative 'rubocop/cop/bundler/ordered_gems'
@@ -262,6 +263,7 @@ require_relative 'rubocop/cop/layout/trailing_whitespace'
262
263
  require_relative 'rubocop/cop/lint/ambiguous_assignment'
263
264
  require_relative 'rubocop/cop/lint/ambiguous_block_association'
264
265
  require_relative 'rubocop/cop/lint/ambiguous_operator'
266
+ require_relative 'rubocop/cop/lint/ambiguous_operator_precedence'
265
267
  require_relative 'rubocop/cop/lint/ambiguous_range'
266
268
  require_relative 'rubocop/cop/lint/ambiguous_regexp_literal'
267
269
  require_relative 'rubocop/cop/lint/assignment_in_condition'
@@ -305,8 +307,9 @@ require_relative 'rubocop/cop/lint/hash_compare_by_identity'
305
307
  require_relative 'rubocop/cop/lint/heredoc_method_call_position'
306
308
  require_relative 'rubocop/cop/lint/identity_comparison'
307
309
  require_relative 'rubocop/cop/lint/implicit_string_concatenation'
308
- require_relative 'rubocop/cop/lint/inherit_exception'
310
+ require_relative 'rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler'
309
311
  require_relative 'rubocop/cop/lint/ineffective_access_modifier'
312
+ require_relative 'rubocop/cop/lint/inherit_exception'
310
313
  require_relative 'rubocop/cop/lint/interpolation_check'
311
314
  require_relative 'rubocop/cop/lint/lambda_without_literal_block'
312
315
  require_relative 'rubocop/cop/lint/literal_as_condition'
@@ -343,6 +346,7 @@ require_relative 'rubocop/cop/lint/redundant_with_index'
343
346
  require_relative 'rubocop/cop/lint/redundant_with_object'
344
347
  require_relative 'rubocop/cop/lint/regexp_as_condition'
345
348
  require_relative 'rubocop/cop/lint/require_parentheses'
349
+ require_relative 'rubocop/cop/lint/require_relative_self_path'
346
350
  require_relative 'rubocop/cop/lint/rescue_exception'
347
351
  require_relative 'rubocop/cop/lint/rescue_type'
348
352
  require_relative 'rubocop/cop/lint/return_in_void_context'
@@ -509,6 +513,7 @@ require_relative 'rubocop/cop/style/line_end_concatenation'
509
513
  require_relative 'rubocop/cop/style/method_call_without_args_parentheses'
510
514
  require_relative 'rubocop/cop/style/method_call_with_args_parentheses'
511
515
  require_relative 'rubocop/cop/style/multiline_in_pattern_then'
516
+ require_relative 'rubocop/cop/style/numbered_parameters'
512
517
  require_relative 'rubocop/cop/style/redundant_assignment'
513
518
  require_relative 'rubocop/cop/style/redundant_fetch_block'
514
519
  require_relative 'rubocop/cop/style/redundant_file_extension_in_require'
@@ -545,6 +550,7 @@ require_relative 'rubocop/cop/style/nil_comparison'
545
550
  require_relative 'rubocop/cop/style/nil_lambda'
546
551
  require_relative 'rubocop/cop/style/non_nil_check'
547
552
  require_relative 'rubocop/cop/style/not'
553
+ require_relative 'rubocop/cop/style/numbered_parameters_limit'
548
554
  require_relative 'rubocop/cop/style/numeric_literals'
549
555
  require_relative 'rubocop/cop/style/numeric_literal_prefix'
550
556
  require_relative 'rubocop/cop/style/numeric_predicate'
@@ -585,6 +591,7 @@ require_relative 'rubocop/cop/style/rescue_standard_error'
585
591
  require_relative 'rubocop/cop/style/return_nil'
586
592
  require_relative 'rubocop/cop/style/safe_navigation'
587
593
  require_relative 'rubocop/cop/style/sample'
594
+ require_relative 'rubocop/cop/style/select_by_regexp'
588
595
  require_relative 'rubocop/cop/style/self_assignment'
589
596
  require_relative 'rubocop/cop/style/semicolon'
590
597
  require_relative 'rubocop/cop/style/send'
@@ -632,6 +639,7 @@ require_relative 'rubocop/cop/style/yoda_condition'
632
639
  require_relative 'rubocop/cop/style/zero_length_predicate'
633
640
 
634
641
  require_relative 'rubocop/cop/security/eval'
642
+ require_relative 'rubocop/cop/security/io_methods'
635
643
  require_relative 'rubocop/cop/security/json_load'
636
644
  require_relative 'rubocop/cop/security/marshal_load'
637
645
  require_relative 'rubocop/cop/security/open'