# encoding: utf-8
require 'optparse'
module Rubocop
# This class handles command line options.
class Options
DEFAULT_FORMATTER = 'progress'
def initialize(config_store)
@config_store = config_store
@options = {}
end
# rubocop:disable MethodLength
def parse(args)
ignore_dropped_options(args)
convert_deprecated_options(args)
OptionParser.new do |opts|
opts.banner = 'Usage: rubocop [options] [file1, file2, ...]'
opts.on('-d', '--debug', 'Display debug info.') do |d|
@options[:debug] = d
end
opts.on('-c', '--config FILE', 'Specify configuration file.') do |f|
@options[:config] = f
@config_store.set_options_config(@options[:config])
end
opts.on('--only COP', 'Run just one cop.') do |s|
@options[:only] = s
validate_only_option
end
opts.on('--auto-gen-config',
'Generate a configuration file acting as a',
'TODO list.') do
@options[:auto_gen_config] = true
@options[:formatters] = [
[DEFAULT_FORMATTER],
[Formatter::DisabledConfigFormatter,
ConfigLoader::AUTO_GENERATED_FILE]
]
validate_auto_gen_config_option(args)
end
opts.on('--show-cops',
'Shows cops and their config for the',
'current directory.') do
print_available_cops
exit(0)
end
opts.on('-f', '--format FORMATTER',
'Choose an output formatter. This option',
'can be specified multiple times to enable',
'multiple formatters at the same time.',
' [p]rogress (default)',
' [s]imple',
' [c]lang',
' [e]macs',
' [j]son',
' [f]iles',
' [o]ffences',
' custom formatter class name') do |key|
@options[:formatters] ||= []
@options[:formatters] << [key]
end
opts.on('-o', '--out FILE',
'Write output to a file instead of STDOUT.',
'This option applies to the previously',
'specified --format, or the default format',
'if no format is specified.') do |path|
@options[:formatters] ||= [[DEFAULT_FORMATTER]]
@options[:formatters].last << path
end
opts.on('-r', '--require FILE', 'Require Ruby file.') do |f|
require f
end
opts.on('-R', '--rails', 'Run extra Rails cops.') do |r|
@options[:rails] = r
end
opts.on('-l', '--lint', 'Run only lint cops.') do |l|
@options[:lint] = l
end
opts.on('-a', '--auto-correct', 'Auto-correct offences.') do |a|
@options[:autocorrect] = a
end
opts.on('-n', '--no-color', 'Disable color output.') do |s|
Sickill::Rainbow.enabled = false
end
opts.on('-v', '--version', 'Display version.') do
puts Rubocop::Version.version(false)
exit(0)
end
opts.on('-V', '--verbose-version', 'Display verbose version.') do
puts Rubocop::Version.version(true)
exit(0)
end
end.parse!(args)
target_files = target_finder.find(args)
[@options, target_files]
end
# rubocop:enable MethodLength
private
def ignore_dropped_options(args)
# Currently we don't make -s/--silent option raise error
# since those are mostly used by external tools.
rejected = args.reject! { |a| %w(-s --silent).include?(a) }
if rejected
warn '-s/--silent options is dropped. ' +
'`emacs` and `files` formatters no longer display summary.'
end
end
def convert_deprecated_options(args)
args.map! do |arg|
case arg
when '-e', '--emacs'
deprecate("#{arg} option", '--format emacs', '1.0.0')
%w(--format emacs)
else
arg
end
end.flatten!
end
def deprecate(subject, alternative = nil, version = nil)
message = "#{subject} is deprecated"
message << " and will be removed in RuboCop #{version}" if version
message << '.'
message << " Please use #{alternative} instead." if alternative
warn message
end
def validate_only_option
if Cop::Cop.all.none? { |c| c.cop_name == @options[:only] }
fail ArgumentError, "Unrecognized cop name: #{@options[:only]}."
end
end
def validate_auto_gen_config_option(args)
if args.any?
fail ArgumentError,
'--auto-gen-config can not be combined with any other arguments.'
end
target_finder.find(args).each do |file|
config = @config_store.for(file)
if @options[:auto_gen_config] && config.contains_auto_generated_config
fail "Remove #{ConfigLoader::AUTO_GENERATED_FILE} from the " +
'current configuration before generating it again.'
end
end
end
def target_finder
@target_finder ||= TargetFinder.new(@config_store, @options[:debug])
end
def print_available_cops
cops = Cop::Cop.all
puts "Available cops (#{cops.length}) + config for #{Dir.pwd.to_s}: "
dirconf = @config_store.for(Dir.pwd.to_s)
cops.types.sort!.each do |type|
coptypes = cops.with_type(type).sort_by!(&:cop_name)
puts "Type '#{type.to_s.capitalize}' (#{coptypes.size}):"
coptypes.each do |cop|
puts " - #{cop.cop_name}"
cnf = dirconf.for_cop(cop).dup
print_conf_option('Description',
cnf.delete('Description') { 'None' })
cnf.each { |k, v| print_conf_option(k, v) }
print_conf_option('SupportsAutoCorrection',
cop.new.support_autocorrect?.to_s)
end
end
end
def print_conf_option(option, value)
puts " - #{option}: #{value}"
end
end
end