class RuboCop::CLI
The CLI
is a class responsible of handling all the command line interface logic.
Constants
- PHASE_1
- PHASE_1_DISABLED
- PHASE_1_OVERRIDDEN
- PHASE_2
- STATUS_ERROR
- STATUS_INTERRUPTED
- STATUS_OFFENSES
- STATUS_SUCCESS
Attributes
config_store[R]
options[R]
Public Class Methods
new()
click to toggle source
# File lib/rubocop/cli.rb, line 27 def initialize @options = {} @config_store = ConfigStore.new end
Public Instance Methods
run(args = ARGV)
click to toggle source
@api public
Entry point for the application logic. Here we do the command line arguments processing and inspect the target files.
@param args [Array<String>] command line arguments @return [Integer] UNIX exit code
rubocop:disable Metrics/MethodLength, Metrics/AbcSize
# File lib/rubocop/cli.rb, line 42 def run(args = ARGV) @options, paths = Options.new.parse(args) if @options[:init] init_dotfile else validate_options_vs_config act_on_options apply_default_formatter execute_runners(paths) end rescue ConfigNotFoundError, IncorrectCopNameError, OptionArgumentError => e warn e.message STATUS_ERROR rescue RuboCop::Error => e warn Rainbow("Error: #{e.message}").red STATUS_ERROR rescue Finished STATUS_SUCCESS rescue OptionParser::InvalidOption => e warn e.message warn 'For usage information, use --help' STATUS_ERROR rescue StandardError, SyntaxError, LoadError => e warn e.message warn e.backtrace STATUS_ERROR end
Private Instance Methods
act_on_options()
click to toggle source
# File lib/rubocop/cli.rb, line 187 def act_on_options ConfigLoader.debug = @options[:debug] ConfigLoader.auto_gen_config = @options[:auto_gen_config] ConfigLoader.ignore_parent_exclusion = @options[:ignore_parent_exclusion] ConfigLoader.options_config = @options[:config] @config_store.options_config = @options[:config] if @options[:config] @config_store.force_default_config! if @options[:force_default_config] handle_exiting_options if @options[:color] # color output explicitly forced on Rainbow.enabled = true elsif @options[:color] == false # color output explicitly forced off Rainbow.enabled = false end end
apply_default_formatter()
click to toggle source
# File lib/rubocop/cli.rb, line 235 def apply_default_formatter # This must be done after the options have already been processed, # because they can affect how ConfigStore behaves @options[:formatters] ||= begin if @options[:auto_gen_config] formatter = 'autogenconf' else cfg = @config_store.for(Dir.pwd).for_all_cops formatter = cfg['DefaultFormatter'] || 'progress' end [[formatter, @options[:output_path]]] end return unless @options[:auto_gen_config] @options[:formatters] << [Formatter::DisabledConfigFormatter, ConfigLoader::AUTO_GENERATED_FILE] end
config_lines(cop)
click to toggle source
# File lib/rubocop/cli.rb, line 300 def config_lines(cop) cnf = @config_store.for(Dir.pwd).for_cop(cop) cnf.to_yaml.lines.to_a.drop(1).map { |line| ' ' + line } end
cops_of_department(cops, department)
click to toggle source
# File lib/rubocop/cli.rb, line 296 def cops_of_department(cops, department) cops.with_department(department).sort! end
display_error_summary(errors)
click to toggle source
# File lib/rubocop/cli.rb, line 313 def display_error_summary(errors) return if errors.empty? warn Rainbow("\n#{pluralize(errors.size, 'error')} occurred:").red errors.each { |error| warn error } warn <<~WARNING Errors are usually caused by RuboCop bugs. Please, report your problems to RuboCop's issue tracker. #{Gem.loaded_specs['rubocop'].metadata['bug_tracker_uri']} Mention the following information in the issue report: #{RuboCop::Version.version(true)} WARNING end
display_warning_summary(warnings)
click to toggle source
# File lib/rubocop/cli.rb, line 305 def display_warning_summary(warnings) return if warnings.empty? warn Rainbow("\n#{pluralize(warnings.size, 'warning')}:").yellow warnings.each { |warning| warn warning } end
execute_runner(paths)
click to toggle source
# File lib/rubocop/cli.rb, line 207 def execute_runner(paths) runner = Runner.new(@options, @config_store) all_passed = runner.run(paths) display_warning_summary(runner.warnings) display_error_summary(runner.errors) maybe_print_corrected_source all_pass_or_excluded = all_passed || @options[:auto_gen_config] if runner.aborting? STATUS_INTERRUPTED elsif all_pass_or_excluded && runner.errors.empty? STATUS_SUCCESS else STATUS_OFFENSES end end
execute_runners(paths)
click to toggle source
rubocop:enable Metrics/MethodLength, Metrics/AbcSize
# File lib/rubocop/cli.rb, line 74 def execute_runners(paths) if @options[:auto_gen_config] reset_config_and_auto_gen_file line_length_contents = maybe_run_line_length_cop(paths) run_all_cops_auto_gen_config(line_length_contents, paths) else execute_runner(paths) end end
handle_exiting_options()
click to toggle source
# File lib/rubocop/cli.rb, line 226 def handle_exiting_options return unless Options::EXITING_OPTIONS.any? { |o| @options.key? o } puts RuboCop::Version.version(false) if @options[:version] puts RuboCop::Version.version(true) if @options[:verbose_version] print_available_cops if @options[:show_cops] raise Finished end
init_dotfile()
click to toggle source
# File lib/rubocop/cli.rb, line 140 def init_dotfile path = File.expand_path(ConfigLoader::DOTFILE) if File.exist?(ConfigLoader::DOTFILE) warn Rainbow("#{ConfigLoader::DOTFILE} already exists at #{path}").red STATUS_ERROR else description = <<~DESC # The behavior of RuboCop can be controlled via the .rubocop.yml # configuration file. It makes it possible to enable/disable # certain cops (checks) and to alter their behavior if they accept # any parameters. The file can be placed either in your home # directory or in some project directory. # # RuboCop will start looking for the configuration file in the directory # where the inspected file is and continue its way up to the root directory. # # See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md DESC File.open(ConfigLoader::DOTFILE, 'w') do |f| f.write(description) end puts "Writing new #{ConfigLoader::DOTFILE} to #{path}" STATUS_SUCCESS end end
line_length_cop(config)
click to toggle source
# File lib/rubocop/cli.rb, line 110 def line_length_cop(config) config.for_cop('Metrics/LineLength') end
line_length_enabled?(config)
click to toggle source
# File lib/rubocop/cli.rb, line 98 def line_length_enabled?(config) line_length_cop(config)['Enabled'] end
max_line_length(config)
click to toggle source
# File lib/rubocop/cli.rb, line 106 def max_line_length(config) line_length_cop(config)['Max'] end
maybe_print_corrected_source()
click to toggle source
# File lib/rubocop/cli.rb, line 330 def maybe_print_corrected_source # If we are asked to autocorrect source code read from stdin, the only # reasonable place to write it is to stdout # Unfortunately, we also write other information to stdout # So a delimiter is needed for tools to easily identify where the # autocorrected source begins return unless @options[:stdin] && @options[:auto_correct] puts '=' * 20 print @options[:stdin] end
maybe_run_line_length_cop(paths)
click to toggle source
# File lib/rubocop/cli.rb, line 84 def maybe_run_line_length_cop(paths) if !line_length_enabled?(@config_store.for(Dir.pwd)) puts Rainbow("#{PHASE_1} #{PHASE_1_DISABLED}").yellow '' elsif !same_max_line_length?( @config_store.for(Dir.pwd), ConfigLoader.default_configuration ) puts Rainbow("#{PHASE_1} #{PHASE_1_OVERRIDDEN}").yellow '' else run_line_length_cop_auto_gen_config(paths) end end
print_available_cops()
click to toggle source
# File lib/rubocop/cli.rb, line 254 def print_available_cops # Load the configs so the require()s are done for custom cops @config_store.for(Dir.pwd) registry = Cop::Cop.registry show_all = @options[:show_cops].empty? if show_all puts "# Available cops (#{registry.length}) + config for #{Dir.pwd}: " end registry.departments.sort!.each do |department| print_cops_of_department(registry, department, show_all) end end
print_cop_details(cops)
click to toggle source
# File lib/rubocop/cli.rb, line 281 def print_cop_details(cops) cops.each do |cop| puts '# Supports --auto-correct' if cop.new.support_autocorrect? puts "#{cop.cop_name}:" puts config_lines(cop) puts end end
print_cops_of_department(registry, department, show_all)
click to toggle source
# File lib/rubocop/cli.rb, line 269 def print_cops_of_department(registry, department, show_all) selected_cops = if show_all cops_of_department(registry, department) else selected_cops_of_department(registry, department) end puts "# Department '#{department}' (#{selected_cops.length}):" if show_all print_cop_details(selected_cops) end
reset_config_and_auto_gen_file()
click to toggle source
# File lib/rubocop/cli.rb, line 171 def reset_config_and_auto_gen_file @config_store = ConfigStore.new @config_store.options_config = @options[:config] if @options[:config] File.open(ConfigLoader::AUTO_GENERATED_FILE, 'w') {} ConfigLoader.add_inheritance_from_auto_generated_file end
run_all_cops_auto_gen_config(line_length_contents, paths)
click to toggle source
# File lib/rubocop/cli.rb, line 129 def run_all_cops_auto_gen_config(line_length_contents, paths) puts Rainbow(PHASE_2).yellow result = execute_runner(paths) # This run was made with the current maximum length allowed, so append # the saved setting for LineLength. File.open(ConfigLoader::AUTO_GENERATED_FILE, 'a') do |f| f.write(line_length_contents) end result end
run_line_length_cop_auto_gen_config(paths)
click to toggle source
Do an initial run with only Metrics/LineLength so that cops that depend on Metrics/LineLength:Max get the correct value for that parameter.
# File lib/rubocop/cli.rb, line 116 def run_line_length_cop_auto_gen_config(paths) puts Rainbow(PHASE_1).yellow @options[:only] = ['Metrics/LineLength'] execute_runner(paths) @options.delete(:only) @config_store = ConfigStore.new # Save the todo configuration of the LineLength cop. IO.read(ConfigLoader::AUTO_GENERATED_FILE) .lines .drop_while { |line| line.start_with?('#') } .join end
same_max_line_length?(config1, config2)
click to toggle source
# File lib/rubocop/cli.rb, line 102 def same_max_line_length?(config1, config2) max_line_length(config1) == max_line_length(config2) end
selected_cops_of_department(cops, department)
click to toggle source
# File lib/rubocop/cli.rb, line 290 def selected_cops_of_department(cops, department) cops_of_department(cops, department).select do |cop| @options[:show_cops].include?(cop.cop_name) end end
validate_options_vs_config()
click to toggle source
# File lib/rubocop/cli.rb, line 178 def validate_options_vs_config if @options[:parallel] && !@config_store.for(Dir.pwd).for_all_cops['UseCache'] raise OptionArgumentError, '-P/--parallel uses caching to speed up ' \ 'execution, so combining with AllCops: ' \ 'UseCache: false is not allowed.' end end