rubocop 0.67.2 → 0.68.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +86 -233
  4. data/exe/rubocop +0 -12
  5. data/lib/rubocop.rb +13 -30
  6. data/lib/rubocop/ast/builder.rb +4 -0
  7. data/lib/rubocop/ast/node/alias_node.rb +24 -0
  8. data/lib/rubocop/ast/node/class_node.rb +31 -0
  9. data/lib/rubocop/ast/node/module_node.rb +24 -0
  10. data/lib/rubocop/ast/node/range_node.rb +7 -0
  11. data/lib/rubocop/ast/node/resbody_node.rb +12 -0
  12. data/lib/rubocop/ast/node/self_class_node.rb +24 -0
  13. data/lib/rubocop/cli.rb +40 -4
  14. data/lib/rubocop/config.rb +9 -7
  15. data/lib/rubocop/config_loader.rb +48 -7
  16. data/lib/rubocop/config_loader_resolver.rb +5 -4
  17. data/lib/rubocop/cop/commissioner.rb +24 -0
  18. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +18 -6
  19. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +12 -14
  20. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +9 -20
  21. data/lib/rubocop/cop/layout/align_arguments.rb +93 -0
  22. data/lib/rubocop/cop/layout/align_parameters.rb +57 -33
  23. data/lib/rubocop/cop/layout/class_structure.rb +5 -5
  24. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +6 -8
  25. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +3 -6
  26. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +1 -2
  27. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -0
  28. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +292 -0
  29. data/lib/rubocop/cop/layout/{first_parameter_indentation.rb → indent_first_argument.rb} +11 -12
  30. data/lib/rubocop/cop/layout/{indent_array.rb → indent_first_array_element.rb} +2 -2
  31. data/lib/rubocop/cop/layout/{indent_hash.rb → indent_first_hash_element.rb} +2 -2
  32. data/lib/rubocop/cop/layout/indent_first_parameter.rb +96 -0
  33. data/lib/rubocop/cop/layout/indentation_width.rb +4 -16
  34. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +2 -4
  35. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -16
  36. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -2
  37. data/lib/rubocop/cop/lint/duplicate_methods.rb +6 -8
  38. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +4 -8
  39. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +157 -0
  40. data/lib/rubocop/cop/lint/inherit_exception.rb +3 -4
  41. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +18 -1
  42. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -5
  43. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +25 -5
  44. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -6
  45. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -2
  46. data/lib/rubocop/cop/message_annotator.rb +1 -0
  47. data/lib/rubocop/cop/metrics/line_length.rb +139 -28
  48. data/lib/rubocop/cop/metrics/perceived_complexity.rb +3 -4
  49. data/lib/rubocop/cop/mixin/check_line_breakable.rb +190 -0
  50. data/lib/rubocop/cop/mixin/{array_hash_indentation.rb → multiline_element_indentation.rb} +3 -2
  51. data/lib/rubocop/cop/mixin/too_many_lines.rb +3 -7
  52. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +33 -4
  53. data/lib/rubocop/cop/rails/active_record_override.rb +23 -8
  54. data/lib/rubocop/cop/rails/delegate.rb +5 -8
  55. data/lib/rubocop/cop/rails/environment_comparison.rb +5 -3
  56. data/lib/rubocop/cop/rails/find_each.rb +1 -1
  57. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +3 -3
  58. data/lib/rubocop/cop/rails/reflection_class_name.rb +1 -1
  59. data/lib/rubocop/cop/rails/skips_model_validations.rb +6 -7
  60. data/lib/rubocop/cop/rails/time_zone.rb +3 -10
  61. data/lib/rubocop/cop/rails/validation.rb +3 -0
  62. data/lib/rubocop/cop/registry.rb +3 -3
  63. data/lib/rubocop/cop/style/alias.rb +13 -7
  64. data/lib/rubocop/cop/style/block_delimiters.rb +20 -0
  65. data/lib/rubocop/cop/style/class_and_module_children.rb +19 -21
  66. data/lib/rubocop/cop/style/class_methods.rb +16 -24
  67. data/lib/rubocop/cop/style/conditional_assignment.rb +20 -49
  68. data/lib/rubocop/cop/style/documentation.rb +3 -7
  69. data/lib/rubocop/cop/style/format_string.rb +18 -21
  70. data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
  71. data/lib/rubocop/cop/style/inverse_methods.rb +4 -0
  72. data/lib/rubocop/cop/style/lambda.rb +12 -8
  73. data/lib/rubocop/cop/style/mixin_grouping.rb +8 -10
  74. data/lib/rubocop/cop/style/module_function.rb +2 -3
  75. data/lib/rubocop/cop/style/next.rb +10 -14
  76. data/lib/rubocop/cop/style/one_line_conditional.rb +5 -3
  77. data/lib/rubocop/cop/style/optional_arguments.rb +1 -4
  78. data/lib/rubocop/cop/style/random_with_offset.rb +44 -47
  79. data/lib/rubocop/cop/style/redundant_return.rb +6 -14
  80. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -1
  81. data/lib/rubocop/cop/style/safe_navigation.rb +3 -0
  82. data/lib/rubocop/cop/style/struct_inheritance.rb +2 -3
  83. data/lib/rubocop/cop/style/symbol_proc.rb +20 -40
  84. data/lib/rubocop/cop/style/unless_else.rb +1 -2
  85. data/lib/rubocop/cop/style/yoda_condition.rb +8 -7
  86. data/lib/rubocop/cop/util.rb +2 -4
  87. data/lib/rubocop/file_finder.rb +5 -10
  88. data/lib/rubocop/formatter/disabled_config_formatter.rb +5 -0
  89. data/lib/rubocop/node_pattern.rb +304 -170
  90. data/lib/rubocop/options.rb +4 -1
  91. data/lib/rubocop/rspec/shared_contexts.rb +3 -0
  92. data/lib/rubocop/version.rb +1 -1
  93. data/lib/rubocop/yaml_duplication_checker.rb +1 -1
  94. metadata +26 -50
  95. data/lib/rubocop/cop/performance/caller.rb +0 -69
  96. data/lib/rubocop/cop/performance/case_when_splat.rb +0 -177
  97. data/lib/rubocop/cop/performance/casecmp.rb +0 -108
  98. data/lib/rubocop/cop/performance/chain_array_allocation.rb +0 -78
  99. data/lib/rubocop/cop/performance/compare_with_block.rb +0 -122
  100. data/lib/rubocop/cop/performance/count.rb +0 -102
  101. data/lib/rubocop/cop/performance/detect.rb +0 -110
  102. data/lib/rubocop/cop/performance/double_start_end_with.rb +0 -94
  103. data/lib/rubocop/cop/performance/end_with.rb +0 -56
  104. data/lib/rubocop/cop/performance/fixed_size.rb +0 -97
  105. data/lib/rubocop/cop/performance/flat_map.rb +0 -78
  106. data/lib/rubocop/cop/performance/inefficient_hash_search.rb +0 -99
  107. data/lib/rubocop/cop/performance/open_struct.rb +0 -46
  108. data/lib/rubocop/cop/performance/range_include.rb +0 -50
  109. data/lib/rubocop/cop/performance/redundant_block_call.rb +0 -93
  110. data/lib/rubocop/cop/performance/redundant_match.rb +0 -56
  111. data/lib/rubocop/cop/performance/redundant_merge.rb +0 -183
  112. data/lib/rubocop/cop/performance/regexp_match.rb +0 -265
  113. data/lib/rubocop/cop/performance/reverse_each.rb +0 -42
  114. data/lib/rubocop/cop/performance/size.rb +0 -77
  115. data/lib/rubocop/cop/performance/start_with.rb +0 -59
  116. data/lib/rubocop/cop/performance/string_replacement.rb +0 -173
  117. data/lib/rubocop/cop/performance/times_map.rb +0 -71
  118. data/lib/rubocop/cop/performance/unfreeze_string.rb +0 -50
  119. data/lib/rubocop/cop/performance/uri_default_parser.rb +0 -47
@@ -30,12 +30,14 @@ require_relative 'rubocop/ast/node/mixin/modifier_node'
30
30
  require_relative 'rubocop/ast/node/mixin/parameterized_node'
31
31
  require_relative 'rubocop/ast/node/mixin/predicate_operator_node'
32
32
  require_relative 'rubocop/ast/node/mixin/basic_literal_node'
33
+ require_relative 'rubocop/ast/node/alias_node'
33
34
  require_relative 'rubocop/ast/node/and_node'
34
35
  require_relative 'rubocop/ast/node/args_node'
35
36
  require_relative 'rubocop/ast/node/array_node'
36
37
  require_relative 'rubocop/ast/node/block_node'
37
38
  require_relative 'rubocop/ast/node/break_node'
38
39
  require_relative 'rubocop/ast/node/case_node'
40
+ require_relative 'rubocop/ast/node/class_node'
39
41
  require_relative 'rubocop/ast/node/def_node'
40
42
  require_relative 'rubocop/ast/node/defined_node'
41
43
  require_relative 'rubocop/ast/node/ensure_node'
@@ -43,12 +45,14 @@ require_relative 'rubocop/ast/node/for_node'
43
45
  require_relative 'rubocop/ast/node/hash_node'
44
46
  require_relative 'rubocop/ast/node/if_node'
45
47
  require_relative 'rubocop/ast/node/keyword_splat_node'
48
+ require_relative 'rubocop/ast/node/module_node'
46
49
  require_relative 'rubocop/ast/node/or_node'
47
50
  require_relative 'rubocop/ast/node/pair_node'
48
51
  require_relative 'rubocop/ast/node/range_node'
49
52
  require_relative 'rubocop/ast/node/regexp_node'
50
53
  require_relative 'rubocop/ast/node/resbody_node'
51
54
  require_relative 'rubocop/ast/node/retry_node'
55
+ require_relative 'rubocop/ast/node/self_class_node'
52
56
  require_relative 'rubocop/ast/node/send_node'
53
57
  require_relative 'rubocop/ast/node/str_node'
54
58
  require_relative 'rubocop/ast/node/super_node'
@@ -88,11 +92,11 @@ require_relative 'rubocop/cop/variable_force/scope'
88
92
  require_relative 'rubocop/cop/variable_force/variable_table'
89
93
 
90
94
  require_relative 'rubocop/cop/mixin/annotation_comment'
91
- require_relative 'rubocop/cop/mixin/array_hash_indentation'
92
95
  require_relative 'rubocop/cop/mixin/array_min_size'
93
96
  require_relative 'rubocop/cop/mixin/array_syntax'
94
97
  require_relative 'rubocop/cop/mixin/alignment'
95
98
  require_relative 'rubocop/cop/mixin/check_assignment'
99
+ require_relative 'rubocop/cop/mixin/check_line_breakable'
96
100
  require_relative 'rubocop/cop/mixin/configurable_max'
97
101
  require_relative 'rubocop/cop/mixin/code_length' # relies on configurable_max
98
102
  require_relative 'rubocop/cop/mixin/classish_length' # relies on code_length
@@ -118,6 +122,7 @@ require_relative 'rubocop/cop/mixin/match_range'
118
122
  require_relative 'rubocop/cop/mixin/method_complexity'
119
123
  require_relative 'rubocop/cop/mixin/method_preference'
120
124
  require_relative 'rubocop/cop/mixin/min_body_length'
125
+ require_relative 'rubocop/cop/mixin/multiline_element_indentation'
121
126
  require_relative 'rubocop/cop/mixin/multiline_element_line_breaks'
122
127
  require_relative 'rubocop/cop/mixin/multiline_expression_indentation'
123
128
  require_relative 'rubocop/cop/mixin/multiline_literal_brace_layout'
@@ -175,6 +180,7 @@ require_relative 'rubocop/cop/gemspec/ordered_dependencies'
175
180
  require_relative 'rubocop/cop/gemspec/required_ruby_version'
176
181
 
177
182
  require_relative 'rubocop/cop/layout/access_modifier_indentation'
183
+ require_relative 'rubocop/cop/layout/align_arguments'
178
184
  require_relative 'rubocop/cop/layout/align_array'
179
185
  require_relative 'rubocop/cop/layout/align_hash'
180
186
  require_relative 'rubocop/cop/layout/align_parameters'
@@ -209,12 +215,14 @@ require_relative 'rubocop/cop/layout/first_array_element_line_break'
209
215
  require_relative 'rubocop/cop/layout/first_hash_element_line_break'
210
216
  require_relative 'rubocop/cop/layout/first_method_argument_line_break'
211
217
  require_relative 'rubocop/cop/layout/first_method_parameter_line_break'
212
- require_relative 'rubocop/cop/layout/first_parameter_indentation'
213
- require_relative 'rubocop/cop/layout/indent_array'
218
+ require_relative 'rubocop/cop/layout/heredoc_argument_closing_parenthesis'
214
219
  require_relative 'rubocop/cop/layout/indent_assignment'
215
220
  require_relative 'rubocop/cop/layout/indentation_consistency'
216
221
  require_relative 'rubocop/cop/layout/indentation_width'
217
- require_relative 'rubocop/cop/layout/indent_hash'
222
+ require_relative 'rubocop/cop/layout/indent_first_argument'
223
+ require_relative 'rubocop/cop/layout/indent_first_array_element'
224
+ require_relative 'rubocop/cop/layout/indent_first_hash_element'
225
+ require_relative 'rubocop/cop/layout/indent_first_parameter'
218
226
  require_relative 'rubocop/cop/layout/indent_heredoc'
219
227
  require_relative 'rubocop/cop/layout/initial_indentation'
220
228
  require_relative 'rubocop/cop/layout/leading_blank_lines'
@@ -285,6 +293,7 @@ require_relative 'rubocop/cop/lint/flip_flop'
285
293
  require_relative 'rubocop/cop/lint/float_out_of_range'
286
294
  require_relative 'rubocop/cop/lint/format_parameter_mismatch'
287
295
  require_relative 'rubocop/cop/lint/handle_exceptions'
296
+ require_relative 'rubocop/cop/lint/heredoc_method_call_position'
288
297
  require_relative 'rubocop/cop/lint/implicit_string_concatenation'
289
298
  require_relative 'rubocop/cop/lint/inherit_exception'
290
299
  require_relative 'rubocop/cop/lint/ineffective_access_modifier'
@@ -369,32 +378,6 @@ require_relative 'rubocop/cop/naming/uncommunicative_method_param_name'
369
378
  require_relative 'rubocop/cop/naming/variable_name'
370
379
  require_relative 'rubocop/cop/naming/variable_number'
371
380
 
372
- require_relative 'rubocop/cop/performance/caller'
373
- require_relative 'rubocop/cop/performance/case_when_splat'
374
- require_relative 'rubocop/cop/performance/casecmp'
375
- require_relative 'rubocop/cop/performance/count'
376
- require_relative 'rubocop/cop/performance/detect'
377
- require_relative 'rubocop/cop/performance/double_start_end_with'
378
- require_relative 'rubocop/cop/performance/end_with'
379
- require_relative 'rubocop/cop/performance/fixed_size'
380
- require_relative 'rubocop/cop/performance/flat_map'
381
- require_relative 'rubocop/cop/performance/inefficient_hash_search'
382
- require_relative 'rubocop/cop/performance/open_struct'
383
- require_relative 'rubocop/cop/performance/range_include'
384
- require_relative 'rubocop/cop/performance/redundant_block_call'
385
- require_relative 'rubocop/cop/performance/redundant_match'
386
- require_relative 'rubocop/cop/performance/redundant_merge'
387
- require_relative 'rubocop/cop/performance/regexp_match'
388
- require_relative 'rubocop/cop/performance/reverse_each'
389
- require_relative 'rubocop/cop/performance/size'
390
- require_relative 'rubocop/cop/performance/compare_with_block'
391
- require_relative 'rubocop/cop/performance/start_with'
392
- require_relative 'rubocop/cop/performance/string_replacement'
393
- require_relative 'rubocop/cop/performance/times_map'
394
- require_relative 'rubocop/cop/performance/unfreeze_string'
395
- require_relative 'rubocop/cop/performance/uri_default_parser'
396
- require_relative 'rubocop/cop/performance/chain_array_allocation'
397
-
398
381
  require_relative 'rubocop/cop/style/access_modifier_declarations'
399
382
  require_relative 'rubocop/cop/style/alias'
400
383
  require_relative 'rubocop/cop/style/and_or'
@@ -16,11 +16,13 @@ module RuboCop
16
16
  class Builder < Parser::Builders::Default
17
17
  NODE_MAP = {
18
18
  and: AndNode,
19
+ alias: AliasNode,
19
20
  args: ArgsNode,
20
21
  array: ArrayNode,
21
22
  block: BlockNode,
22
23
  break: BreakNode,
23
24
  case: CaseNode,
25
+ class: ClassNode,
24
26
  def: DefNode,
25
27
  defined?: DefinedNode,
26
28
  defs: DefNode,
@@ -31,6 +33,7 @@ module RuboCop
31
33
  irange: RangeNode,
32
34
  erange: RangeNode,
33
35
  kwsplat: KeywordSplatNode,
36
+ module: ModuleNode,
34
37
  or: OrNode,
35
38
  pair: PairNode,
36
39
  regexp: RegexpNode,
@@ -41,6 +44,7 @@ module RuboCop
41
44
  str: StrNode,
42
45
  dstr: StrNode,
43
46
  xstr: StrNode,
47
+ sclass: SelfClassNode,
44
48
  super: SuperNode,
45
49
  zsuper: SuperNode,
46
50
  sym: SymbolNode,
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `alias` nodes. This will be used in place of a plain
6
+ # node when the builder constructs the AST, making its methods available
7
+ # to all `alias` nodes within RuboCop.
8
+ class AliasNode < Node
9
+ # Returns the old identifier as specified by the `alias`.
10
+ #
11
+ # @return [SymbolNode] the old identifier
12
+ def old_identifier
13
+ node_parts[1]
14
+ end
15
+
16
+ # Returns the new identifier as specified by the `alias`.
17
+ #
18
+ # @return [SymbolNode] the new identifier
19
+ def new_identifier
20
+ node_parts[0]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `class` nodes. This will be used in place of a plain
6
+ # node when the builder constructs the AST, making its methods available
7
+ # to all `class` nodes within RuboCop.
8
+ class ClassNode < Node
9
+ # The identifer for this `class` node.
10
+ #
11
+ # @return [Node] the identifer of the class
12
+ def identifier
13
+ node_parts[0]
14
+ end
15
+
16
+ # The parent class for this `class` node.
17
+ #
18
+ # @return [Node, nil] the parent class of the class
19
+ def parent_class
20
+ node_parts[1]
21
+ end
22
+
23
+ # The body of this `class` node.
24
+ #
25
+ # @return [Node, nil] the body of the class
26
+ def body
27
+ node_parts[2]
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `module` nodes. This will be used in place of a
6
+ # plain node when the builder constructs the AST, making its methods
7
+ # available to all `module` nodes within RuboCop.
8
+ class ModuleNode < Node
9
+ # The identifer for this `module` node.
10
+ #
11
+ # @return [Node] the identifer of the module
12
+ def identifier
13
+ node_parts[0]
14
+ end
15
+
16
+ # The body of this `module` node.
17
+ #
18
+ # @return [Node, nil] the body of the module
19
+ def body
20
+ node_parts[1]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -6,6 +6,13 @@ module RuboCop
6
6
  # place of a plain node when the builder constructs the AST, making its
7
7
  # methods available to all `irange` and `erange` nodes within RuboCop.
8
8
  class RangeNode < Node
9
+ def begin
10
+ node_parts[0]
11
+ end
12
+
13
+ def end
14
+ node_parts[1]
15
+ end
9
16
  end
10
17
  end
11
18
  end
@@ -12,6 +12,18 @@ module RuboCop
12
12
  def body
13
13
  node_parts[2]
14
14
  end
15
+
16
+ # Returns the exception variable of the `rescue` clause.
17
+ #
18
+ # @return [Node, nil] The exception variable of the `resbody`.
19
+ def exception_variable
20
+ variable = node_parts[1]
21
+ return variable if variable
22
+
23
+ # When resbody is an implicit rescue (i.e. `rescue e` style),
24
+ # the exception variable is descendants[1].
25
+ descendants[1]
26
+ end
15
27
  end
16
28
  end
17
29
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `sclass` nodes. This will be used in place of a
6
+ # plain node when the builder constructs the AST, making its methods
7
+ # available to all `sclass` nodes within RuboCop.
8
+ class SelfClassNode < Node
9
+ # The identifer for this `sclass` node. (Always `self`.)
10
+ #
11
+ # @return [Node] the identifer of the class
12
+ def identifier
13
+ node_parts[0]
14
+ end
15
+
16
+ # The body of this `sclass` node.
17
+ #
18
+ # @return [Node, nil] the body of the class
19
+ def body
20
+ node_parts[1]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -41,10 +41,15 @@ module RuboCop
41
41
  # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
42
42
  def run(args = ARGV)
43
43
  @options, paths = Options.new.parse(args)
44
- validate_options_vs_config
45
- act_on_options
46
- apply_default_formatter
47
- execute_runners(paths)
44
+
45
+ if @options[:init]
46
+ init_dotfile
47
+ else
48
+ validate_options_vs_config
49
+ act_on_options
50
+ apply_default_formatter
51
+ execute_runners(paths)
52
+ end
48
53
  rescue ConfigNotFoundError, IncorrectCopNameError, OptionArgumentError => e
49
54
  warn e.message
50
55
  STATUS_ERROR
@@ -132,6 +137,37 @@ module RuboCop
132
137
  result
133
138
  end
134
139
 
140
+ def init_dotfile
141
+ path = File.expand_path(ConfigLoader::DOTFILE)
142
+
143
+ if File.exist?(ConfigLoader::DOTFILE)
144
+ warn Rainbow("#{ConfigLoader::DOTFILE} already exists at #{path}").red
145
+
146
+ STATUS_ERROR
147
+ else
148
+ description = <<-DESC.strip_indent
149
+ # The behavior of RuboCop can be controlled via the .rubocop.yml
150
+ # configuration file. It makes it possible to enable/disable
151
+ # certain cops (checks) and to alter their behavior if they accept
152
+ # any parameters. The file can be placed either in your home
153
+ # directory or in some project directory.
154
+ #
155
+ # RuboCop will start looking for the configuration file in the directory
156
+ # where the inspected file is and continue its way up to the root directory.
157
+ #
158
+ # See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
159
+ DESC
160
+
161
+ File.open(ConfigLoader::DOTFILE, 'w') do |f|
162
+ f.write(description)
163
+ end
164
+
165
+ puts "Writing new #{ConfigLoader::DOTFILE} to #{path}"
166
+
167
+ STATUS_SUCCESS
168
+ end
169
+ end
170
+
135
171
  def reset_config_and_auto_gen_file
136
172
  @config_store = ConfigStore.new
137
173
  @config_store.options_config = @options[:config] if @options[:config]
@@ -26,9 +26,6 @@ module RuboCop
26
26
  RUBY_VERSION_FILENAME = '.ruby-version'.freeze
27
27
  DEFAULT_RAILS_VERSION = 5.0
28
28
  OBSOLETE_COPS = {
29
- 'Performance/LstripRstrip' =>
30
- 'The `Performance/LstripRstrip` cop has been moved ' \
31
- 'to `Style/Strip`',
32
29
  'Style/FlipFlop' =>
33
30
  'The `Style/FlipFlop` cop has been moved to `Lint/FlipFlop`.',
34
31
  'Style/TrailingComma' =>
@@ -55,6 +52,15 @@ module RuboCop
55
52
  'The `Lint/SpaceBeforeFirstArg` cop has been removed, since it was a ' \
56
53
  'duplicate of `Layout/SpaceBeforeFirstArg`. Please use ' \
57
54
  '`Layout/SpaceBeforeFirstArg` instead.',
55
+ 'Layout/FirstParameterIndentation' =>
56
+ 'The `Layout/FirstParameterIndentation` cop has been renamed to ' \
57
+ '`Layout/IndentFirstArgument`.',
58
+ 'Layout/IndentArray' =>
59
+ 'The `Layout/IndentArray` cop has been renamed to ' \
60
+ '`Layout/IndentFirstArrayElement`.',
61
+ 'Layout/IndentHash' =>
62
+ 'The `Layout/IndentHash` cop has been renamed to ' \
63
+ '`Layout/IndentFirstHashElement`.',
58
64
  'Layout/SpaceAfterControlKeyword' =>
59
65
  'The `Layout/SpaceAfterControlKeyword` cop has been removed. Please ' \
60
66
  'use `Layout/SpaceAroundKeyword` instead.',
@@ -113,10 +119,6 @@ module RuboCop
113
119
  'Lint/DefEndAlignment' =>
114
120
  'The `Lint/DefEndAlignment` cop has been renamed to ' \
115
121
  '`Layout/DefEndAlignment`.',
116
- 'Performance/HashEachMethods' =>
117
- 'The `Performance/HashEachMethods` cop has been removed ' \
118
- 'since it no longer provides performance benefits in ' \
119
- 'modern rubies.',
120
122
  'Style/MethodMissing' =>
121
123
  'The `Style/MethodMissing` cop has been split into ' \
122
124
  '`Style/MethodMissingSuper` and `Style/MissingRespondToMissing`.'
@@ -15,6 +15,7 @@ module RuboCop
15
15
  # directories are inspected.
16
16
  class ConfigLoader
17
17
  DOTFILE = '.rubocop.yml'.freeze
18
+ XDG_CONFIG = 'config.yml'.freeze
18
19
  RUBOCOP_HOME = File.realpath(File.join(File.dirname(__FILE__), '..', '..'))
19
20
  DEFAULT_FILE = File.join(RUBOCOP_HOME, 'config', 'default.yml')
20
21
  AUTO_GENERATED_FILE = '.rubocop_todo.yml'.freeze
@@ -75,7 +76,10 @@ module RuboCop
75
76
  # user's home directory is checked. If there's no .rubocop.yml
76
77
  # there either, the path to the default file is returned.
77
78
  def configuration_file_for(target_dir)
78
- find_file_upwards(DOTFILE, target_dir, use_home: true) || DEFAULT_FILE
79
+ find_project_dotfile(target_dir) ||
80
+ find_user_dotfile ||
81
+ find_user_xdg_config ||
82
+ DEFAULT_FILE
79
83
  end
80
84
 
81
85
  def configuration_from_file(config_file)
@@ -91,7 +95,10 @@ module RuboCop
91
95
  end
92
96
 
93
97
  def add_excludes_from_files(config, config_file)
94
- found_files = find_files_upwards(DOTFILE, config_file, use_home: true)
98
+ found_files =
99
+ find_files_upwards(DOTFILE, config_file) +
100
+ [find_user_dotfile, find_user_xdg_config].compact
101
+
95
102
  return if found_files.empty?
96
103
  return if PathUtil.relative_path(found_files.last) ==
97
104
  PathUtil.relative_path(config_file)
@@ -139,6 +146,31 @@ module RuboCop
139
146
 
140
147
  private
141
148
 
149
+ def find_project_dotfile(target_dir)
150
+ find_file_upwards(DOTFILE, target_dir)
151
+ end
152
+
153
+ def find_user_dotfile
154
+ return unless ENV.key?('HOME')
155
+
156
+ file = File.join(Dir.home, DOTFILE)
157
+ return file if File.exist?(file)
158
+ end
159
+
160
+ def find_user_xdg_config
161
+ xdg_config_home = expand_path(ENV.fetch('XDG_CONFIG_HOME', '~/.config'))
162
+ xdg_config = File.join(xdg_config_home, 'rubocop', XDG_CONFIG)
163
+ return xdg_config if File.exist?(xdg_config)
164
+ end
165
+
166
+ def expand_path(path)
167
+ File.expand_path(path)
168
+ rescue ArgumentError
169
+ # Could happen because HOME or ID could not be determined. Fall back on
170
+ # using the path literally in that case.
171
+ path
172
+ end
173
+
142
174
  def existing_configuration(config_file)
143
175
  IO.read(config_file, encoding: Encoding::UTF_8)
144
176
  .sub(%r{^inherit_from: *[.\/\w]+}, '')
@@ -174,10 +206,16 @@ module RuboCop
174
206
  smart_path = PathUtil.smart_path(absolute_path)
175
207
  YAMLDuplicationChecker.check(yaml_code, absolute_path) do |key1, key2|
176
208
  value = key1.value
177
- line1 = key1.start_line + 1
178
- line2 = key2.start_line + 1
179
- message = "#{smart_path}:#{line1}: " \
180
- "`#{value}` is concealed by line #{line2}"
209
+ # .start_line is only available since ruby 2.5 / psych 3.0
210
+ message = if key1.respond_to? :start_line
211
+ line1 = key1.start_line + 1
212
+ line2 = key2.start_line + 1
213
+ "#{smart_path}:#{line1}: " \
214
+ "`#{value}` is concealed by line #{line2}"
215
+ else
216
+ "#{smart_path}: " \
217
+ "`#{value}` is concealed by duplicate"
218
+ end
181
219
  warn Rainbow(message).yellow
182
220
  end
183
221
  end
@@ -196,7 +234,8 @@ module RuboCop
196
234
  if defined?(SafeYAML) && SafeYAML.respond_to?(:load)
197
235
  SafeYAML.load(yaml_code, filename,
198
236
  whitelisted_tags: %w[!ruby/regexp])
199
- else
237
+ # Ruby 2.6+
238
+ elsif Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0')
200
239
  YAML.safe_load(
201
240
  yaml_code,
202
241
  permitted_classes: [Regexp, Symbol],
@@ -204,6 +243,8 @@ module RuboCop
204
243
  aliases: false,
205
244
  filename: filename
206
245
  )
246
+ else
247
+ YAML.safe_load(yaml_code, [Regexp, Symbol], [], false, filename)
207
248
  end
208
249
  end
209
250
  end