rubocop 0.90.0 → 0.93.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +79 -3
  4. data/lib/rubocop.rb +20 -5
  5. data/lib/rubocop/cached_data.rb +2 -1
  6. data/lib/rubocop/cli/command/execute_runner.rb +8 -0
  7. data/lib/rubocop/comment_config.rb +9 -5
  8. data/lib/rubocop/config_loader.rb +3 -3
  9. data/lib/rubocop/config_regeneration.rb +33 -0
  10. data/lib/rubocop/config_store.rb +3 -3
  11. data/lib/rubocop/cop/bundler/duplicated_gem.rb +5 -1
  12. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -0
  13. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -0
  14. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -2
  15. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +10 -10
  16. data/lib/rubocop/cop/generator.rb +1 -1
  17. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +1 -0
  18. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -0
  19. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +1 -0
  20. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -0
  21. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -0
  22. data/lib/rubocop/cop/layout/array_alignment.rb +1 -0
  23. data/lib/rubocop/cop/layout/begin_end_alignment.rb +77 -0
  24. data/lib/rubocop/cop/layout/case_indentation.rb +4 -7
  25. data/lib/rubocop/cop/layout/class_structure.rb +1 -1
  26. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  27. data/lib/rubocop/cop/layout/dot_position.rb +6 -9
  28. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
  29. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +4 -12
  30. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +13 -8
  31. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -2
  32. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -2
  33. data/lib/rubocop/cop/layout/end_alignment.rb +5 -10
  34. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +26 -4
  35. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +4 -13
  36. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -7
  37. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +0 -4
  38. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +6 -21
  39. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +3 -8
  40. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +2 -2
  41. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -0
  42. data/lib/rubocop/cop/lint/ambiguous_operator.rb +2 -0
  43. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +18 -1
  44. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -2
  45. data/lib/rubocop/cop/lint/boolean_symbol.rb +3 -0
  46. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +74 -0
  47. data/lib/rubocop/cop/lint/debugger.rb +2 -3
  48. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -3
  49. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -4
  50. data/lib/rubocop/cop/lint/duplicate_require.rb +7 -2
  51. data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +2 -4
  52. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -0
  53. data/lib/rubocop/cop/lint/empty_file.rb +1 -4
  54. data/lib/rubocop/cop/lint/erb_new_arguments.rb +2 -0
  55. data/lib/rubocop/cop/lint/float_comparison.rb +2 -2
  56. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  57. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +37 -0
  58. data/lib/rubocop/cop/lint/identity_comparison.rb +51 -0
  59. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +2 -5
  60. data/lib/rubocop/cop/lint/inherit_exception.rb +2 -2
  61. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  62. data/lib/rubocop/cop/lint/multiple_comparison.rb +3 -1
  63. data/lib/rubocop/cop/lint/number_conversion.rb +1 -0
  64. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -2
  65. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  66. data/lib/rubocop/cop/lint/raise_exception.rb +1 -0
  67. data/lib/rubocop/cop/lint/rand_one.rb +2 -1
  68. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +22 -12
  69. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +14 -4
  70. data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -0
  71. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +78 -0
  72. data/lib/rubocop/cop/lint/rescue_type.rb +0 -1
  73. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +3 -1
  74. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -6
  75. data/lib/rubocop/cop/lint/struct_new_override.rb +1 -0
  76. data/lib/rubocop/cop/lint/to_json.rb +16 -5
  77. data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -6
  78. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +3 -1
  79. data/lib/rubocop/cop/lint/uri_regexp.rb +2 -1
  80. data/lib/rubocop/cop/lint/useless_access_modifier.rb +3 -9
  81. data/lib/rubocop/cop/lint/useless_method_definition.rb +20 -27
  82. data/lib/rubocop/cop/lint/useless_times.rb +106 -0
  83. data/lib/rubocop/cop/metrics/block_length.rb +3 -1
  84. data/lib/rubocop/cop/metrics/class_length.rb +14 -6
  85. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +25 -16
  86. data/lib/rubocop/cop/mixin/comments_help.rb +3 -9
  87. data/lib/rubocop/cop/mixin/configurable_naming.rb +2 -2
  88. data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
  89. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +9 -0
  90. data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -2
  91. data/lib/rubocop/cop/mixin/rescue_node.rb +1 -0
  92. data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -3
  93. data/lib/rubocop/cop/mixin/visibility_help.rb +4 -16
  94. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  95. data/lib/rubocop/cop/naming/file_name.rb +1 -1
  96. data/lib/rubocop/cop/offense.rb +15 -2
  97. data/lib/rubocop/cop/security/eval.rb +1 -0
  98. data/lib/rubocop/cop/security/json_load.rb +1 -0
  99. data/lib/rubocop/cop/security/marshal_load.rb +1 -0
  100. data/lib/rubocop/cop/security/open.rb +1 -0
  101. data/lib/rubocop/cop/security/yaml_load.rb +1 -0
  102. data/lib/rubocop/cop/style/access_modifier_declarations.rb +7 -11
  103. data/lib/rubocop/cop/style/accessor_grouping.rb +3 -0
  104. data/lib/rubocop/cop/style/alias.rb +2 -0
  105. data/lib/rubocop/cop/style/array_coercion.rb +4 -0
  106. data/lib/rubocop/cop/style/array_join.rb +1 -0
  107. data/lib/rubocop/cop/style/attr.rb +1 -0
  108. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +2 -0
  109. data/lib/rubocop/cop/style/case_equality.rb +3 -0
  110. data/lib/rubocop/cop/style/case_like_if.rb +20 -4
  111. data/lib/rubocop/cop/style/class_and_module_children.rb +2 -0
  112. data/lib/rubocop/cop/style/class_check.rb +6 -9
  113. data/lib/rubocop/cop/style/class_equality_comparison.rb +64 -0
  114. data/lib/rubocop/cop/style/class_methods_definitions.rb +42 -16
  115. data/lib/rubocop/cop/style/class_vars.rb +1 -2
  116. data/lib/rubocop/cop/style/combinable_loops.rb +13 -11
  117. data/lib/rubocop/cop/style/comment_annotation.rb +6 -0
  118. data/lib/rubocop/cop/style/commented_keyword.rb +7 -8
  119. data/lib/rubocop/cop/style/conditional_assignment.rb +49 -60
  120. data/lib/rubocop/cop/style/date_time.rb +12 -1
  121. data/lib/rubocop/cop/style/dir.rb +1 -0
  122. data/lib/rubocop/cop/style/double_negation.rb +1 -0
  123. data/lib/rubocop/cop/style/empty_literal.rb +3 -1
  124. data/lib/rubocop/cop/style/eval_with_location.rb +1 -3
  125. data/lib/rubocop/cop/style/even_odd.rb +1 -0
  126. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -2
  127. data/lib/rubocop/cop/style/explicit_block_argument.rb +7 -3
  128. data/lib/rubocop/cop/style/float_division.rb +2 -0
  129. data/lib/rubocop/cop/style/for.rb +0 -4
  130. data/lib/rubocop/cop/style/format_string.rb +1 -4
  131. data/lib/rubocop/cop/style/format_string_token.rb +1 -1
  132. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +24 -5
  133. data/lib/rubocop/cop/style/hash_transform_keys.rb +5 -11
  134. data/lib/rubocop/cop/style/hash_transform_values.rb +5 -11
  135. data/lib/rubocop/cop/style/if_unless_modifier.rb +0 -4
  136. data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -0
  137. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -6
  138. data/lib/rubocop/cop/style/lambda_call.rb +3 -1
  139. data/lib/rubocop/cop/style/method_def_parentheses.rb +0 -4
  140. data/lib/rubocop/cop/style/mixin_usage.rb +8 -27
  141. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -2
  142. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +14 -1
  143. data/lib/rubocop/cop/style/multiline_when_then.rb +1 -0
  144. data/lib/rubocop/cop/style/nested_ternary_operator.rb +2 -0
  145. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  146. data/lib/rubocop/cop/style/non_nil_check.rb +2 -0
  147. data/lib/rubocop/cop/style/not.rb +1 -0
  148. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -3
  149. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -1
  150. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +12 -1
  151. data/lib/rubocop/cop/style/preferred_hash_methods.rb +2 -0
  152. data/lib/rubocop/cop/style/raise_args.rb +2 -3
  153. data/lib/rubocop/cop/style/random_with_offset.rb +4 -3
  154. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -9
  155. data/lib/rubocop/cop/style/redundant_begin.rb +36 -8
  156. data/lib/rubocop/cop/style/redundant_condition.rb +5 -1
  157. data/lib/rubocop/cop/style/redundant_conditional.rb +4 -5
  158. data/lib/rubocop/cop/style/redundant_exception.rb +1 -3
  159. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -0
  160. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -1
  161. data/lib/rubocop/cop/style/redundant_interpolation.rb +6 -1
  162. data/lib/rubocop/cop/style/redundant_parentheses.rb +14 -6
  163. data/lib/rubocop/cop/style/redundant_percent_q.rb +9 -11
  164. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +39 -24
  165. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -15
  166. data/lib/rubocop/cop/style/redundant_return.rb +17 -17
  167. data/lib/rubocop/cop/style/redundant_self.rb +7 -9
  168. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -2
  169. data/lib/rubocop/cop/style/redundant_sort.rb +12 -29
  170. data/lib/rubocop/cop/style/redundant_sort_by.rb +5 -9
  171. data/lib/rubocop/cop/style/rescue_standard_error.rb +20 -16
  172. data/lib/rubocop/cop/style/safe_navigation.rb +5 -0
  173. data/lib/rubocop/cop/style/sample.rb +2 -1
  174. data/lib/rubocop/cop/style/send.rb +2 -3
  175. data/lib/rubocop/cop/style/signal_exception.rb +2 -0
  176. data/lib/rubocop/cop/style/single_argument_dig.rb +1 -0
  177. data/lib/rubocop/cop/style/slicing_with_range.rb +2 -1
  178. data/lib/rubocop/cop/style/stderr_puts.rb +1 -0
  179. data/lib/rubocop/cop/style/string_concatenation.rb +17 -3
  180. data/lib/rubocop/cop/style/strip.rb +1 -0
  181. data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -3
  182. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +4 -3
  183. data/lib/rubocop/cop/style/unpack_first.rb +1 -0
  184. data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -5
  185. data/lib/rubocop/cop/util.rb +0 -1
  186. data/lib/rubocop/cop/variable_force/branch.rb +0 -4
  187. data/lib/rubocop/core_ext/string.rb +1 -1
  188. data/lib/rubocop/directive_comment.rb +32 -0
  189. data/lib/rubocop/ext/regexp_node.rb +23 -7
  190. data/lib/rubocop/formatter/disabled_config_formatter.rb +12 -5
  191. data/lib/rubocop/options.rb +37 -17
  192. data/lib/rubocop/result_cache.rb +38 -15
  193. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  194. data/lib/rubocop/rspec/expect_offense.rb +5 -5
  195. data/lib/rubocop/runner.rb +37 -18
  196. data/lib/rubocop/target_finder.rb +27 -26
  197. data/lib/rubocop/target_ruby.rb +1 -1
  198. data/lib/rubocop/version.rb +6 -1
  199. metadata +19 -18
  200. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +0 -43
  201. data/lib/rubocop/cop/tokens_util.rb +0 -84
@@ -3,6 +3,7 @@
3
3
  require 'digest/sha1'
4
4
  require 'find'
5
5
  require 'etc'
6
+ require 'zlib'
6
7
 
7
8
  module RuboCop
8
9
  # Provides functionality for caching rubocop runs.
@@ -30,6 +31,11 @@ module RuboCop
30
31
  end
31
32
 
32
33
  class << self
34
+ # @api private
35
+ attr_accessor :rubocop_required_features
36
+
37
+ ResultCache.rubocop_required_features = []
38
+
33
39
  private
34
40
 
35
41
  def requires_file_removal?(file_count, config_store)
@@ -61,7 +67,8 @@ module RuboCop
61
67
  end
62
68
 
63
69
  def self.cache_root(config_store)
64
- root = config_store.for_pwd.for_all_cops['CacheRootDirectory']
70
+ root = ENV['RUBOCOP_CACHE_ROOT']
71
+ root ||= config_store.for_pwd.for_all_cops['CacheRootDirectory']
65
72
  root ||= if ENV.key?('XDG_CACHE_HOME')
66
73
  # Include user ID in the path to make sure the user has write
67
74
  # access.
@@ -76,7 +83,10 @@ module RuboCop
76
83
  config_store.for_pwd.for_all_cops['AllowSymlinksInCacheRootDirectory']
77
84
  end
78
85
 
86
+ attr :path
87
+
79
88
  def initialize(file, team, options, config_store, cache_root = nil)
89
+ cache_root ||= options[:cache_root]
80
90
  cache_root ||= ResultCache.cache_root(config_store)
81
91
  @allow_symlinks_in_cache_location =
82
92
  ResultCache.allow_symlinks_in_cache_location?(config_store)
@@ -85,6 +95,11 @@ module RuboCop
85
95
  context_checksum(team, options),
86
96
  file_checksum(file, config_store))
87
97
  @cached_data = CachedData.new(file)
98
+ @debug = options[:debug]
99
+ end
100
+
101
+ def debug?
102
+ @debug
88
103
  end
89
104
 
90
105
  def valid?
@@ -92,6 +107,7 @@ module RuboCop
92
107
  end
93
108
 
94
109
  def load
110
+ puts "Loading cache from #{@path}" if debug?
95
111
  @cached_data.from_json(IO.read(@path, encoding: Encoding::UTF_8))
96
112
  end
97
113
 
@@ -159,27 +175,34 @@ module RuboCop
159
175
  end
160
176
 
161
177
  # The checksum of the rubocop program running the inspection.
162
- # rubocop:disable Metrics/AbcSize
163
178
  def rubocop_checksum
164
179
  ResultCache.source_checksum ||=
165
180
  begin
166
- lib_root = File.join(File.dirname(__FILE__), '..')
167
- exe_root = File.join(lib_root, '..', 'exe')
168
-
169
- # These are all the files we have `require`d plus everything in the
170
- # exe directory. A change to any of them could affect the cop output
171
- # so we include them in the cache hash.
172
- source_files = $LOADED_FEATURES + Find.find(exe_root).to_a
173
-
174
181
  digest = Digest::SHA1.new
175
- source_files
182
+ rubocop_extra_features
176
183
  .select { |path| File.file?(path) }
177
184
  .sort!
178
- .each { |path| digest << File.mtime(path).to_s }
185
+ .each do |path|
186
+ content = File.open(path, 'rb', &:read)
187
+ digest << Zlib.crc32(content).to_s # mtime not reliable
188
+ end
189
+ digest << RuboCop::Version::STRING << RuboCop::AST::Version::STRING
179
190
  digest.hexdigest
180
191
  end
181
192
  end
182
- # rubocop:enable Metrics/AbcSize
193
+
194
+ def rubocop_extra_features
195
+ lib_root = File.join(File.dirname(__FILE__), '..')
196
+ exe_root = File.join(lib_root, '..', 'exe')
197
+
198
+ # These are all the files we have `require`d plus everything in the
199
+ # exe directory. A change to any of them could affect the cop output
200
+ # so we include them in the cache hash.
201
+ source_files = $LOADED_FEATURES + Find.find(exe_root).to_a
202
+ source_files -= ResultCache.rubocop_required_features # Rely on gem versions
203
+
204
+ source_files
205
+ end
183
206
 
184
207
  # Return a hash of the options given at invocation, minus the ones that have
185
208
  # no effect on which offenses and disabled line ranges are found, and thus
@@ -192,8 +215,8 @@ module RuboCop
192
215
  # The external dependency checksums are cached per RuboCop team so that
193
216
  # the checksums don't need to be recomputed for each file.
194
217
  def team_checksum(team)
195
- @checksum_by_team ||= {}
196
- @checksum_by_team[team.object_id] ||= team.external_dependency_checksum
218
+ @checksum_by_team ||= {}.compare_by_identity
219
+ @checksum_by_team[team] ||= team.external_dependency_checksum
197
220
  end
198
221
 
199
222
  # We combine team and options into a single "context" checksum to avoid
@@ -26,7 +26,7 @@ module CopHelper
26
26
  end
27
27
 
28
28
  def parse_source(source, file = nil)
29
- if file&.respond_to?(:write)
29
+ if file.respond_to?(:write)
30
30
  file.write(source)
31
31
  file.rewind
32
32
  file = file.path
@@ -133,14 +133,14 @@ module RuboCop
133
133
  "#{@processed_source.diagnostics.map(&:render).join("\n")}"
134
134
  end
135
135
 
136
- offenses = _investigate(cop, @processed_source)
136
+ @offenses = _investigate(cop, @processed_source)
137
137
  actual_annotations =
138
- expected_annotations.with_offense_annotations(offenses)
138
+ expected_annotations.with_offense_annotations(@offenses)
139
139
 
140
140
  expect(actual_annotations).to eq(expected_annotations), ''
141
- expect(offenses.map(&:severity).uniq).to eq([severity]) if severity
141
+ expect(@offenses.map(&:severity).uniq).to eq([severity]) if severity
142
142
 
143
- offenses
143
+ @offenses
144
144
  end
145
145
 
146
146
  def expect_correction(correction, loop: true)
@@ -157,7 +157,7 @@ module RuboCop
157
157
  break corrected_source if corrected_source == @processed_source.buffer.source
158
158
 
159
159
  if iteration > RuboCop::Runner::MAX_ITERATIONS
160
- raise RuboCop::Runner::InfiniteCorrectionLoop.new(@processed_source.path, [])
160
+ raise RuboCop::Runner::InfiniteCorrectionLoop.new(@processed_source.path, [@offenses])
161
161
  end
162
162
 
163
163
  # Prepare for next loop
@@ -11,9 +11,16 @@ module RuboCop
11
11
  class InfiniteCorrectionLoop < RuntimeError
12
12
  attr_reader :offenses
13
13
 
14
- def initialize(path, offenses)
15
- super "Infinite loop detected in #{path}."
16
- @offenses = offenses
14
+ def initialize(path, offenses_by_iteration, loop_start: -1)
15
+ @offenses = offenses_by_iteration.flatten.uniq
16
+ root_cause = offenses_by_iteration[loop_start..-1]
17
+ .map { |x| x.map(&:cop_name).uniq.join(', ') }
18
+ .join(' -> ')
19
+
20
+ message = 'Infinite loop detected'
21
+ message += " in #{path}" if path
22
+ message += " and caused by #{root_cause}" if root_cause
23
+ super message
17
24
  end
18
25
  end
19
26
 
@@ -81,7 +88,10 @@ module RuboCop
81
88
  # OPTIMIZE: Calling `ResultCache.cleanup` takes time. This optimization
82
89
  # mainly targets editors that integrates RuboCop. When RuboCop is run
83
90
  # by an editor, it should be inspecting only one file.
84
- ResultCache.cleanup(@config_store, @options[:debug]) if files.size > 1 && cached_run?
91
+ if files.size > 1 && cached_run?
92
+ ResultCache.cleanup(@config_store, @options[:debug], @options[:cache_root])
93
+ end
94
+
85
95
  formatter_set.finished(inspected_files.freeze)
86
96
  formatter_set.close_output_files
87
97
  end
@@ -233,18 +243,21 @@ module RuboCop
233
243
 
234
244
  def do_inspection_loop(file)
235
245
  processed_source = get_processed_source(file)
236
- offenses = []
246
+ # This variable is 2d array used to track corrected offenses after each
247
+ # inspection iteration. This is used to output meaningful infinite loop
248
+ # error message.
249
+ offenses_by_iteration = []
237
250
 
238
251
  # When running with --auto-correct, we need to inspect the file (which
239
252
  # includes writing a corrected version of it) until no more corrections
240
253
  # are made. This is because automatic corrections can introduce new
241
254
  # offenses. In the normal case the loop is only executed once.
242
- iterate_until_no_changes(processed_source, offenses) do
255
+ iterate_until_no_changes(processed_source, offenses_by_iteration) do
243
256
  # The offenses that couldn't be corrected will be found again so we
244
257
  # only keep the corrected ones in order to avoid duplicate reporting.
245
- offenses.select!(&:corrected?)
258
+ !offenses_by_iteration.empty? && offenses_by_iteration.last.select!(&:corrected?)
246
259
  new_offenses, updated_source_file = inspect_file(processed_source)
247
- offenses.concat(new_offenses).uniq!
260
+ offenses_by_iteration.push(new_offenses)
248
261
 
249
262
  # We have to reprocess the source to pickup the changes. Since the
250
263
  # change could (theoretically) introduce parsing errors, we break the
@@ -254,10 +267,12 @@ module RuboCop
254
267
  processed_source = get_processed_source(file)
255
268
  end
256
269
 
270
+ # Return summary of corrected offenses after all iterations
271
+ offenses = offenses_by_iteration.flatten.uniq
257
272
  [processed_source, offenses]
258
273
  end
259
274
 
260
- def iterate_until_no_changes(source, offenses)
275
+ def iterate_until_no_changes(source, offenses_by_iteration)
261
276
  # Keep track of the state of the source. If a cop modifies the source
262
277
  # and another cop undoes it producing identical source we have an
263
278
  # infinite loop.
@@ -269,10 +284,10 @@ module RuboCop
269
284
  iterations = 0
270
285
 
271
286
  loop do
272
- check_for_infinite_loop(source, offenses)
287
+ check_for_infinite_loop(source, offenses_by_iteration)
273
288
 
274
289
  if (iterations += 1) > MAX_ITERATIONS
275
- raise InfiniteCorrectionLoop.new(source.path, offenses)
290
+ raise InfiniteCorrectionLoop.new(source.path, offenses_by_iteration)
276
291
  end
277
292
 
278
293
  source = yield
@@ -282,11 +297,15 @@ module RuboCop
282
297
 
283
298
  # Check whether a run created source identical to a previous run, which
284
299
  # means that we definitely have an infinite loop.
285
- def check_for_infinite_loop(processed_source, offenses)
300
+ def check_for_infinite_loop(processed_source, offenses_by_iteration)
286
301
  checksum = processed_source.checksum
287
302
 
288
- if @processed_sources.include?(checksum)
289
- raise InfiniteCorrectionLoop.new(processed_source.path, offenses)
303
+ if (loop_start_index = @processed_sources.index(checksum))
304
+ raise InfiniteCorrectionLoop.new(
305
+ processed_source.path,
306
+ offenses_by_iteration,
307
+ loop_start: loop_start_index
308
+ )
290
309
  end
291
310
 
292
311
  @processed_sources << checksum
@@ -305,8 +324,8 @@ module RuboCop
305
324
  end
306
325
 
307
326
  def mobilized_cop_classes(config)
308
- @mobilized_cop_classes ||= {}
309
- @mobilized_cop_classes[config.object_id] ||= begin
327
+ @mobilized_cop_classes ||= {}.compare_by_identity
328
+ @mobilized_cop_classes[config] ||= begin
310
329
  cop_classes = Cop::Registry.all
311
330
 
312
331
  OptionsValidator.new(@options).validate_cop_options
@@ -380,8 +399,8 @@ module RuboCop
380
399
  # otherwise dormant team that can be used for config- and option-
381
400
  # level caching in ResultCache.
382
401
  def standby_team(config)
383
- @team_by_config ||= {}
384
- @team_by_config[config.object_id] ||=
402
+ @team_by_config ||= {}.compare_by_identity
403
+ @team_by_config[config] ||=
385
404
  Cop::Team.mobilize(mobilized_cop_classes(config), config, @options)
386
405
  end
387
406
  end
@@ -5,6 +5,8 @@ module RuboCop
5
5
  # and picking ruby files.
6
6
  # @api private
7
7
  class TargetFinder
8
+ HIDDEN_PATH_SUBSTRING = "#{File::SEPARATOR}."
9
+
8
10
  def initialize(config_store, options = {})
9
11
  @config_store = config_store
10
12
  @options = options
@@ -55,7 +57,8 @@ module RuboCop
55
57
  # Support Windows: Backslashes from command-line -> forward slashes
56
58
  base_dir = base_dir.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
57
59
  all_files = find_files(base_dir, File::FNM_DOTMATCH)
58
- hidden_files = Set.new(all_files - find_files(base_dir, 0))
60
+ # use file.include? for performance optimization
61
+ hidden_files = all_files.select { |file| file.include?(HIDDEN_PATH_SUBSTRING) }
59
62
  base_dir_config = @config_store.for(base_dir)
60
63
 
61
64
  target_files = all_files.select do |file|
@@ -78,34 +81,32 @@ module RuboCop
78
81
  # the top level directories that are excluded in configuration in the
79
82
  # normal way (dir/**/*).
80
83
  def find_files(base_dir, flags)
81
- wanted_toplevel_dirs = toplevel_dirs(base_dir, flags) -
82
- excluded_dirs(base_dir)
83
- wanted_toplevel_dirs.map! { |dir| dir << '/**/*' }
84
-
85
- pattern = if wanted_toplevel_dirs.empty?
86
- # We need this special case to avoid creating the pattern
87
- # /**/* which searches the entire file system.
88
- ["#{base_dir}/**/*"]
89
- else
90
- # Search the non-excluded top directories, but also add files
91
- # on the top level, which would otherwise not be found.
92
- wanted_toplevel_dirs.unshift("#{base_dir}/*")
84
+ # get all wanted directories first to improve speed of finding all files
85
+ exclude_pattern = combined_exclude_glob_patterns(base_dir)
86
+ dir_flags = flags | File::FNM_PATHNAME | File::FNM_EXTGLOB
87
+ patterns = wanted_dir_patterns(base_dir, exclude_pattern, dir_flags)
88
+ patterns.map! { |dir| File.join(dir, '*') }
89
+ # We need this special case to avoid creating the pattern
90
+ # /**/* which searches the entire file system.
91
+ patterns = [File.join(dir, '**/*')] if patterns.empty?
92
+
93
+ Dir.glob(patterns, flags).select { |path| FileTest.file?(path) }
94
+ end
95
+
96
+ def wanted_dir_patterns(base_dir, exclude_pattern, flags)
97
+ dirs = Dir.glob(File.join(base_dir, '*/'), flags)
98
+ .reject do |dir|
99
+ dir.end_with?('/./', '/../') || File.fnmatch?(exclude_pattern, dir, flags)
93
100
  end
94
- Dir.glob(pattern, flags).select { |path| FileTest.file?(path) }
101
+ dirs.flat_map { |dir| wanted_dir_patterns(dir, exclude_pattern, flags) }
102
+ .unshift(base_dir)
95
103
  end
96
104
 
97
- def toplevel_dirs(base_dir, flags)
98
- Dir.glob(File.join(base_dir, '*'), flags).select do |dir|
99
- File.directory?(dir) && !dir.end_with?('/.', '/..')
100
- end
101
- end
102
-
103
- def excluded_dirs(base_dir)
104
- all_cops_config = @config_store.for(base_dir).for_all_cops
105
- dir_tree_excludes = all_cops_config['Exclude'].select do |pattern|
106
- pattern.is_a?(String) && pattern.end_with?('/**/*')
107
- end
108
- dir_tree_excludes.map { |pattern| pattern.sub(%r{/\*\*/\*$}, '') }
105
+ def combined_exclude_glob_patterns(base_dir)
106
+ exclude = @config_store.for(base_dir).for_all_cops['Exclude']
107
+ patterns = exclude.select { |pattern| pattern.is_a?(String) && pattern.end_with?('/**/*') }
108
+ .map { |pattern| pattern.sub("#{base_dir}/", '') }
109
+ "#{base_dir}/{#{patterns.join(',')}}"
109
110
  end
110
111
 
111
112
  def ruby_extension?(file)
@@ -4,7 +4,7 @@ module RuboCop
4
4
  # The kind of Ruby that code inspected by RuboCop is written in.
5
5
  # @api private
6
6
  class TargetRuby
7
- KNOWN_RUBIES = [2.4, 2.5, 2.6, 2.7, 2.8].freeze
7
+ KNOWN_RUBIES = [2.4, 2.5, 2.6, 2.7, 3.0].freeze
8
8
  DEFAULT_VERSION = KNOWN_RUBIES.first
9
9
 
10
10
  OBSOLETE_RUBIES = {
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '0.90.0'
6
+ STRING = '0.93.1'
7
7
 
8
8
  MSG = '%<version>s (using Parser %<parser_version>s, '\
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
@@ -20,5 +20,10 @@ module RuboCop
20
20
  STRING
21
21
  end
22
22
  end
23
+
24
+ # @api private
25
+ def self.document_version
26
+ STRING.match('\d+\.\d+').to_s
27
+ end
23
28
  end
24
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.90.0
4
+ version: 0.93.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2020-09-01 00:00:00.000000000 Z
13
+ date: 2020-10-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: parallel
@@ -32,14 +32,14 @@ dependencies:
32
32
  requirements:
33
33
  - - ">="
34
34
  - !ruby/object:Gem::Version
35
- version: 2.7.1.1
35
+ version: 2.7.1.5
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: 2.7.1.1
42
+ version: 2.7.1.5
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: rainbow
45
45
  requirement: !ruby/object:Gem::Requirement
@@ -66,14 +66,14 @@ dependencies:
66
66
  requirements:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: '1.7'
69
+ version: '1.8'
70
70
  type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - ">="
75
75
  - !ruby/object:Gem::Version
76
- version: '1.7'
76
+ version: '1.8'
77
77
  - !ruby/object:Gem::Dependency
78
78
  name: rexml
79
79
  requirement: !ruby/object:Gem::Requirement
@@ -94,20 +94,14 @@ dependencies:
94
94
  requirements:
95
95
  - - ">="
96
96
  - !ruby/object:Gem::Version
97
- version: 0.3.0
98
- - - "<"
99
- - !ruby/object:Gem::Version
100
- version: '1.0'
97
+ version: 0.6.0
101
98
  type: :runtime
102
99
  prerelease: false
103
100
  version_requirements: !ruby/object:Gem::Requirement
104
101
  requirements:
105
102
  - - ">="
106
103
  - !ruby/object:Gem::Version
107
- version: 0.3.0
108
- - - "<"
109
- - !ruby/object:Gem::Version
110
- version: '1.0'
104
+ version: 0.6.0
111
105
  - !ruby/object:Gem::Dependency
112
106
  name: ruby-progressbar
113
107
  requirement: !ruby/object:Gem::Requirement
@@ -199,6 +193,7 @@ files:
199
193
  - lib/rubocop/config_loader.rb
200
194
  - lib/rubocop/config_loader_resolver.rb
201
195
  - lib/rubocop/config_obsoletion.rb
196
+ - lib/rubocop/config_regeneration.rb
202
197
  - lib/rubocop/config_store.rb
203
198
  - lib/rubocop/config_validator.rb
204
199
  - lib/rubocop/cop/autocorrect_logic.rb
@@ -248,6 +243,7 @@ files:
248
243
  - lib/rubocop/cop/layout/argument_alignment.rb
249
244
  - lib/rubocop/cop/layout/array_alignment.rb
250
245
  - lib/rubocop/cop/layout/assignment_indentation.rb
246
+ - lib/rubocop/cop/layout/begin_end_alignment.rb
251
247
  - lib/rubocop/cop/layout/block_alignment.rb
252
248
  - lib/rubocop/cop/layout/block_end_newline.rb
253
249
  - lib/rubocop/cop/layout/case_indentation.rb
@@ -345,6 +341,7 @@ files:
345
341
  - lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb
346
342
  - lib/rubocop/cop/lint/boolean_symbol.rb
347
343
  - lib/rubocop/cop/lint/circular_argument_reference.rb
344
+ - lib/rubocop/cop/lint/constant_definition_in_block.rb
348
345
  - lib/rubocop/cop/lint/constant_resolution.rb
349
346
  - lib/rubocop/cop/lint/debugger.rb
350
347
  - lib/rubocop/cop/lint/deprecated_class_methods.rb
@@ -370,7 +367,9 @@ files:
370
367
  - lib/rubocop/cop/lint/float_comparison.rb
371
368
  - lib/rubocop/cop/lint/float_out_of_range.rb
372
369
  - lib/rubocop/cop/lint/format_parameter_mismatch.rb
370
+ - lib/rubocop/cop/lint/hash_compare_by_identity.rb
373
371
  - lib/rubocop/cop/lint/heredoc_method_call_position.rb
372
+ - lib/rubocop/cop/lint/identity_comparison.rb
374
373
  - lib/rubocop/cop/lint/implicit_string_concatenation.rb
375
374
  - lib/rubocop/cop/lint/ineffective_access_modifier.rb
376
375
  - lib/rubocop/cop/lint/inherit_exception.rb
@@ -398,6 +397,7 @@ files:
398
397
  - lib/rubocop/cop/lint/redundant_cop_disable_directive.rb
399
398
  - lib/rubocop/cop/lint/redundant_cop_enable_directive.rb
400
399
  - lib/rubocop/cop/lint/redundant_require_statement.rb
400
+ - lib/rubocop/cop/lint/redundant_safe_navigation.rb
401
401
  - lib/rubocop/cop/lint/redundant_splat_expansion.rb
402
402
  - lib/rubocop/cop/lint/redundant_string_coercion.rb
403
403
  - lib/rubocop/cop/lint/redundant_with_index.rb
@@ -435,6 +435,7 @@ files:
435
435
  - lib/rubocop/cop/lint/useless_else_without_rescue.rb
436
436
  - lib/rubocop/cop/lint/useless_method_definition.rb
437
437
  - lib/rubocop/cop/lint/useless_setter_call.rb
438
+ - lib/rubocop/cop/lint/useless_times.rb
438
439
  - lib/rubocop/cop/lint/void.rb
439
440
  - lib/rubocop/cop/message_annotator.rb
440
441
  - lib/rubocop/cop/metrics/abc_size.rb
@@ -502,7 +503,6 @@ files:
502
503
  - lib/rubocop/cop/mixin/preferred_delimiters.rb
503
504
  - lib/rubocop/cop/mixin/range_help.rb
504
505
  - lib/rubocop/cop/mixin/rational_literal.rb
505
- - lib/rubocop/cop/mixin/regexp_literal_help.rb
506
506
  - lib/rubocop/cop/mixin/rescue_node.rb
507
507
  - lib/rubocop/cop/mixin/safe_assignment.rb
508
508
  - lib/rubocop/cop/mixin/space_after_punctuation.rb
@@ -560,6 +560,7 @@ files:
560
560
  - lib/rubocop/cop/style/character_literal.rb
561
561
  - lib/rubocop/cop/style/class_and_module_children.rb
562
562
  - lib/rubocop/cop/style/class_check.rb
563
+ - lib/rubocop/cop/style/class_equality_comparison.rb
563
564
  - lib/rubocop/cop/style/class_methods.rb
564
565
  - lib/rubocop/cop/style/class_methods_definitions.rb
565
566
  - lib/rubocop/cop/style/class_vars.rb
@@ -740,7 +741,6 @@ files:
740
741
  - lib/rubocop/cop/style/yoda_condition.rb
741
742
  - lib/rubocop/cop/style/zero_length_predicate.rb
742
743
  - lib/rubocop/cop/team.rb
743
- - lib/rubocop/cop/tokens_util.rb
744
744
  - lib/rubocop/cop/util.rb
745
745
  - lib/rubocop/cop/utils/format_string.rb
746
746
  - lib/rubocop/cop/variable_force.rb
@@ -753,6 +753,7 @@ files:
753
753
  - lib/rubocop/cop/variable_force/variable_table.rb
754
754
  - lib/rubocop/cops_documentation_generator.rb
755
755
  - lib/rubocop/core_ext/string.rb
756
+ - lib/rubocop/directive_comment.rb
756
757
  - lib/rubocop/error.rb
757
758
  - lib/rubocop/ext/processed_source.rb
758
759
  - lib/rubocop/ext/regexp_node.rb
@@ -804,7 +805,7 @@ metadata:
804
805
  homepage_uri: https://rubocop.org/
805
806
  changelog_uri: https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md
806
807
  source_code_uri: https://github.com/rubocop-hq/rubocop/
807
- documentation_uri: https://docs.rubocop.org/
808
+ documentation_uri: https://docs.rubocop.org/rubocop/0.93/
808
809
  bug_tracker_uri: https://github.com/rubocop-hq/rubocop/issues
809
810
  post_install_message:
810
811
  rdoc_options: []
@@ -821,7 +822,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
821
822
  - !ruby/object:Gem::Version
822
823
  version: '0'
823
824
  requirements: []
824
- rubygems_version: 3.1.2
825
+ rubygems_version: 3.1.4
825
826
  signing_key:
826
827
  specification_version: 4
827
828
  summary: Automatic Ruby code style checking tool.