rubocop 0.76.0 → 0.80.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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +325 -283
  5. data/lib/rubocop.rb +43 -23
  6. data/lib/rubocop/ast/builder.rb +43 -42
  7. data/lib/rubocop/ast/node.rb +1 -13
  8. data/lib/rubocop/ast/node/block_node.rb +2 -0
  9. data/lib/rubocop/ast/node/def_node.rb +11 -0
  10. data/lib/rubocop/ast/node/forward_args_node.rb +18 -0
  11. data/lib/rubocop/ast/node/regexp_node.rb +2 -4
  12. data/lib/rubocop/ast/traversal.rb +20 -3
  13. data/lib/rubocop/cli.rb +11 -230
  14. data/lib/rubocop/cli/command.rb +21 -0
  15. data/lib/rubocop/cli/command/auto_genenerate_config.rb +105 -0
  16. data/lib/rubocop/cli/command/base.rb +33 -0
  17. data/lib/rubocop/cli/command/execute_runner.rb +76 -0
  18. data/lib/rubocop/cli/command/init_dotfile.rb +45 -0
  19. data/lib/rubocop/cli/command/show_cops.rb +80 -0
  20. data/lib/rubocop/cli/command/version.rb +17 -0
  21. data/lib/rubocop/cli/environment.rb +21 -0
  22. data/lib/rubocop/comment_config.rb +6 -1
  23. data/lib/rubocop/config.rb +28 -10
  24. data/lib/rubocop/config_loader.rb +19 -19
  25. data/lib/rubocop/config_obsoletion.rb +65 -11
  26. data/lib/rubocop/config_validator.rb +56 -98
  27. data/lib/rubocop/cop/autocorrect_logic.rb +7 -4
  28. data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -2
  30. data/lib/rubocop/cop/cop.rb +21 -0
  31. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -2
  32. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  33. data/lib/rubocop/cop/generator.rb +3 -4
  34. data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
  35. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  36. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +59 -0
  37. data/lib/rubocop/cop/layout/{align_arguments.rb → argument_alignment.rb} +1 -1
  38. data/lib/rubocop/cop/layout/{align_array.rb → array_alignment.rb} +1 -1
  39. data/lib/rubocop/cop/layout/{indent_assignment.rb → assignment_indentation.rb} +1 -1
  40. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
  41. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  42. data/lib/rubocop/cop/layout/{indent_first_argument.rb → first_argument_indentation.rb} +5 -5
  43. data/lib/rubocop/cop/layout/{indent_first_array_element.rb → first_array_element_indentation.rb} +4 -4
  44. data/lib/rubocop/cop/layout/{indent_first_hash_element.rb → first_hash_element_indentation.rb} +3 -3
  45. data/lib/rubocop/cop/layout/{indent_first_parameter.rb → first_parameter_indentation.rb} +3 -3
  46. data/lib/rubocop/cop/layout/{align_hash.rb → hash_alignment.rb} +10 -6
  47. data/lib/rubocop/cop/layout/{indent_heredoc.rb → heredoc_indentation.rb} +5 -5
  48. data/lib/rubocop/cop/layout/leading_comment_space.rb +33 -2
  49. data/lib/rubocop/cop/layout/{leading_blank_lines.rb → leading_empty_lines.rb} +1 -1
  50. data/lib/rubocop/cop/{metrics → layout}/line_length.rb +67 -108
  51. data/lib/rubocop/cop/layout/multiline_block_layout.rb +14 -5
  52. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +0 -4
  53. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
  54. data/lib/rubocop/cop/layout/{align_parameters.rb → parameter_alignment.rb} +1 -1
  55. data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -0
  56. data/lib/rubocop/cop/layout/space_around_operators.rb +50 -7
  57. data/lib/rubocop/cop/layout/space_before_block_braces.rb +17 -0
  58. data/lib/rubocop/cop/layout/space_before_first_arg.rb +8 -0
  59. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -9
  60. data/lib/rubocop/cop/layout/{trailing_blank_lines.rb → trailing_empty_lines.rb} +1 -1
  61. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  62. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +1 -1
  63. data/lib/rubocop/cop/lint/{duplicated_key.rb → duplicate_hash_key.rb} +1 -1
  64. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  65. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  66. data/lib/rubocop/cop/lint/{multiple_compare.rb → multiple_comparison.rb} +1 -1
  67. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +89 -0
  68. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +3 -3
  69. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +13 -8
  70. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  71. data/lib/rubocop/cop/lint/{string_conversion_in_interpolation.rb → redundant_string_coercion.rb} +1 -1
  72. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
  73. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  74. data/lib/rubocop/cop/lint/{handle_exceptions.rb → suppressed_exception.rb} +1 -1
  75. data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -23
  76. data/lib/rubocop/cop/lint/useless_setter_call.rb +5 -1
  77. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  78. data/lib/rubocop/cop/migration/department_name.rb +30 -2
  79. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  80. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +4 -0
  81. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +7 -7
  82. data/lib/rubocop/cop/mixin/{hash_alignment.rb → hash_alignment_styles.rb} +1 -1
  83. data/lib/rubocop/cop/mixin/hash_transform_method.rb +171 -0
  84. data/lib/rubocop/cop/mixin/line_length_help.rb +88 -0
  85. data/lib/rubocop/cop/mixin/nil_methods.rb +4 -4
  86. data/lib/rubocop/cop/mixin/rational_literal.rb +18 -0
  87. data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
  88. data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -12
  89. data/lib/rubocop/cop/naming/{uncommunicative_block_param_name.rb → block_parameter_name.rb} +3 -3
  90. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -5
  91. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  92. data/lib/rubocop/cop/naming/{uncommunicative_method_param_name.rb → method_parameter_name.rb} +4 -4
  93. data/lib/rubocop/cop/naming/predicate_name.rb +6 -6
  94. data/lib/rubocop/cop/offense.rb +11 -0
  95. data/lib/rubocop/cop/registry.rb +7 -2
  96. data/lib/rubocop/cop/style/alias.rb +1 -1
  97. data/lib/rubocop/cop/style/array_join.rb +1 -1
  98. data/lib/rubocop/cop/style/attr.rb +8 -0
  99. data/lib/rubocop/cop/style/block_delimiters.rb +60 -1
  100. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
  101. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  102. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  103. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +89 -11
  104. data/lib/rubocop/cop/style/guard_clause.rb +3 -2
  105. data/lib/rubocop/cop/style/hash_each_methods.rb +87 -0
  106. data/lib/rubocop/cop/style/hash_transform_keys.rb +79 -0
  107. data/lib/rubocop/cop/style/hash_transform_values.rb +79 -0
  108. data/lib/rubocop/cop/style/if_unless_modifier.rb +38 -3
  109. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  110. data/lib/rubocop/cop/style/inverse_methods.rb +8 -4
  111. data/lib/rubocop/cop/style/ip_addresses.rb +4 -4
  112. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -205
  113. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +169 -0
  114. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +54 -0
  115. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  116. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
  117. data/lib/rubocop/cop/style/multiline_when_then.rb +5 -1
  118. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +7 -7
  119. data/lib/rubocop/cop/style/next.rb +5 -5
  120. data/lib/rubocop/cop/style/numeric_literals.rb +7 -3
  121. data/lib/rubocop/cop/style/numeric_predicate.rb +4 -3
  122. data/lib/rubocop/cop/style/option_hash.rb +3 -3
  123. data/lib/rubocop/cop/style/or_assignment.rb +3 -2
  124. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +7 -7
  125. data/lib/rubocop/cop/style/redundant_condition.rb +17 -4
  126. data/lib/rubocop/cop/style/redundant_parentheses.rb +3 -3
  127. data/lib/rubocop/cop/style/redundant_return.rb +2 -8
  128. data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
  129. data/lib/rubocop/cop/style/symbol_array.rb +2 -2
  130. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  131. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +0 -22
  132. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +7 -1
  133. data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
  134. data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
  135. data/lib/rubocop/cop/style/yoda_condition.rb +16 -1
  136. data/lib/rubocop/cop/team.rb +5 -0
  137. data/lib/rubocop/cop/variable_force.rb +4 -1
  138. data/lib/rubocop/formatter/base_formatter.rb +2 -2
  139. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -3
  140. data/lib/rubocop/formatter/formatter_set.rb +1 -0
  141. data/lib/rubocop/formatter/json_formatter.rb +6 -5
  142. data/lib/rubocop/formatter/junit_formatter.rb +63 -0
  143. data/lib/rubocop/formatter/tap_formatter.rb +1 -3
  144. data/lib/rubocop/node_pattern.rb +97 -11
  145. data/lib/rubocop/options.rb +8 -8
  146. data/lib/rubocop/processed_source.rb +1 -1
  147. data/lib/rubocop/rake_task.rb +1 -0
  148. data/lib/rubocop/result_cache.rb +23 -7
  149. data/lib/rubocop/rspec/shared_contexts.rb +5 -0
  150. data/lib/rubocop/runner.rb +18 -2
  151. data/lib/rubocop/target_ruby.rb +151 -0
  152. data/lib/rubocop/version.rb +1 -1
  153. metadata +60 -27
  154. data/lib/rubocop/cop/mixin/safe_mode.rb +0 -24
  155. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +0 -209
@@ -1,20 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Metrics/ClassLength
4
3
  module RuboCop
5
4
  # The CLI is a class responsible of handling all the command line interface
6
5
  # logic.
7
6
  class CLI
8
- include Formatter::TextUtil
9
-
10
- PHASE_1 = 'Phase 1 of 2: run Metrics/LineLength cop'
11
- PHASE_2 = 'Phase 2 of 2: run all cops'
12
-
13
- PHASE_1_OVERRIDDEN = '(skipped because the default Metrics/LineLength:Max' \
14
- ' is overridden)'
15
- PHASE_1_DISABLED = '(skipped because Metrics/LineLength is ' \
16
- 'disabled)'
17
-
18
7
  STATUS_SUCCESS = 0
19
8
  STATUS_OFFENSES = 1
20
9
  STATUS_ERROR = 2
@@ -41,14 +30,15 @@ module RuboCop
41
30
  # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
42
31
  def run(args = ARGV)
43
32
  @options, paths = Options.new.parse(args)
33
+ @env = Environment.new(@options, @config_store, paths)
44
34
 
45
35
  if @options[:init]
46
- init_dotfile
36
+ run_command(:init)
47
37
  else
48
38
  validate_options_vs_config
49
39
  act_on_options
50
40
  apply_default_formatter
51
- execute_runners(paths)
41
+ execute_runners
52
42
  end
53
43
  rescue ConfigNotFoundError, IncorrectCopNameError, OptionArgumentError => e
54
44
  warn e.message
@@ -71,113 +61,18 @@ module RuboCop
71
61
 
72
62
  private
73
63
 
74
- def execute_runners(paths)
75
- if @options[:auto_gen_config]
76
- reset_config_and_auto_gen_file
77
- line_length_contents = maybe_run_line_length_cop(paths)
78
- run_all_cops_auto_gen_config(line_length_contents, paths)
79
- else
80
- execute_runner(paths)
81
- end
82
- end
83
-
84
- def maybe_run_line_length_cop(paths)
85
- if !line_length_enabled?(@config_store.for(Dir.pwd))
86
- skip_line_length_cop(PHASE_1_DISABLED)
87
- elsif !same_max_line_length?(
88
- @config_store.for(Dir.pwd), ConfigLoader.default_configuration
89
- )
90
- skip_line_length_cop(PHASE_1_OVERRIDDEN)
91
- else
92
- run_line_length_cop_auto_gen_config(paths)
93
- end
94
- end
95
-
96
- def skip_line_length_cop(reason)
97
- puts Rainbow("#{PHASE_1} #{reason}").yellow
98
- ''
99
- end
100
-
101
- def line_length_enabled?(config)
102
- line_length_cop(config)['Enabled']
103
- end
104
-
105
- def same_max_line_length?(config1, config2)
106
- max_line_length(config1) == max_line_length(config2)
107
- end
108
-
109
- def max_line_length(config)
110
- line_length_cop(config)['Max']
111
- end
112
-
113
- def line_length_cop(config)
114
- config.for_cop('Metrics/LineLength')
64
+ def run_command(name)
65
+ @env.run(name)
115
66
  end
116
67
 
117
- # Do an initial run with only Metrics/LineLength so that cops that depend
118
- # on Metrics/LineLength:Max get the correct value for that parameter.
119
- def run_line_length_cop_auto_gen_config(paths)
120
- puts Rainbow(PHASE_1).yellow
121
- @options[:only] = ['Metrics/LineLength']
122
- execute_runner(paths)
123
- @options.delete(:only)
124
- @config_store = ConfigStore.new
125
- # Save the todo configuration of the LineLength cop.
126
- IO.read(ConfigLoader::AUTO_GENERATED_FILE)
127
- .lines
128
- .drop_while { |line| line.start_with?('#') }
129
- .join
130
- end
131
-
132
- def run_all_cops_auto_gen_config(line_length_contents, paths)
133
- puts Rainbow(PHASE_2).yellow
134
- result = execute_runner(paths)
135
- # This run was made with the current maximum length allowed, so append
136
- # the saved setting for LineLength.
137
- File.open(ConfigLoader::AUTO_GENERATED_FILE, 'a') do |f|
138
- f.write(line_length_contents)
139
- end
140
- result
141
- end
142
-
143
- def init_dotfile
144
- path = File.expand_path(ConfigLoader::DOTFILE)
145
-
146
- if File.exist?(ConfigLoader::DOTFILE)
147
- warn Rainbow("#{ConfigLoader::DOTFILE} already exists at #{path}").red
148
-
149
- STATUS_ERROR
68
+ def execute_runners
69
+ if @options[:auto_gen_config]
70
+ run_command(:auto_gen_config)
150
71
  else
151
- description = <<~DESC
152
- # The behavior of RuboCop can be controlled via the .rubocop.yml
153
- # configuration file. It makes it possible to enable/disable
154
- # certain cops (checks) and to alter their behavior if they accept
155
- # any parameters. The file can be placed either in your home
156
- # directory or in some project directory.
157
- #
158
- # RuboCop will start looking for the configuration file in the directory
159
- # where the inspected file is and continue its way up to the root directory.
160
- #
161
- # See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
162
- DESC
163
-
164
- File.open(ConfigLoader::DOTFILE, 'w') do |f|
165
- f.write(description)
166
- end
167
-
168
- puts "Writing new #{ConfigLoader::DOTFILE} to #{path}"
169
-
170
- STATUS_SUCCESS
72
+ run_command(:execute_runner)
171
73
  end
172
74
  end
173
75
 
174
- def reset_config_and_auto_gen_file
175
- @config_store = ConfigStore.new
176
- @config_store.options_config = @options[:config] if @options[:config]
177
- File.open(ConfigLoader::AUTO_GENERATED_FILE, 'w') {}
178
- ConfigLoader.add_inheritance_from_auto_generated_file
179
- end
180
-
181
76
  def validate_options_vs_config
182
77
  if @options[:parallel] &&
183
78
  !@config_store.for(Dir.pwd).for_all_cops['UseCache']
@@ -207,31 +102,11 @@ module RuboCop
207
102
  end
208
103
  end
209
104
 
210
- def execute_runner(paths)
211
- runner = Runner.new(@options, @config_store)
212
-
213
- all_passed = runner.run(paths)
214
- display_warning_summary(runner.warnings)
215
- display_error_summary(runner.errors)
216
- maybe_print_corrected_source
217
-
218
- all_pass_or_excluded = all_passed || @options[:auto_gen_config]
219
-
220
- if runner.aborting?
221
- STATUS_INTERRUPTED
222
- elsif all_pass_or_excluded && runner.errors.empty?
223
- STATUS_SUCCESS
224
- else
225
- STATUS_OFFENSES
226
- end
227
- end
228
-
229
105
  def handle_exiting_options
230
106
  return unless Options::EXITING_OPTIONS.any? { |o| @options.key? o }
231
107
 
232
- puts RuboCop::Version.version(false) if @options[:version]
233
- puts RuboCop::Version.version(true) if @options[:verbose_version]
234
- print_available_cops if @options[:show_cops]
108
+ run_command(:version) if @options[:version] || @options[:verbose_version]
109
+ run_command(:show_cops) if @options[:show_cops]
235
110
  raise Finished
236
111
  end
237
112
 
@@ -247,100 +122,6 @@ module RuboCop
247
122
  end
248
123
  [[formatter, @options[:output_path]]]
249
124
  end
250
-
251
- return unless @options[:auto_gen_config]
252
-
253
- @options[:formatters] << [Formatter::DisabledConfigFormatter,
254
- ConfigLoader::AUTO_GENERATED_FILE]
255
- end
256
-
257
- def print_available_cops
258
- # Load the configs so the require()s are done for custom cops
259
- @config_store.for(Dir.pwd)
260
- registry = Cop::Cop.registry
261
- show_all = @options[:show_cops].empty?
262
-
263
- if show_all
264
- puts "# Available cops (#{registry.length}) + config for #{Dir.pwd}: "
265
- end
266
-
267
- registry.departments.sort!.each do |department|
268
- print_cops_of_department(registry, department, show_all)
269
- end
270
- end
271
-
272
- def print_cops_of_department(registry, department, show_all)
273
- selected_cops = if show_all
274
- cops_of_department(registry, department)
275
- else
276
- selected_cops_of_department(registry, department)
277
- end
278
-
279
- puts "# Department '#{department}' (#{selected_cops.length}):" if show_all
280
-
281
- print_cop_details(selected_cops)
282
- end
283
-
284
- def print_cop_details(cops)
285
- cops.each do |cop|
286
- puts '# Supports --auto-correct' if cop.new.support_autocorrect?
287
- puts "#{cop.cop_name}:"
288
- puts config_lines(cop)
289
- puts
290
- end
291
- end
292
-
293
- def selected_cops_of_department(cops, department)
294
- cops_of_department(cops, department).select do |cop|
295
- @options[:show_cops].include?(cop.cop_name)
296
- end
297
- end
298
-
299
- def cops_of_department(cops, department)
300
- cops.with_department(department).sort!
301
- end
302
-
303
- def config_lines(cop)
304
- cnf = @config_store.for(Dir.pwd).for_cop(cop)
305
- cnf.to_yaml.lines.to_a.drop(1).map { |line| ' ' + line }
306
- end
307
-
308
- def display_warning_summary(warnings)
309
- return if warnings.empty?
310
-
311
- warn Rainbow("\n#{pluralize(warnings.size, 'warning')}:").yellow
312
-
313
- warnings.each { |warning| warn warning }
314
- end
315
-
316
- def display_error_summary(errors)
317
- return if errors.empty?
318
-
319
- warn Rainbow("\n#{pluralize(errors.size, 'error')} occurred:").red
320
-
321
- errors.each { |error| warn error }
322
-
323
- warn <<~WARNING
324
- Errors are usually caused by RuboCop bugs.
325
- Please, report your problems to RuboCop's issue tracker.
326
- #{Gem.loaded_specs['rubocop'].metadata['bug_tracker_uri']}
327
-
328
- Mention the following information in the issue report:
329
- #{RuboCop::Version.version(true)}
330
- WARNING
331
- end
332
-
333
- def maybe_print_corrected_source
334
- # If we are asked to autocorrect source code read from stdin, the only
335
- # reasonable place to write it is to stdout
336
- # Unfortunately, we also write other information to stdout
337
- # So a delimiter is needed for tools to easily identify where the
338
- # autocorrected source begins
339
- return unless @options[:stdin] && @options[:auto_correct]
340
-
341
- puts '=' * 20
342
- print @options[:stdin]
343
125
  end
344
126
  end
345
127
  end
346
- # rubocop:enable Metrics/ClassLength
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CLI
5
+ # Home of subcommands in the CLI.
6
+ module Command
7
+ class << self
8
+ # Find the command with a given name and run it in an environment.
9
+ def run(env, name)
10
+ class_for(name).new(env).run
11
+ end
12
+
13
+ private
14
+
15
+ def class_for(name)
16
+ Base.by_command_name(name)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CLI
5
+ module Command
6
+ # Generate a configuration file acting as a TODO list.
7
+ class AutoGenerateConfig < Base
8
+ self.command_name = :auto_gen_config
9
+
10
+ PHASE_1 = 'Phase 1 of 2: run Layout/LineLength cop'
11
+ PHASE_2 = 'Phase 2 of 2: run all cops'
12
+
13
+ PHASE_1_OVERRIDDEN =
14
+ '(skipped because the default Layout/LineLength:Max is overridden)'
15
+ PHASE_1_DISABLED =
16
+ '(skipped because Layout/LineLength is disabled)'
17
+
18
+ def run
19
+ add_formatter
20
+ reset_config_and_auto_gen_file
21
+ line_length_contents = maybe_run_line_length_cop
22
+ run_all_cops(line_length_contents)
23
+ end
24
+
25
+ private
26
+
27
+ def maybe_run_line_length_cop
28
+ if !line_length_enabled?(@config_store.for(Dir.pwd))
29
+ skip_line_length_cop(PHASE_1_DISABLED)
30
+ elsif !same_max_line_length?(
31
+ @config_store.for(Dir.pwd), ConfigLoader.default_configuration
32
+ )
33
+ skip_line_length_cop(PHASE_1_OVERRIDDEN)
34
+ else
35
+ run_line_length_cop
36
+ end
37
+ end
38
+
39
+ def skip_line_length_cop(reason)
40
+ puts Rainbow("#{PHASE_1} #{reason}").yellow
41
+ ''
42
+ end
43
+
44
+ def line_length_enabled?(config)
45
+ line_length_cop(config)['Enabled']
46
+ end
47
+
48
+ def same_max_line_length?(config1, config2)
49
+ max_line_length(config1) == max_line_length(config2)
50
+ end
51
+
52
+ def max_line_length(config)
53
+ line_length_cop(config)['Max']
54
+ end
55
+
56
+ def line_length_cop(config)
57
+ config.for_cop('Layout/LineLength')
58
+ end
59
+
60
+ # Do an initial run with only Layout/LineLength so that cops that
61
+ # depend on Layout/LineLength:Max get the correct value for that
62
+ # parameter.
63
+ def run_line_length_cop
64
+ puts Rainbow(PHASE_1).yellow
65
+ @options[:only] = ['Layout/LineLength']
66
+ execute_runner
67
+ @options.delete(:only)
68
+ @config_store = ConfigStore.new
69
+ # Save the todo configuration of the LineLength cop.
70
+ IO.read(ConfigLoader::AUTO_GENERATED_FILE)
71
+ .lines
72
+ .drop_while { |line| line.start_with?('#') }
73
+ .join
74
+ end
75
+
76
+ def run_all_cops(line_length_contents)
77
+ puts Rainbow(PHASE_2).yellow
78
+ result = execute_runner
79
+ # This run was made with the current maximum length allowed, so append
80
+ # the saved setting for LineLength.
81
+ File.open(ConfigLoader::AUTO_GENERATED_FILE, 'a') do |f|
82
+ f.write(line_length_contents)
83
+ end
84
+ result
85
+ end
86
+
87
+ def reset_config_and_auto_gen_file
88
+ @config_store = ConfigStore.new
89
+ @config_store.options_config = @options[:config] if @options[:config]
90
+ File.open(ConfigLoader::AUTO_GENERATED_FILE, 'w') {}
91
+ ConfigLoader.add_inheritance_from_auto_generated_file
92
+ end
93
+
94
+ def add_formatter
95
+ @options[:formatters] << [Formatter::DisabledConfigFormatter,
96
+ ConfigLoader::AUTO_GENERATED_FILE]
97
+ end
98
+
99
+ def execute_runner
100
+ Environment.new(@options, @config_store, @paths).run(:execute_runner)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CLI
5
+ module Command
6
+ # A subcommand in the CLI.
7
+ class Base
8
+ attr_reader :env
9
+
10
+ @subclasses = []
11
+
12
+ class << self
13
+ attr_accessor :command_name
14
+
15
+ def inherited(subclass)
16
+ @subclasses << subclass
17
+ end
18
+
19
+ def by_command_name(name)
20
+ @subclasses.detect { |s| s.command_name == name }
21
+ end
22
+ end
23
+
24
+ def initialize(env)
25
+ @env = env
26
+ @options = env.options
27
+ @config_store = env.config_store
28
+ @paths = env.paths
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end