rubocop 0.52.1 → 0.53.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 (292) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +118 -46
  5. data/config/disabled.yml +8 -8
  6. data/config/enabled.yml +84 -28
  7. data/lib/rubocop.rb +28 -8
  8. data/lib/rubocop/ast/builder.rb +35 -37
  9. data/lib/rubocop/ast/node.rb +16 -1
  10. data/lib/rubocop/ast/node/and_node.rb +0 -8
  11. data/lib/rubocop/ast/node/block_node.rb +1 -9
  12. data/lib/rubocop/ast/node/case_node.rb +0 -8
  13. data/lib/rubocop/ast/node/ensure_node.rb +0 -8
  14. data/lib/rubocop/ast/node/for_node.rb +0 -8
  15. data/lib/rubocop/ast/node/or_node.rb +0 -8
  16. data/lib/rubocop/ast/node/pair_node.rb +0 -8
  17. data/lib/rubocop/ast/node/resbody_node.rb +0 -8
  18. data/lib/rubocop/ast/node/send_node.rb +0 -8
  19. data/lib/rubocop/ast/node/symbol_node.rb +0 -8
  20. data/lib/rubocop/ast/node/until_node.rb +0 -8
  21. data/lib/rubocop/ast/node/when_node.rb +0 -8
  22. data/lib/rubocop/ast/node/while_node.rb +0 -8
  23. data/lib/rubocop/cli.rb +17 -7
  24. data/lib/rubocop/comment_config.rb +24 -3
  25. data/lib/rubocop/config.rb +75 -6
  26. data/lib/rubocop/config_loader.rb +18 -28
  27. data/lib/rubocop/config_loader_resolver.rb +61 -9
  28. data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -1
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +4 -2
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  31. data/lib/rubocop/cop/commissioner.rb +2 -2
  32. data/lib/rubocop/cop/cop.rb +4 -0
  33. data/lib/rubocop/cop/corrector.rb +11 -1
  34. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -6
  35. data/lib/rubocop/cop/correctors/line_break_corrector.rb +59 -0
  36. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -1
  37. data/lib/rubocop/cop/correctors/space_corrector.rb +13 -0
  38. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +1 -1
  39. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +3 -1
  40. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  41. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +3 -5
  42. data/lib/rubocop/cop/generator.rb +29 -8
  43. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +2 -0
  44. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +2 -0
  45. data/lib/rubocop/cop/layout/align_hash.rb +106 -37
  46. data/lib/rubocop/cop/{lint → layout}/block_alignment.rb +8 -5
  47. data/lib/rubocop/cop/layout/block_end_newline.rb +7 -17
  48. data/lib/rubocop/cop/layout/case_indentation.rb +1 -0
  49. data/lib/rubocop/cop/layout/class_structure.rb +6 -7
  50. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  51. data/lib/rubocop/cop/{lint → layout}/condition_position.rb +3 -3
  52. data/lib/rubocop/cop/{lint → layout}/def_end_alignment.rb +2 -1
  53. data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
  54. data/lib/rubocop/cop/layout/empty_comment.rb +140 -0
  55. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -0
  56. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -0
  57. data/lib/rubocop/cop/layout/empty_lines.rb +3 -1
  58. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +7 -5
  59. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +20 -10
  60. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +20 -0
  61. data/lib/rubocop/cop/{lint → layout}/end_alignment.rb +37 -6
  62. data/lib/rubocop/cop/layout/end_of_line.rb +1 -0
  63. data/lib/rubocop/cop/layout/extra_spacing.rb +30 -37
  64. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -0
  65. data/lib/rubocop/cop/layout/indent_heredoc.rb +38 -2
  66. data/lib/rubocop/cop/layout/indentation_consistency.rb +105 -1
  67. data/lib/rubocop/cop/layout/indentation_width.rb +4 -3
  68. data/lib/rubocop/cop/layout/initial_indentation.rb +15 -1
  69. data/lib/rubocop/cop/layout/leading_comment_space.rb +4 -2
  70. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -0
  71. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
  72. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +62 -29
  73. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
  74. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +74 -33
  75. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +16 -2
  76. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -1
  77. data/lib/rubocop/cop/layout/space_after_method_name.rb +2 -0
  78. data/lib/rubocop/cop/layout/space_after_not.rb +2 -0
  79. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -0
  80. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +15 -2
  81. data/lib/rubocop/cop/layout/space_around_operators.rb +15 -13
  82. data/lib/rubocop/cop/layout/space_before_block_braces.rb +13 -1
  83. data/lib/rubocop/cop/layout/space_before_comment.rb +6 -4
  84. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -0
  85. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -0
  86. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +30 -45
  87. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -2
  88. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +48 -18
  89. data/lib/rubocop/cop/layout/space_inside_parens.rb +8 -7
  90. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +57 -11
  91. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +1 -0
  92. data/lib/rubocop/cop/layout/tab.rb +42 -16
  93. data/lib/rubocop/cop/layout/trailing_blank_lines.rb +46 -13
  94. data/lib/rubocop/cop/layout/trailing_whitespace.rb +12 -0
  95. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +5 -3
  96. data/lib/rubocop/cop/lint/big_decimal_new.rb +44 -0
  97. data/lib/rubocop/cop/lint/boolean_symbol.rb +2 -2
  98. data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -2
  99. data/lib/rubocop/cop/lint/debugger.rb +2 -2
  100. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +5 -4
  101. data/lib/rubocop/cop/lint/duplicate_methods.rb +20 -9
  102. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +4 -3
  103. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +16 -10
  104. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +5 -4
  105. data/lib/rubocop/cop/lint/inherit_exception.rb +2 -2
  106. data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
  107. data/lib/rubocop/cop/lint/literal_as_condition.rb +2 -2
  108. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +2 -0
  109. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +7 -5
  110. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  111. data/lib/rubocop/cop/lint/number_conversion.rb +59 -0
  112. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +86 -0
  113. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2 -0
  114. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -2
  115. data/lib/rubocop/cop/lint/rand_one.rb +2 -2
  116. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -0
  117. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -0
  118. data/lib/rubocop/cop/lint/require_parentheses.rb +2 -0
  119. data/lib/rubocop/cop/lint/rescue_type.rb +6 -3
  120. data/lib/rubocop/cop/lint/return_in_void_context.rb +2 -2
  121. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -21
  122. data/lib/rubocop/cop/lint/script_permission.rb +30 -10
  123. data/lib/rubocop/cop/lint/shadowed_argument.rb +3 -3
  124. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -0
  125. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +2 -2
  126. data/lib/rubocop/cop/lint/unified_integer.rb +2 -2
  127. data/lib/rubocop/cop/lint/{unneeded_disable.rb → unneeded_cop_disable_directive.rb} +13 -7
  128. data/lib/rubocop/cop/lint/unneeded_cop_enable_directive.rb +97 -0
  129. data/lib/rubocop/cop/lint/unneeded_require_statement.rb +1 -0
  130. data/lib/rubocop/cop/lint/unreachable_code.rb +3 -3
  131. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +11 -10
  132. data/lib/rubocop/cop/lint/useless_access_modifier.rb +7 -5
  133. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -2
  134. data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -2
  135. data/lib/rubocop/cop/lint/void.rb +49 -10
  136. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  137. data/lib/rubocop/cop/metrics/line_length.rb +5 -2
  138. data/lib/rubocop/cop/mixin/alignment.rb +4 -0
  139. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -1
  140. data/lib/rubocop/cop/mixin/def_node.rb +4 -0
  141. data/lib/rubocop/cop/mixin/documentation_comment.rb +11 -3
  142. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -2
  143. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +20 -1
  144. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
  145. data/lib/rubocop/cop/mixin/hash_alignment.rb +2 -2
  146. data/lib/rubocop/cop/mixin/match_range.rb +2 -0
  147. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +6 -0
  148. data/lib/rubocop/cop/mixin/nil_methods.rb +19 -0
  149. data/lib/rubocop/cop/mixin/percent_literal.rb +57 -9
  150. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -5
  151. data/lib/rubocop/cop/mixin/range_help.rb +102 -0
  152. data/lib/rubocop/cop/mixin/rescue_node.rb +1 -1
  153. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +8 -7
  154. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +11 -9
  155. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -10
  156. data/lib/rubocop/cop/mixin/surrounding_space.rb +38 -8
  157. data/lib/rubocop/cop/mixin/trailing_body.rb +26 -0
  158. data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -3
  159. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +104 -0
  160. data/lib/rubocop/cop/naming/ascii_identifiers.rb +3 -1
  161. data/lib/rubocop/cop/naming/file_name.rb +5 -10
  162. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +76 -0
  163. data/lib/rubocop/cop/naming/uncommunicative_block_param_name.rb +48 -0
  164. data/lib/rubocop/cop/naming/uncommunicative_method_param_name.rb +57 -0
  165. data/lib/rubocop/cop/offense.rb +3 -2
  166. data/lib/rubocop/cop/performance/case_when_splat.rb +1 -0
  167. data/lib/rubocop/cop/performance/casecmp.rb +17 -8
  168. data/lib/rubocop/cop/performance/compare_with_block.rb +2 -0
  169. data/lib/rubocop/cop/performance/count.rb +1 -0
  170. data/lib/rubocop/cop/performance/fixed_size.rb +41 -0
  171. data/lib/rubocop/cop/performance/flat_map.rb +2 -0
  172. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -0
  173. data/lib/rubocop/cop/performance/redundant_merge.rb +1 -1
  174. data/lib/rubocop/cop/performance/redundant_sort_by.rb +2 -0
  175. data/lib/rubocop/cop/performance/regexp_match.rb +4 -0
  176. data/lib/rubocop/cop/performance/reverse_each.rb +2 -0
  177. data/lib/rubocop/cop/performance/string_replacement.rb +2 -0
  178. data/lib/rubocop/cop/rails/active_record_aliases.rb +46 -0
  179. data/lib/rubocop/cop/rails/blank.rb +3 -3
  180. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +6 -0
  181. data/lib/rubocop/cop/rails/delegate.rb +6 -6
  182. data/lib/rubocop/cop/rails/file_path.rb +7 -1
  183. data/lib/rubocop/cop/rails/find_by.rb +2 -0
  184. data/lib/rubocop/cop/rails/http_positional_arguments.rb +17 -5
  185. data/lib/rubocop/cop/rails/inverse_of.rb +21 -2
  186. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +45 -9
  187. data/lib/rubocop/cop/rails/presence.rb +8 -2
  188. data/lib/rubocop/cop/rails/present.rb +5 -5
  189. data/lib/rubocop/cop/rails/read_write_attribute.rb +4 -3
  190. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -0
  191. data/lib/rubocop/cop/rails/relative_date_constant.rb +4 -3
  192. data/lib/rubocop/cop/rails/request_referer.rb +3 -2
  193. data/lib/rubocop/cop/rails/reversible_migration.rb +9 -8
  194. data/lib/rubocop/cop/rails/safe_navigation.rb +3 -2
  195. data/lib/rubocop/cop/rails/save_bang.rb +11 -12
  196. data/lib/rubocop/cop/rails/skips_model_validations.rb +2 -2
  197. data/lib/rubocop/cop/rails/time_zone.rb +38 -16
  198. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +26 -16
  199. data/lib/rubocop/cop/rails/validation.rb +30 -2
  200. data/lib/rubocop/cop/security/open.rb +48 -0
  201. data/lib/rubocop/cop/style/and_or.rb +1 -0
  202. data/lib/rubocop/cop/style/ascii_comments.rb +3 -1
  203. data/lib/rubocop/cop/style/attr.rb +2 -0
  204. data/lib/rubocop/cop/style/block_comments.rb +3 -1
  205. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +2 -5
  206. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -0
  207. data/lib/rubocop/cop/style/class_vars.rb +23 -0
  208. data/lib/rubocop/cop/style/colon_method_call.rb +1 -2
  209. data/lib/rubocop/cop/style/comment_annotation.rb +6 -4
  210. data/lib/rubocop/cop/style/commented_keyword.rb +3 -1
  211. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
  212. data/lib/rubocop/cop/style/copyright.rb +3 -1
  213. data/lib/rubocop/cop/style/each_with_object.rb +15 -1
  214. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -0
  215. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -0
  216. data/lib/rubocop/cop/style/empty_else.rb +9 -5
  217. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -0
  218. data/lib/rubocop/cop/style/empty_line_after_guard_clause.rb +80 -0
  219. data/lib/rubocop/cop/style/empty_literal.rb +1 -0
  220. data/lib/rubocop/cop/style/encoding.rb +2 -0
  221. data/lib/rubocop/cop/style/expand_path_arguments.rb +194 -0
  222. data/lib/rubocop/cop/style/for.rb +33 -0
  223. data/lib/rubocop/cop/style/format_string.rb +1 -1
  224. data/lib/rubocop/cop/style/format_string_token.rb +4 -5
  225. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
  226. data/lib/rubocop/cop/style/hash_syntax.rb +1 -0
  227. data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
  228. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  229. data/lib/rubocop/cop/style/lambda.rb +1 -1
  230. data/lib/rubocop/cop/style/line_end_concatenation.rb +2 -0
  231. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -0
  232. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -0
  233. data/lib/rubocop/cop/style/missing_else.rb +72 -7
  234. data/lib/rubocop/cop/style/mixin_usage.rb +3 -5
  235. data/lib/rubocop/cop/style/module_function.rb +10 -0
  236. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -0
  237. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -0
  238. data/lib/rubocop/cop/style/nested_modifier.rb +2 -0
  239. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -0
  240. data/lib/rubocop/cop/style/next.rb +1 -0
  241. data/lib/rubocop/cop/style/not.rb +2 -0
  242. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  243. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
  244. data/lib/rubocop/cop/style/redundant_exception.rb +8 -3
  245. data/lib/rubocop/cop/style/redundant_return.rb +37 -3
  246. data/lib/rubocop/cop/style/redundant_self.rb +1 -1
  247. data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -0
  248. data/lib/rubocop/cop/style/safe_navigation.rb +74 -32
  249. data/lib/rubocop/cop/style/semicolon.rb +3 -1
  250. data/lib/rubocop/cop/style/single_line_methods.rb +14 -23
  251. data/lib/rubocop/cop/style/stderr_puts.rb +2 -0
  252. data/lib/rubocop/cop/style/string_hash_keys.rb +12 -0
  253. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  254. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +1 -1
  255. data/lib/rubocop/cop/style/symbol_array.rb +29 -0
  256. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  257. data/lib/rubocop/cop/style/trailing_body_on_class.rb +43 -0
  258. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +7 -54
  259. data/lib/rubocop/cop/style/trailing_body_on_module.rb +43 -0
  260. data/lib/rubocop/cop/style/{trailing_comma_in_literal.rb → trailing_comma_in_array_literal.rb} +2 -20
  261. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +56 -0
  262. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +17 -20
  263. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -0
  264. data/lib/rubocop/cop/style/unless_else.rb +2 -0
  265. data/lib/rubocop/cop/style/word_array.rb +0 -1
  266. data/lib/rubocop/cop/style/yoda_condition.rb +1 -0
  267. data/lib/rubocop/cop/team.rb +5 -5
  268. data/lib/rubocop/cop/util.rb +23 -188
  269. data/lib/rubocop/cop/variable_force.rb +1 -1
  270. data/lib/rubocop/file_finder.rb +45 -0
  271. data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -14
  272. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  273. data/lib/rubocop/formatter/html_formatter.rb +12 -5
  274. data/lib/rubocop/formatter/json_formatter.rb +1 -1
  275. data/lib/rubocop/node_pattern.rb +8 -5
  276. data/lib/rubocop/options.rb +40 -33
  277. data/lib/rubocop/path_util.rb +5 -8
  278. data/lib/rubocop/processed_source.rb +53 -0
  279. data/lib/rubocop/remote_config.rb +1 -1
  280. data/lib/rubocop/result_cache.rb +1 -1
  281. data/lib/rubocop/rspec/cop_helper.rb +0 -4
  282. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -4
  283. data/lib/rubocop/rspec/shared_contexts.rb +3 -1
  284. data/lib/rubocop/rspec/shared_examples.rb +23 -25
  285. data/lib/rubocop/rspec/support.rb +5 -0
  286. data/lib/rubocop/runner.rb +3 -2
  287. data/lib/rubocop/string_util.rb +10 -9
  288. data/lib/rubocop/target_finder.rb +4 -1
  289. data/lib/rubocop/token.rb +26 -16
  290. data/lib/rubocop/version.rb +6 -4
  291. metadata +31 -17
  292. data/lib/rubocop/cop/performance/hash_each_methods.rb +0 -129
@@ -432,7 +432,7 @@ module RuboCop
432
432
  # (send nil :puts
433
433
  # (lvar :foo)))
434
434
  #
435
- # So the the method argument nodes need to be processed
435
+ # So the method argument nodes need to be processed
436
436
  # in current scope.
437
437
  #
438
438
  # Same thing.
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ module RuboCop
6
+ # Common methods for finding files.
7
+ module FileFinder
8
+ def self.root_level=(level)
9
+ @root_level = level
10
+ end
11
+
12
+ def self.root_level?(path)
13
+ @root_level == path.to_s
14
+ end
15
+
16
+ def find_file_upwards(filename, start_dir, use_home: false)
17
+ traverse_files_upwards(filename, start_dir, use_home) do |file|
18
+ # minimize iteration for performance
19
+ return file if file
20
+ end
21
+ end
22
+
23
+ def find_files_upwards(filename, start_dir, use_home: false)
24
+ files = []
25
+ traverse_files_upwards(filename, start_dir, use_home) do |file|
26
+ files << file
27
+ end
28
+ files
29
+ end
30
+
31
+ private
32
+
33
+ def traverse_files_upwards(filename, start_dir, use_home)
34
+ Pathname.new(start_dir).expand_path.ascend do |dir|
35
+ break if FileFinder.root_level?(dir)
36
+ file = dir + filename
37
+ yield(file.to_s) if file.exist?
38
+ end
39
+
40
+ return unless use_home && ENV.key?('HOME')
41
+ file = File.join(Dir.home, filename)
42
+ yield(file) if File.exist?(file)
43
+ end
44
+ end
45
+ end
@@ -5,15 +5,15 @@ module RuboCop
5
5
  # This formatter displays a YAML configuration file where all cops that
6
6
  # detected any offenses are configured to not detect the offense.
7
7
  class DisabledConfigFormatter < BaseFormatter
8
- HEADING =
9
- ['# This configuration was generated by',
10
- '# `%s`',
11
- "# on #{Time.now} using RuboCop version #{Version.version}.",
12
- '# The point is for the user to remove these configuration records',
13
- '# one by one as the offenses are removed from the code base.',
14
- '# Note that changes in the inspected code, or installation of new',
15
- '# versions of RuboCop, may require this file to be generated again.']
16
- .join("\n")
8
+ HEADING = <<-COMMENTS.strip_indent
9
+ # This configuration was generated by
10
+ # `%<command>s`
11
+ # %<timestamp>susing RuboCop version #{Version.version}.
12
+ # The point is for the user to remove these configuration records
13
+ # one by one as the offenses are removed from the code base.
14
+ # Note that changes in the inspected code, or installation of new
15
+ # versions of RuboCop, may require this file to be generated again.
16
+ COMMENTS
17
17
 
18
18
  @config_to_allow_offenses = {}
19
19
  @detected_styles = {}
@@ -32,9 +32,8 @@ module RuboCop
32
32
 
33
33
  def file_started(_file, _file_info)
34
34
  @exclude_limit_option = @options[:exclude_limit]
35
- @exclude_limit = (
36
- @exclude_limit_option ||
37
- RuboCop::Options::DEFAULT_MAXIMUM_EXCLUSION_ITEMS).to_i
35
+ @exclude_limit = Integer(@exclude_limit_option ||
36
+ RuboCop::Options::DEFAULT_MAXIMUM_EXCLUSION_ITEMS)
38
37
  @show_offense_counts = !@options[:no_offense_counts]
39
38
  end
40
39
 
@@ -47,7 +46,7 @@ module RuboCop
47
46
  end
48
47
 
49
48
  def finished(_inspected_files)
50
- output.puts HEADING % command
49
+ output.puts format(HEADING, command: command, timestamp: timestamp)
51
50
 
52
51
  # Syntax isn't a real cop and it can't be disabled.
53
52
  @cops_with_offenses.delete('Lint/Syntax')
@@ -62,13 +61,23 @@ module RuboCop
62
61
  def command
63
62
  command = 'rubocop --auto-gen-config'
64
63
  if @exclude_limit_option
65
- command += format(' --exclude-limit %d', @exclude_limit_option.to_i)
64
+ command +=
65
+ format(' --exclude-limit %<limit>d',
66
+ limit: Integer(@exclude_limit_option))
66
67
  end
67
68
  command += ' --no-offense-counts' if @options[:no_offense_counts]
68
69
 
70
+ if @options[:no_auto_gen_timestamp]
71
+ command += ' --no-auto-gen-timestamp'
72
+ end
73
+
69
74
  command
70
75
  end
71
76
 
77
+ def timestamp
78
+ @options[:no_auto_gen_timestamp] ? '' : "on #{Time.now} "
79
+ end
80
+
72
81
  def output_offenses
73
82
  @cops_with_offenses.sort.each do |cop_name, offense_count|
74
83
  output_cop(cop_name, offense_count)
@@ -11,7 +11,7 @@ module RuboCop
11
11
  class FuubarStyleFormatter < ClangStyleFormatter
12
12
  RESET_SEQUENCE = "\e[0m".freeze
13
13
 
14
- def initialize(*)
14
+ def initialize(*output)
15
15
  @severest_offense = nil
16
16
 
17
17
  super
@@ -12,7 +12,7 @@ module RuboCop
12
12
  class HTMLFormatter < BaseFormatter
13
13
  ELLIPSES = '<span class="extra-code">...</span>'.freeze
14
14
  TEMPLATE_PATH =
15
- File.expand_path('../../../../assets/output.html.erb', __FILE__)
15
+ File.expand_path('../../../assets/output.html.erb', __dir__)
16
16
 
17
17
  Color = Struct.new(:red, :green, :blue, :alpha) do
18
18
  def to_s
@@ -53,7 +53,14 @@ module RuboCop
53
53
  context = ERBContext.new(files, summary)
54
54
 
55
55
  template = File.read(TEMPLATE_PATH, encoding: Encoding::UTF_8)
56
- erb = ERB.new(template, nil, '-')
56
+
57
+ # The following condition is workaround for until Ruby 2.6 is released.
58
+ # https://github.com/ruby/ruby/commit/cc777d09f44fa909a336ba14f3aa802ffe16e010
59
+ erb = if RUBY_VERSION >= '2.6'
60
+ ERB.new(template, trim_mode: '-')
61
+ else
62
+ ERB.new(template, nil, '-')
63
+ end
57
64
  html = erb.result(context.binding)
58
65
 
59
66
  output.write html
@@ -73,7 +80,7 @@ module RuboCop
73
80
  }.freeze
74
81
 
75
82
  LOGO_IMAGE_PATH =
76
- File.expand_path('../../../../assets/logo.png', __FILE__)
83
+ File.expand_path('../../../assets/logo.png', __dir__)
77
84
 
78
85
  attr_reader :files, :summary
79
86
 
@@ -120,8 +127,8 @@ module RuboCop
120
127
  location.first_line == location.last_line ? '' : " #{ELLIPSES}"
121
128
  end
122
129
 
123
- def escape(s)
124
- CGI.escapeHTML(s)
130
+ def escape(string)
131
+ CGI.escapeHTML(string)
125
132
  end
126
133
 
127
134
  def base64_encoded_logo_image
@@ -46,7 +46,7 @@ module RuboCop
46
46
 
47
47
  def hash_for_file(file, offenses)
48
48
  {
49
- path: relative_path(file),
49
+ path: smart_path(file),
50
50
  offenses: offenses.map { |o| hash_for_offense(o) }
51
51
  }
52
52
  end
@@ -369,7 +369,7 @@ module RuboCop
369
369
  if method.end_with?('(') # is there an arglist?
370
370
  args = compile_args(tokens)
371
371
  method = method[0..-2] # drop the trailing (
372
- "(#{method}(#{cur_node}#{'.type' if seq_head}),#{args.join(',')})"
372
+ "(#{method}(#{cur_node}#{'.type' if seq_head},#{args.join(',')}))"
373
373
  else
374
374
  "(#{method}(#{cur_node}#{'.type' if seq_head}))"
375
375
  end
@@ -384,10 +384,13 @@ module RuboCop
384
384
  end
385
385
 
386
386
  def compile_args(tokens)
387
- args = []
388
- args << compile_arg(tokens.shift) until tokens.first == ')'
389
- tokens.shift # drop the )
390
- args
387
+ index = tokens.find_index { |token| token == ')' }
388
+
389
+ tokens.slice!(0..index).each_with_object([]) do |token, args|
390
+ next if [')', ','].include?(token)
391
+
392
+ args << compile_arg(token)
393
+ end
391
394
  end
392
395
 
393
396
  def compile_arg(token)
@@ -18,7 +18,7 @@ module RuboCop
18
18
 
19
19
  def parse(command_line_args)
20
20
  args = args_from_file.concat(args_from_env).concat(command_line_args)
21
- define_options(args).parse!(args)
21
+ define_options.parse!(args)
22
22
 
23
23
  @validator.validate_compatibility
24
24
 
@@ -51,13 +51,13 @@ module RuboCop
51
51
  Shellwords.split(ENV.fetch('RUBOCOP_OPTS', ''))
52
52
  end
53
53
 
54
- def define_options(args)
54
+ def define_options
55
55
  OptionParser.new do |opts|
56
56
  opts.banner = 'Usage: rubocop [options] [file1, file2, ...]'
57
57
 
58
58
  add_list_options(opts)
59
59
  add_only_options(opts)
60
- add_configuration_options(opts, args)
60
+ add_configuration_options(opts)
61
61
  add_formatting_options(opts)
62
62
 
63
63
  option(opts, '-r', '--require FILE') { |f| require f }
@@ -89,13 +89,13 @@ module RuboCop
89
89
  end
90
90
  end
91
91
 
92
- def add_configuration_options(opts, args)
92
+ def add_configuration_options(opts)
93
93
  option(opts, '-c', '--config FILE')
94
94
 
95
95
  option(opts, '--auto-gen-config')
96
96
 
97
97
  option(opts, '--exclude-limit COUNT') do
98
- @validator.validate_exclude_limit_option(args)
98
+ @validator.validate_exclude_limit_option
99
99
  end
100
100
 
101
101
  option(opts, '--force-exclusion')
@@ -106,6 +106,10 @@ module RuboCop
106
106
  option(opts, '--no-offense-counts') do
107
107
  @options[:no_offense_counts] = true
108
108
  end
109
+
110
+ option(opts, '--no-auto-gen-timestamp') do
111
+ @options[:no_auto_gen_timestamp] = true
112
+ end
109
113
  end
110
114
 
111
115
  def add_formatting_options(opts)
@@ -206,18 +210,18 @@ module RuboCop
206
210
  private
207
211
 
208
212
  def format_message_from(name, cop_names)
209
- message = 'Unrecognized cop or department: %{name}.'
210
- message_with_candidate = "#{message}\nDid you mean? %{candidate}"
213
+ message = 'Unrecognized cop or department: %<name>s.'
214
+ message_with_candidate = "%<message>s\nDid you mean? %<candidate>s"
211
215
  corrections = cop_names.select do |cn|
212
216
  score = StringUtil.similarity(cn, name)
213
217
  score >= NameSimilarity::MINIMUM_SIMILARITY_TO_SUGGEST
214
218
  end.sort
215
219
 
216
220
  if corrections.empty?
217
- format message, name: name
221
+ format(message, name: name)
218
222
  else
219
- format message_with_candidate, name: name,
220
- candidate: corrections.join(', ')
223
+ format(message_with_candidate, message: format(message, name: name),
224
+ candidate: corrections.join(', '))
221
225
  end
222
226
  end
223
227
  end
@@ -228,7 +232,8 @@ module RuboCop
228
232
 
229
233
  def validate_compatibility # rubocop:disable Metrics/MethodLength
230
234
  if only_includes_unneeded_disable?
231
- raise ArgumentError, 'Lint/UnneededDisable can not be used with --only.'
235
+ raise ArgumentError, 'Lint/UnneededCopDisableDirective can not ' \
236
+ 'be used with --only.'
232
237
  end
233
238
  if except_syntax?
234
239
  raise ArgumentError, 'Syntax checking can not be turned off.'
@@ -236,10 +241,7 @@ module RuboCop
236
241
  unless boolean_or_empty_cache?
237
242
  raise ArgumentError, '-C/--cache argument must be true or false'
238
243
  end
239
- if no_offense_counts_without_auto_gen_config?
240
- raise ArgumentError, '--no-offense-counts can only be used together ' \
241
- 'with --auto-gen-config.'
242
- end
244
+ validate_auto_gen_config
243
245
  validate_parallel
244
246
 
245
247
  return if incompatible_options.size <= 1
@@ -247,6 +249,18 @@ module RuboCop
247
249
  "#{incompatible_options.inspect}"
248
250
  end
249
251
 
252
+ def validate_auto_gen_config
253
+ return if @options.key?(:auto_gen_config)
254
+
255
+ message = '--%<flag>s can only be used together with --auto-gen-config.'
256
+
257
+ %i[exclude_limit no_offense_counts no_auto_gen_timestamp].each do |option|
258
+ if @options.key?(option)
259
+ raise ArgumentError, format(message, flag: option.to_s.tr('_', '-'))
260
+ end
261
+ end
262
+ end
263
+
250
264
  def validate_parallel
251
265
  return unless @options.key?(:parallel)
252
266
 
@@ -269,7 +283,8 @@ module RuboCop
269
283
 
270
284
  def only_includes_unneeded_disable?
271
285
  @options.key?(:only) &&
272
- (@options[:only] & %w[Lint/UnneededDisable UnneededDisable]).any?
286
+ (@options[:only] & %w[Lint/UnneededCopDisableDirective
287
+ UnneededCopDisableDirective]).any?
273
288
  end
274
289
 
275
290
  def except_syntax?
@@ -281,27 +296,15 @@ module RuboCop
281
296
  !@options.key?(:cache) || %w[true false].include?(@options[:cache])
282
297
  end
283
298
 
284
- def no_offense_counts_without_auto_gen_config?
285
- @options.key?(:no_offense_counts) && !@options.key?(:auto_gen_config)
286
- end
287
-
288
299
  def incompatible_options
289
300
  @incompatible_options ||= @options.keys & Options::EXITING_OPTIONS
290
301
  end
291
302
 
292
- def validate_exclude_limit_option(args)
293
- if @options[:exclude_limit] !~ /^\d+$/
294
- # Emulate OptionParser's behavior to make failures consistent regardless
295
- # of option order.
296
- raise OptionParser::MissingArgument
297
- end
298
-
299
- # --exclude-limit is valid if there's a parsed or yet unparsed
300
- # --auto-gen-config.
301
- return if @options[:auto_gen_config] || args.include?('--auto-gen-config')
302
-
303
- raise ArgumentError,
304
- '--exclude-limit can only be used with --auto-gen-config.'
303
+ def validate_exclude_limit_option
304
+ return if @options[:exclude_limit] =~ /^\d+$/
305
+ # Emulate OptionParser's behavior to make failures consistent regardless
306
+ # of option order.
307
+ raise OptionParser::MissingArgument
305
308
  end
306
309
  end
307
310
 
@@ -319,6 +322,10 @@ module RuboCop
319
322
  'TODO list.'],
320
323
  no_offense_counts: ['Do not include offense counts in configuration',
321
324
  'file generated by --auto-gen-config.'],
325
+ no_auto_gen_timestamp:
326
+ ['Do not include the date and time when',
327
+ 'the --auto-gen-config was run in the file it',
328
+ 'generates.'],
322
329
  exclude_limit: ['Used together with --auto-gen-config to',
323
330
  'set the limit for how many Exclude',
324
331
  "properties to generate. Default is #{MAX_EXCL}."],
@@ -15,7 +15,11 @@ module RuboCop
15
15
  end
16
16
 
17
17
  path_name = Pathname.new(File.expand_path(path))
18
- path_name.relative_path_from(Pathname.new(base_dir)).to_s
18
+ begin
19
+ path_name.relative_path_from(Pathname.new(base_dir)).to_s
20
+ rescue ArgumentError
21
+ path
22
+ end
19
23
  end
20
24
 
21
25
  def smart_path(path)
@@ -43,13 +47,6 @@ module RuboCop
43
47
  end
44
48
  end
45
49
 
46
- def find_file_upwards(filename, start_dir = PathUtil.pwd)
47
- Pathname(File.expand_path(start_dir)).ascend do |dir|
48
- file = File.join(dir, filename)
49
- return file if File.exist?(file)
50
- end
51
- end
52
-
53
50
  # Returns true for an absolute Unix or Windows path.
54
51
  def absolute?(path)
55
52
  path =~ %r{\A([A-Z]:)?/}
@@ -78,8 +78,61 @@ module RuboCop
78
78
  Digest::MD5.hexdigest(@raw_source)
79
79
  end
80
80
 
81
+ def each_comment
82
+ comments.each { |comment| yield comment }
83
+ end
84
+
85
+ def find_comment
86
+ comments.find { |comment| yield comment }
87
+ end
88
+
89
+ def each_token
90
+ tokens.each { |token| yield token }
91
+ end
92
+
93
+ def find_token
94
+ tokens.find { |token| yield token }
95
+ end
96
+
97
+ def file_path
98
+ buffer.name
99
+ end
100
+
101
+ def blank?
102
+ ast.nil?
103
+ end
104
+
105
+ def commented?(source_range)
106
+ comment_lines.include?(source_range.line)
107
+ end
108
+
109
+ def comment_on_line?(line)
110
+ comments.any? { |c| c.loc.line == line }
111
+ end
112
+
113
+ def comments_before_line(line)
114
+ comments.select { |c| c.location.line <= line }
115
+ end
116
+
117
+ def start_with?(string)
118
+ return false if self[0].nil?
119
+ self[0].start_with?(string)
120
+ end
121
+
122
+ def preceding_line(token)
123
+ lines[token.line - 2]
124
+ end
125
+
126
+ def following_line(token)
127
+ lines[token.line]
128
+ end
129
+
81
130
  private
82
131
 
132
+ def comment_lines
133
+ @comment_lines ||= comments.map { |c| c.location.line }
134
+ end
135
+
83
136
  def parse(source, ruby_version)
84
137
  buffer_name = @path || STRING_SOURCE_NAME
85
138
  @buffer = Parser::Source::Buffer.new(buffer_name, 1)