rubocop 1.39.0 → 1.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +91 -10
  5. data/exe/rubocop +1 -1
  6. data/lib/rubocop/cli.rb +1 -1
  7. data/lib/rubocop/comment_config.rb +5 -0
  8. data/lib/rubocop/config.rb +39 -15
  9. data/lib/rubocop/config_loader.rb +14 -5
  10. data/lib/rubocop/config_loader_resolver.rb +6 -2
  11. data/lib/rubocop/config_validator.rb +1 -1
  12. data/lib/rubocop/cop/badge.rb +9 -4
  13. data/lib/rubocop/cop/base.rb +84 -74
  14. data/lib/rubocop/cop/commissioner.rb +8 -3
  15. data/lib/rubocop/cop/cop.rb +29 -29
  16. data/lib/rubocop/cop/corrector.rb +23 -11
  17. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +22 -6
  18. data/lib/rubocop/cop/gemspec/dependency_version.rb +16 -18
  19. data/lib/rubocop/cop/internal_affairs/cop_description.rb +3 -1
  20. data/lib/rubocop/cop/internal_affairs/lambda_or_proc.rb +46 -0
  21. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  22. data/lib/rubocop/cop/layout/class_structure.rb +32 -11
  23. data/lib/rubocop/cop/layout/comment_indentation.rb +3 -1
  24. data/lib/rubocop/cop/layout/empty_lines.rb +2 -0
  25. data/lib/rubocop/cop/layout/extra_spacing.rb +10 -6
  26. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +38 -2
  27. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +49 -2
  28. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +61 -2
  29. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +52 -2
  30. data/lib/rubocop/cop/layout/indentation_style.rb +7 -2
  31. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +5 -0
  32. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +11 -5
  33. data/lib/rubocop/cop/layout/line_length.rb +2 -0
  34. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +51 -2
  35. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
  36. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +49 -2
  37. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +53 -2
  38. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +58 -2
  39. data/lib/rubocop/cop/layout/redundant_line_break.rb +2 -2
  40. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  41. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +1 -1
  42. data/lib/rubocop/cop/layout/trailing_whitespace.rb +11 -4
  43. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  44. data/lib/rubocop/cop/lint/assignment_in_condition.rb +11 -1
  45. data/lib/rubocop/cop/lint/constant_resolution.rb +4 -0
  46. data/lib/rubocop/cop/lint/debugger.rb +3 -1
  47. data/lib/rubocop/cop/lint/deprecated_constants.rb +8 -1
  48. data/lib/rubocop/cop/lint/duplicate_branch.rb +0 -2
  49. data/lib/rubocop/cop/lint/duplicate_methods.rb +19 -8
  50. data/lib/rubocop/cop/lint/empty_block.rb +1 -5
  51. data/lib/rubocop/cop/lint/empty_conditional_body.rb +1 -1
  52. data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
  53. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -5
  54. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +19 -0
  55. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -0
  56. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +15 -3
  57. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  58. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
  59. data/lib/rubocop/cop/lint/require_parentheses.rb +3 -1
  60. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +10 -12
  61. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +5 -4
  62. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +4 -3
  63. data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -1
  64. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -3
  65. data/lib/rubocop/cop/lint/void.rb +6 -6
  66. data/lib/rubocop/cop/metrics/block_length.rb +9 -4
  67. data/lib/rubocop/cop/metrics/class_length.rb +10 -5
  68. data/lib/rubocop/cop/metrics/method_length.rb +9 -4
  69. data/lib/rubocop/cop/metrics/module_length.rb +10 -5
  70. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  71. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -4
  72. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +6 -3
  73. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  74. data/lib/rubocop/cop/mixin/allowed_identifiers.rb +2 -2
  75. data/lib/rubocop/cop/mixin/annotation_comment.rb +13 -6
  76. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +21 -9
  77. data/lib/rubocop/cop/mixin/first_element_line_break.rb +11 -7
  78. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +28 -5
  79. data/lib/rubocop/cop/mixin/line_length_help.rb +8 -1
  80. data/lib/rubocop/cop/mixin/method_complexity.rb +5 -3
  81. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +5 -3
  82. data/lib/rubocop/cop/mixin/percent_array.rb +3 -5
  83. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
  84. data/lib/rubocop/cop/mixin/require_library.rb +2 -0
  85. data/lib/rubocop/cop/mixin/rescue_node.rb +3 -3
  86. data/lib/rubocop/cop/mixin/statement_modifier.rb +15 -1
  87. data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
  88. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +2 -0
  89. data/lib/rubocop/cop/naming/inclusive_language.rb +4 -1
  90. data/lib/rubocop/cop/registry.rb +51 -36
  91. data/lib/rubocop/cop/security/compound_hash.rb +2 -1
  92. data/lib/rubocop/cop/style/alias.rb +9 -1
  93. data/lib/rubocop/cop/style/array_intersect.rb +111 -0
  94. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  95. data/lib/rubocop/cop/style/concat_array_literals.rb +86 -0
  96. data/lib/rubocop/cop/style/documentation.rb +11 -5
  97. data/lib/rubocop/cop/style/guard_clause.rb +44 -9
  98. data/lib/rubocop/cop/style/hash_syntax.rb +10 -7
  99. data/lib/rubocop/cop/style/identical_conditional_branches.rb +15 -0
  100. data/lib/rubocop/cop/style/if_with_semicolon.rb +4 -4
  101. data/lib/rubocop/cop/style/inverse_methods.rb +2 -0
  102. data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -1
  103. data/lib/rubocop/cop/style/map_to_set.rb +61 -0
  104. data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -4
  105. data/lib/rubocop/cop/style/min_max_comparison.rb +73 -0
  106. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  107. data/lib/rubocop/cop/style/redundant_argument.rb +3 -0
  108. data/lib/rubocop/cop/style/redundant_constant_base.rb +85 -0
  109. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +39 -0
  110. data/lib/rubocop/cop/style/redundant_return.rb +7 -0
  111. data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
  112. data/lib/rubocop/cop/style/redundant_string_escape.rb +6 -3
  113. data/lib/rubocop/cop/style/require_order.rb +142 -0
  114. data/lib/rubocop/cop/style/safe_navigation.rb +35 -6
  115. data/lib/rubocop/cop/style/select_by_regexp.rb +13 -5
  116. data/lib/rubocop/cop/style/semicolon.rb +2 -1
  117. data/lib/rubocop/cop/style/signal_exception.rb +8 -6
  118. data/lib/rubocop/cop/style/string_literals.rb +1 -5
  119. data/lib/rubocop/cop/style/symbol_proc.rb +2 -4
  120. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -4
  121. data/lib/rubocop/cop/style/word_array.rb +41 -0
  122. data/lib/rubocop/cop/style/yoda_expression.rb +74 -0
  123. data/lib/rubocop/cop/style/zero_length_predicate.rb +31 -14
  124. data/lib/rubocop/cop/team.rb +30 -30
  125. data/lib/rubocop/cop/util.rb +32 -5
  126. data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
  127. data/lib/rubocop/cop/variable_force.rb +17 -29
  128. data/lib/rubocop/cops_documentation_generator.rb +33 -11
  129. data/lib/rubocop/directive_comment.rb +1 -1
  130. data/lib/rubocop/file_patterns.rb +43 -0
  131. data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
  132. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  133. data/lib/rubocop/formatter.rb +5 -1
  134. data/lib/rubocop/options.rb +8 -0
  135. data/lib/rubocop/path_util.rb +39 -16
  136. data/lib/rubocop/result_cache.rb +2 -2
  137. data/lib/rubocop/rspec/cop_helper.rb +4 -1
  138. data/lib/rubocop/rspec/support.rb +2 -2
  139. data/lib/rubocop/runner.rb +10 -3
  140. data/lib/rubocop/server/core.rb +1 -1
  141. data/lib/rubocop/target_finder.rb +1 -1
  142. data/lib/rubocop/target_ruby.rb +1 -2
  143. data/lib/rubocop/version.rb +1 -1
  144. data/lib/rubocop.rb +19 -6
  145. metadata +19 -9
@@ -108,34 +108,23 @@ module RuboCop
108
108
  :skip_children
109
109
  end
110
110
 
111
- # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
111
+ NODE_HANDLER_METHOD_NAMES = [
112
+ [VARIABLE_ASSIGNMENT_TYPE, :process_variable_assignment],
113
+ [REGEXP_NAMED_CAPTURE_TYPE, :process_regexp_named_captures],
114
+ [MULTIPLE_ASSIGNMENT_TYPE, :process_variable_multiple_assignment],
115
+ [VARIABLE_REFERENCE_TYPE, :process_variable_referencing],
116
+ [RESCUE_TYPE, :process_rescue],
117
+ [ZERO_ARITY_SUPER_TYPE, :process_zero_arity_super],
118
+ [SEND_TYPE, :process_send],
119
+ *ARGUMENT_DECLARATION_TYPES.product([:process_variable_declaration]),
120
+ *OPERATOR_ASSIGNMENT_TYPES.product([:process_variable_operator_assignment]),
121
+ *LOOP_TYPES.product([:process_loop]),
122
+ *SCOPE_TYPES.product([:process_scope])
123
+ ].to_h.freeze
124
+ private_constant :NODE_HANDLER_METHOD_NAMES
112
125
  def node_handler_method_name(node)
113
- case node.type
114
- when VARIABLE_ASSIGNMENT_TYPE
115
- :process_variable_assignment
116
- when REGEXP_NAMED_CAPTURE_TYPE
117
- :process_regexp_named_captures
118
- when MULTIPLE_ASSIGNMENT_TYPE
119
- :process_variable_multiple_assignment
120
- when VARIABLE_REFERENCE_TYPE
121
- :process_variable_referencing
122
- when RESCUE_TYPE
123
- :process_rescue
124
- when ZERO_ARITY_SUPER_TYPE
125
- :process_zero_arity_super
126
- when SEND_TYPE
127
- :process_send
128
- when *ARGUMENT_DECLARATION_TYPES
129
- :process_variable_declaration
130
- when *OPERATOR_ASSIGNMENT_TYPES
131
- :process_variable_operator_assignment
132
- when *LOOP_TYPES
133
- :process_loop
134
- when *SCOPE_TYPES
135
- :process_scope
136
- end
126
+ NODE_HANDLER_METHOD_NAMES[node.type]
137
127
  end
138
- # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
139
128
 
140
129
  def process_variable_declaration(node)
141
130
  variable_name = node.children.first
@@ -358,13 +347,12 @@ module RuboCop
358
347
  end
359
348
  end
360
349
 
361
- # Use Node#equal? for accurate check.
362
350
  def scanned_node?(node)
363
- scanned_nodes.any? { |scanned_node| scanned_node.equal?(node) }
351
+ scanned_nodes.include?(node)
364
352
  end
365
353
 
366
354
  def scanned_nodes
367
- @scanned_nodes ||= []
355
+ @scanned_nodes ||= Set.new.compare_by_identity
368
356
  end
369
357
 
370
358
  # Hooks invoked by VariableTable.
@@ -33,7 +33,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
33
33
  cops.with_department(department).sort!
34
34
  end
35
35
 
36
- def cops_body(cop, description, examples_objects, safety_objects, pars) # rubocop:disable Metrics/AbcSize
36
+ def cops_body(cop, description, examples_objects, safety_objects, see_objects, pars) # rubocop:disable Metrics/AbcSize, Metrics/ParameterLists
37
37
  check_examples_to_have_the_default_enforced_style!(examples_objects, cop)
38
38
 
39
39
  content = h2(cop.cop_name)
@@ -42,8 +42,8 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
42
42
  content << "#{description}\n"
43
43
  content << safety_object(safety_objects) if safety_objects.any? { |s| !s.text.blank? }
44
44
  content << examples(examples_objects) if examples_objects.any?
45
- content << configurations(pars)
46
- content << references(cop)
45
+ content << configurations(cop.department, pars)
46
+ content << references(cop, see_objects)
47
47
  content
48
48
  end
49
49
 
@@ -136,7 +136,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
136
136
  content
137
137
  end
138
138
 
139
- def configurations(pars)
139
+ def configurations(department, pars)
140
140
  return '' if pars.empty?
141
141
 
142
142
  header = ['Name', 'Default value', 'Configurable values']
@@ -147,12 +147,20 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
147
147
  content = configs.map do |name|
148
148
  configurable = configurable_values(pars, name)
149
149
  default = format_table_value(pars[name])
150
- [name, default, configurable]
150
+
151
+ [configuration_name(department, name), default, configurable]
151
152
  end
152
153
 
153
154
  h3('Configurable attributes') + to_table(header, content)
154
155
  end
155
156
 
157
+ def configuration_name(department, name)
158
+ return name unless name == 'AllowMultilineFinalElement'
159
+
160
+ filename = "#{department_to_basename(department)}.adoc"
161
+ "xref:#{filename}#allowmultilinefinalelement[AllowMultilineFinalElement]"
162
+ end
163
+
156
164
  # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
157
165
  def configurable_values(pars, name)
158
166
  case name
@@ -216,21 +224,34 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
216
224
  end
217
225
  end
218
226
 
219
- def references(cop)
227
+ def references(cop, see_objects) # rubocop:disable Metrics/AbcSize
220
228
  cop_config = config.for_cop(cop)
221
229
  urls = RuboCop::Cop::MessageAnnotator.new(config, cop.name, cop_config, {}).urls
222
- return '' if urls.empty?
230
+ return '' if urls.empty? && see_objects.empty?
223
231
 
224
232
  content = h3('References')
225
233
  content << urls.map { |url| "* #{url}" }.join("\n")
226
- content << "\n"
234
+ content << "\n" unless urls.empty?
235
+ content << see_objects.map { |see| "* #{see.name}" }.join("\n")
236
+ content << "\n" unless see_objects.empty?
227
237
  content
228
238
  end
229
239
 
240
+ def footer_for_department(department)
241
+ return '' unless department == :Layout
242
+
243
+ filename = "#{department_to_basename(department)}_footer.adoc"
244
+ file = "#{Dir.pwd}/docs/modules/ROOT/partials/#{filename}"
245
+ return '' unless File.exist?(file)
246
+
247
+ "\ninclude::../partials/#{filename}[]\n"
248
+ end
249
+
230
250
  def print_cops_of_department(department)
231
251
  selected_cops = cops_of_department(department)
232
252
  content = +"= #{department}\n"
233
253
  selected_cops.each { |cop| content << print_cop_with_doc(cop) }
254
+ content << footer_for_department(department)
234
255
  file_name = "#{Dir.pwd}/docs/modules/ROOT/pages/#{department_to_basename(department)}.adoc"
235
256
  File.open(file_name, 'w') do |file|
236
257
  puts "* generated #{file_name}"
@@ -238,7 +259,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
238
259
  end
239
260
  end
240
261
 
241
- def print_cop_with_doc(cop)
262
+ def print_cop_with_doc(cop) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
242
263
  cop_config = config.for_cop(cop)
243
264
  non_display_keys = %w[
244
265
  Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded
@@ -246,13 +267,14 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
246
267
  ]
247
268
  pars = cop_config.reject { |k| non_display_keys.include? k }
248
269
  description = 'No documentation'
249
- examples_object = safety_object = []
270
+ examples_object = safety_object = see_object = []
250
271
  cop_code(cop) do |code_object|
251
272
  description = code_object.docstring unless code_object.docstring.blank?
252
273
  examples_object = code_object.tags('example')
253
274
  safety_object = code_object.tags('safety')
275
+ see_object = code_object.tags('see')
254
276
  end
255
- cops_body(cop, description, examples_object, safety_object, pars)
277
+ cops_body(cop, description, examples_object, safety_object, see_object, pars)
256
278
  end
257
279
 
258
280
  def cop_code(cop)
@@ -35,7 +35,7 @@ module RuboCop
35
35
 
36
36
  # Checks if this directive relates to single line
37
37
  def single_line?
38
- !self.class.before_comment(comment.text).empty?
38
+ !comment.text.start_with?(DIRECTIVE_COMMENT_REGEXP)
39
39
  end
40
40
 
41
41
  # Checks if this directive contains all the given cop names
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ # A wrapper around patterns array to perform optimized search.
5
+ #
6
+ # For projects with a large set of rubocop todo files, most items in `Exclude`/`Include`
7
+ # are exact file names. It is wasteful to linearly check the list of patterns over and over
8
+ # to check if the file is relevant to the cop.
9
+ #
10
+ # This class partitions an array of patterns into a set of exact match strings and the rest
11
+ # of the patterns. This way we can firstly do a cheap check in the set and then proceed via
12
+ # the costly patterns check, if needed.
13
+ # @api private
14
+ class FilePatterns
15
+ @cache = {}.compare_by_identity
16
+
17
+ def self.from(patterns)
18
+ @cache[patterns] ||= new(patterns)
19
+ end
20
+
21
+ def initialize(patterns)
22
+ @strings = Set.new
23
+ @patterns = []
24
+ partition_patterns(patterns)
25
+ end
26
+
27
+ def match?(path)
28
+ @strings.include?(path) || @patterns.any? { |pattern| PathUtil.match_path?(pattern, path) }
29
+ end
30
+
31
+ private
32
+
33
+ def partition_patterns(patterns)
34
+ patterns.each do |pattern|
35
+ if pattern.is_a?(String) && !pattern.match?(/[*{\[?]/)
36
+ @strings << pattern
37
+ else
38
+ @patterns << pattern
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -65,6 +65,10 @@ module RuboCop
65
65
  @options.fetch(:offense_counts, true)
66
66
  end
67
67
 
68
+ def auto_gen_enforced_style?
69
+ @options.fetch(:auto_gen_enforced_style, true)
70
+ end
71
+
68
72
  def command
69
73
  command = 'rubocop --auto-gen-config'
70
74
 
@@ -79,6 +83,8 @@ module RuboCop
79
83
 
80
84
  command += ' --no-auto-gen-timestamp' unless show_timestamp?
81
85
 
86
+ command += ' --no-auto-gen-enforced-style' unless auto_gen_enforced_style?
87
+
82
88
  command
83
89
  end
84
90
 
@@ -172,17 +178,22 @@ module RuboCop
172
178
  end
173
179
 
174
180
  def output_cop_config(output_buffer, cfg, cop_name)
175
- # 'Enabled' option will be put into file only if exclude
176
- # limit is exceeded.
177
- cfg_without_enabled = cfg.reject { |key| key == 'Enabled' }
178
-
181
+ filtered_cfg = filtered_config(cfg)
179
182
  output_buffer.puts "#{cop_name}:"
180
- cfg_without_enabled.each do |key, value|
183
+ filtered_cfg.each do |key, value|
181
184
  value = value[0] if value.is_a?(Array)
182
185
  output_buffer.puts " #{key}: #{value}"
183
186
  end
184
187
 
185
- output_offending_files(output_buffer, cfg_without_enabled, cop_name)
188
+ output_offending_files(output_buffer, filtered_cfg, cop_name)
189
+ end
190
+
191
+ def filtered_config(cfg)
192
+ # 'Enabled' option will be put into file only if exclude
193
+ # limit is exceeded.
194
+ rejected_keys = ['Enabled']
195
+ rejected_keys << 'EnforcedStyle' unless auto_gen_enforced_style?
196
+ cfg.reject { |key| rejected_keys.include?(key) }
186
197
  end
187
198
 
188
199
  def output_offending_files(output_buffer, cfg, cop_name)
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'base64'
3
4
  require 'cgi'
4
5
  require 'erb'
5
6
  require 'ostruct'
6
- require 'base64'
7
7
 
8
8
  module RuboCop
9
9
  module Formatter
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RuboCop
4
+ # The bootstrap module for formatter.
5
+ # @api private
4
6
  module Formatter
5
7
  require_relative 'formatter/text_util'
6
8
 
7
9
  require_relative 'formatter/base_formatter'
8
10
  require_relative 'formatter/simple_text_formatter'
11
+
9
12
  # relies on simple text
10
13
  require_relative 'formatter/clang_style_formatter'
11
14
  require_relative 'formatter/disabled_config_formatter'
@@ -18,11 +21,12 @@ module RuboCop
18
21
  require_relative 'formatter/junit_formatter'
19
22
  require_relative 'formatter/markdown_formatter'
20
23
  require_relative 'formatter/offense_count_formatter'
24
+ require_relative 'formatter/pacman_formatter'
21
25
  require_relative 'formatter/progress_formatter'
22
26
  require_relative 'formatter/quiet_formatter'
23
27
  require_relative 'formatter/tap_formatter'
24
28
  require_relative 'formatter/worst_offenders_formatter'
25
- require_relative 'formatter/pacman_formatter'
29
+
26
30
  # relies on progress formatter
27
31
  require_relative 'formatter/auto_gen_config_formatter'
28
32
 
@@ -167,6 +167,7 @@ module RuboCop
167
167
  option(opts, '--[no-]offense-counts')
168
168
  option(opts, '--[no-]auto-gen-only-exclude')
169
169
  option(opts, '--[no-]auto-gen-timestamp')
170
+ option(opts, '--[no-]auto-gen-enforced-style')
170
171
  end
171
172
  end
172
173
 
@@ -486,6 +487,13 @@ module RuboCop
486
487
  auto_gen_timestamp:
487
488
  ['Include the date and time when the --auto-gen-config',
488
489
  'was run in the file it generates. Default is true.'],
490
+ auto_gen_enforced_style:
491
+ ['Add a setting to the TODO configuration file to enforce',
492
+ 'the style used, rather than a per-file exclusion',
493
+ 'if one style is used in all files for cop with',
494
+ 'EnforcedStyle as a configurable option',
495
+ 'when the --auto-gen-config was run',
496
+ 'in the file it generates. Default is true.'],
489
497
  auto_gen_only_exclude:
490
498
  ['Generate only Exclude parameters and not Max',
491
499
  'when running --auto-gen-config, except if the',
@@ -3,23 +3,29 @@
3
3
  module RuboCop
4
4
  # Common methods and behaviors for dealing with paths.
5
5
  module PathUtil
6
+ class << self
7
+ attr_accessor :relative_paths_cache
8
+ end
9
+ self.relative_paths_cache = Hash.new { |hash, key| hash[key] = {} }
10
+
6
11
  module_function
7
12
 
8
13
  def relative_path(path, base_dir = Dir.pwd)
9
- # Optimization for the common case where path begins with the base
10
- # dir. Just cut off the first part.
11
- if path.start_with?(base_dir)
12
- base_dir_length = base_dir.length
13
- result_length = path.length - base_dir_length - 1
14
- return path[base_dir_length + 1, result_length]
15
- end
16
-
17
- path_name = Pathname.new(File.expand_path(path))
18
- begin
19
- path_name.relative_path_from(Pathname.new(base_dir)).to_s
20
- rescue ArgumentError
21
- path
22
- end
14
+ PathUtil.relative_paths_cache[base_dir][path] ||=
15
+ # Optimization for the common case where path begins with the base
16
+ # dir. Just cut off the first part.
17
+ if path.start_with?(base_dir)
18
+ base_dir_length = base_dir.length
19
+ result_length = path.length - base_dir_length - 1
20
+ path[base_dir_length + 1, result_length]
21
+ else
22
+ path_name = Pathname.new(File.expand_path(path))
23
+ begin
24
+ path_name.relative_path_from(Pathname.new(base_dir)).to_s
25
+ rescue ArgumentError
26
+ path
27
+ end
28
+ end
23
29
  end
24
30
 
25
31
  def smart_path(path)
@@ -33,11 +39,18 @@ module RuboCop
33
39
  end
34
40
  end
35
41
 
42
+ # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
36
43
  def match_path?(pattern, path)
37
44
  case pattern
38
45
  when String
39
- File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_EXTGLOB) ||
40
- hidden_file_in_not_hidden_dir?(pattern, path)
46
+ matches =
47
+ if pattern == path
48
+ true
49
+ elsif glob?(pattern)
50
+ File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
51
+ end
52
+
53
+ matches || hidden_file_in_not_hidden_dir?(pattern, path)
41
54
  when Regexp
42
55
  begin
43
56
  pattern.match?(path)
@@ -48,12 +61,18 @@ module RuboCop
48
61
  end
49
62
  end
50
63
  end
64
+ # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
51
65
 
52
66
  # Returns true for an absolute Unix or Windows path.
53
67
  def absolute?(path)
54
68
  %r{\A([A-Z]:)?/}i.match?(path)
55
69
  end
56
70
 
71
+ # Returns true for a glob
72
+ def glob?(path)
73
+ path.match?(/[*{\[?]/)
74
+ end
75
+
57
76
  def hidden_file_in_not_hidden_dir?(pattern, path)
58
77
  hidden_file?(path) &&
59
78
  File.fnmatch?(
@@ -67,8 +86,12 @@ module RuboCop
67
86
  maybe_hidden_file?(path) && File.basename(path).start_with?('.')
68
87
  end
69
88
 
89
+ HIDDEN_FILE_PATTERN = "#{File::SEPARATOR}."
90
+
70
91
  # Loose check to reduce memory allocations
71
92
  def maybe_hidden_file?(path)
93
+ return false unless path.include?(HIDDEN_FILE_PATTERN)
94
+
72
95
  separator_index = path.rindex(File::SEPARATOR)
73
96
  return false unless separator_index
74
97
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'digest/sha1'
4
- require 'find'
5
4
  require 'etc'
5
+ require 'find'
6
6
  require 'zlib'
7
7
  require_relative 'cache_config'
8
8
 
@@ -53,7 +53,7 @@ module RuboCop
53
53
  def remove_oldest_files(files, dirs, cache_root, verbose)
54
54
  # Add 1 to half the number of files, so that we remove the file if
55
55
  # there's only 1 left.
56
- remove_count = 1 + (files.length / 2)
56
+ remove_count = (files.length / 2) + 1
57
57
  puts "Removing the #{remove_count} oldest files from #{cache_root}" if verbose
58
58
  sorted = files.sort_by { |path| File.mtime(path) }
59
59
  remove_files(sorted, dirs, remove_count)
@@ -44,7 +44,10 @@ module CopHelper
44
44
 
45
45
  def registry
46
46
  @registry ||= begin
47
- cops = configuration.keys.map { |cop| RuboCop::Cop::Registry.global.find_by_cop_name(cop) }
47
+ keys = configuration.keys
48
+ cops =
49
+ keys.map { |directive| RuboCop::Cop::Registry.global.find_cops_by_directive(directive) }
50
+ .flatten
48
51
  cops << cop_class if defined?(cop_class) && !cops.include?(cop_class)
49
52
  cops.compact!
50
53
  RuboCop::Cop::Registry.new(cops)
@@ -3,10 +3,10 @@
3
3
  # Require this file to load code that supports testing using RSpec.
4
4
 
5
5
  require_relative 'cop_helper'
6
- require_relative 'host_environment_simulation_helper'
7
- require_relative 'shared_contexts'
8
6
  require_relative 'expect_offense'
7
+ require_relative 'host_environment_simulation_helper'
9
8
  require_relative 'parallel_formatter'
9
+ require_relative 'shared_contexts'
10
10
 
11
11
  RSpec.configure do |config|
12
12
  config.include CopHelper
@@ -27,6 +27,11 @@ module RuboCop
27
27
  # @api private
28
28
  MAX_ITERATIONS = 200
29
29
 
30
+ # @api private
31
+ REDUNDANT_COP_DISABLE_DIRECTIVE_RULES = %w[
32
+ Lint/RedundantCopDisableDirective RedundantCopDisableDirective Lint
33
+ ].freeze
34
+
30
35
  attr_reader :errors, :warnings
31
36
  attr_writer :aborting
32
37
 
@@ -194,7 +199,9 @@ module RuboCop
194
199
  end
195
200
 
196
201
  def check_for_redundant_disables?(source)
197
- !source.disabled_line_ranges.empty? && !filtered_run?
202
+ return false if source.disabled_line_ranges.empty? || except_redundant_cop_disable_directive?
203
+
204
+ !@options[:only]
198
205
  end
199
206
 
200
207
  def redundant_cop_disable_directive(file)
@@ -205,8 +212,8 @@ module RuboCop
205
212
  yield cop if cop.relevant_file?(file)
206
213
  end
207
214
 
208
- def filtered_run?
209
- @options[:except] || @options[:only]
215
+ def except_redundant_cop_disable_directive?
216
+ @options[:except] && (@options[:except] & REDUNDANT_COP_DISABLE_DIRECTIVE_RULES).any?
210
217
  end
211
218
 
212
219
  def file_started(file)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'socket'
4
3
  require 'securerandom'
4
+ require 'socket'
5
5
 
6
6
  #
7
7
  # This code is based on https://github.com/fohte/rubocop-daemon.
@@ -88,7 +88,7 @@ module RuboCop
88
88
  patterns.map! { |dir| File.join(dir, '*') }
89
89
  # We need this special case to avoid creating the pattern
90
90
  # /**/* which searches the entire file system.
91
- patterns = [File.join(dir, '**/*')] if patterns.empty?
91
+ patterns = [File.join(base_dir, '**/*')] if patterns.empty?
92
92
 
93
93
  Dir.glob(patterns, flags).select { |path| FileTest.file?(path) }
94
94
  end
@@ -84,7 +84,7 @@ module RuboCop
84
84
  # @api private
85
85
  class ToolVersionsFile < RubyVersionFile
86
86
  TOOL_VERSIONS_FILENAME = '.tool-versions'
87
- TOOL_VERSIONS_PATTERN = /\Aruby (?:ruby-)?(?<version>\d+\.\d+)/.freeze
87
+ TOOL_VERSIONS_PATTERN = /^(?:ruby )(?<version>\d+\.\d+)/.freeze
88
88
 
89
89
  def name
90
90
  "`#{TOOL_VERSIONS_FILENAME}`"
@@ -244,7 +244,6 @@ module RuboCop
244
244
  ].freeze
245
245
 
246
246
  private_constant :SOURCES
247
-
248
247
  def initialize(config)
249
248
  @config = config
250
249
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.39.0'
6
+ STRING = '1.42.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
@@ -4,9 +4,9 @@ require 'English'
4
4
  before_us = $LOADED_FEATURES.dup
5
5
  require 'rainbow'
6
6
 
7
- require 'set'
8
7
  require 'forwardable'
9
8
  require 'regexp_parser'
9
+ require 'set'
10
10
  require 'unicode/display_width'
11
11
 
12
12
  # we have to require RuboCop's version, before rubocop-ast's
@@ -14,21 +14,24 @@ require_relative 'rubocop/version'
14
14
  require 'rubocop-ast'
15
15
 
16
16
  require_relative 'rubocop/ast_aliases'
17
+ require_relative 'rubocop/ext/range'
17
18
  require_relative 'rubocop/ext/regexp_node'
18
19
  require_relative 'rubocop/ext/regexp_parser'
19
- require_relative 'rubocop/ext/range'
20
20
 
21
21
  require_relative 'rubocop/core_ext/string'
22
22
  require_relative 'rubocop/ext/processed_source'
23
23
 
24
- require_relative 'rubocop/path_util'
24
+ require_relative 'rubocop/error'
25
25
  require_relative 'rubocop/file_finder'
26
- require_relative 'rubocop/platform'
26
+ require_relative 'rubocop/file_patterns'
27
27
  require_relative 'rubocop/name_similarity'
28
+ require_relative 'rubocop/path_util'
29
+ require_relative 'rubocop/platform'
28
30
  require_relative 'rubocop/string_interpreter'
29
- require_relative 'rubocop/error'
30
- require_relative 'rubocop/warning'
31
31
  require_relative 'rubocop/util'
32
+ require_relative 'rubocop/warning'
33
+
34
+ # rubocop:disable Style/RequireOrder
32
35
 
33
36
  require_relative 'rubocop/cop/util'
34
37
  require_relative 'rubocop/cop/offense'
@@ -440,6 +443,7 @@ require_relative 'rubocop/cop/style/alias'
440
443
  require_relative 'rubocop/cop/style/and_or'
441
444
  require_relative 'rubocop/cop/style/arguments_forwarding'
442
445
  require_relative 'rubocop/cop/style/array_coercion'
446
+ require_relative 'rubocop/cop/style/array_intersect'
443
447
  require_relative 'rubocop/cop/style/array_join'
444
448
  require_relative 'rubocop/cop/style/ascii_comments'
445
449
  require_relative 'rubocop/cop/style/attr'
@@ -466,6 +470,7 @@ require_relative 'rubocop/cop/style/combinable_loops'
466
470
  require_relative 'rubocop/cop/style/command_literal'
467
471
  require_relative 'rubocop/cop/style/comment_annotation'
468
472
  require_relative 'rubocop/cop/style/commented_keyword'
473
+ require_relative 'rubocop/cop/style/concat_array_literals'
469
474
  require_relative 'rubocop/cop/style/conditional_assignment'
470
475
  require_relative 'rubocop/cop/style/constant_visibility'
471
476
  require_relative 'rubocop/cop/style/copyright'
@@ -533,19 +538,24 @@ require_relative 'rubocop/cop/style/lambda_call'
533
538
  require_relative 'rubocop/cop/style/line_end_concatenation'
534
539
  require_relative 'rubocop/cop/style/magic_comment_format'
535
540
  require_relative 'rubocop/cop/style/map_to_hash'
541
+ require_relative 'rubocop/cop/style/map_to_set'
536
542
  require_relative 'rubocop/cop/style/method_call_without_args_parentheses'
537
543
  require_relative 'rubocop/cop/style/method_call_with_args_parentheses'
544
+ require_relative 'rubocop/cop/style/min_max_comparison'
538
545
  require_relative 'rubocop/cop/style/multiline_in_pattern_then'
539
546
  require_relative 'rubocop/cop/style/numbered_parameters'
540
547
  require_relative 'rubocop/cop/style/open_struct_use'
541
548
  require_relative 'rubocop/cop/style/operator_method_call'
542
549
  require_relative 'rubocop/cop/style/redundant_assignment'
550
+ require_relative 'rubocop/cop/style/redundant_constant_base'
551
+ require_relative 'rubocop/cop/style/redundant_double_splat_hash_braces'
543
552
  require_relative 'rubocop/cop/style/redundant_each'
544
553
  require_relative 'rubocop/cop/style/redundant_fetch_block'
545
554
  require_relative 'rubocop/cop/style/redundant_file_extension_in_require'
546
555
  require_relative 'rubocop/cop/style/redundant_initialize'
547
556
  require_relative 'rubocop/cop/style/redundant_self_assignment'
548
557
  require_relative 'rubocop/cop/style/redundant_self_assignment_branch'
558
+ require_relative 'rubocop/cop/style/require_order'
549
559
  require_relative 'rubocop/cop/style/sole_nested_conditional'
550
560
  require_relative 'rubocop/cop/style/static_class'
551
561
  require_relative 'rubocop/cop/style/map_compact_with_conditional_block'
@@ -667,6 +677,7 @@ require_relative 'rubocop/cop/style/while_until_do'
667
677
  require_relative 'rubocop/cop/style/while_until_modifier'
668
678
  require_relative 'rubocop/cop/style/word_array'
669
679
  require_relative 'rubocop/cop/style/yoda_condition'
680
+ require_relative 'rubocop/cop/style/yoda_expression'
670
681
  require_relative 'rubocop/cop/style/zero_length_predicate'
671
682
 
672
683
  require_relative 'rubocop/cop/security/compound_hash'
@@ -720,6 +731,8 @@ require_relative 'rubocop/remote_config'
720
731
  require_relative 'rubocop/target_ruby'
721
732
  require_relative 'rubocop/yaml_duplication_checker'
722
733
 
734
+ # rubocop:enable Style/RequireOrder
735
+
723
736
  unless File.exist?("#{__dir__}/../rubocop.gemspec") # Check if we are a gem
724
737
  RuboCop::ResultCache.rubocop_required_features = $LOADED_FEATURES - before_us
725
738
  end