class RuboCop::OptionsValidator

Validates option arguments and the options’ compatibility with each other.

def boolean_or_empty_cache?

def boolean_or_empty_cache?
  !@options.key?(:cache) || %w[true false].include?(@options[:cache])
end

def except_syntax?

def except_syntax?
  @options.key?(:except) &&
    (@options[:except] & %w[Lint/Syntax Syntax]).any?
end

def format_message_from(name, cop_names)

def format_message_from(name, cop_names)
  message = 'Unrecognized cop or department: %<name>s.'
  message_with_candidate = "%<message>s\nDid you mean? %<candidate>s"
  corrections = cop_names.select do |cn|
    score = StringUtil.similarity(cn, name)
    score >= NameSimilarity::MINIMUM_SIMILARITY_TO_SUGGEST
  end.sort
  if corrections.empty?
    format(message, name: name)
  else
    format(message_with_candidate, message: format(message, name: name),
                                   candidate: corrections.join(', '))
  end
end

def incompatible_options

def incompatible_options
  @incompatible_options ||= @options.keys & Options::EXITING_OPTIONS
end

def initialize(options)

def initialize(options)
  @options = options
end

def only_includes_unneeded_disable?

def only_includes_unneeded_disable?
  @options.key?(:only) &&
    (@options[:only] & %w[Lint/UnneededCopDisableDirective
                          UnneededCopDisableDirective]).any?
end

def validate_auto_gen_config

def validate_auto_gen_config
  return if @options.key?(:auto_gen_config)
  message = '--%<flag>s can only be used together with --auto-gen-config.'
  %i[exclude_limit no_offense_counts no_auto_gen_timestamp].each do |option|
    if @options.key?(option)
      raise ArgumentError, format(message, flag: option.to_s.tr('_', '-'))
    end
  end
end

def validate_compatibility # rubocop:disable Metrics/MethodLength

rubocop:disable Metrics/MethodLength
def validate_compatibility # rubocop:disable Metrics/MethodLength
  if only_includes_unneeded_disable?
    raise ArgumentError, 'Lint/UnneededCopDisableDirective can not ' \
                         'be used with --only.'
  end
  if except_syntax?
    raise ArgumentError, 'Syntax checking can not be turned off.'
  end
  unless boolean_or_empty_cache?
    raise ArgumentError, '-C/--cache argument must be true or false'
  end
  validate_auto_gen_config
  validate_parallel
  return if incompatible_options.size <= 1
  raise ArgumentError, 'Incompatible cli options: ' \
                       "#{incompatible_options.inspect}"
end

def validate_cop_list(names)

called from within Options.
Cop name validation must be done later than option parsing, so it's not
def validate_cop_list(names)
  return unless names
  cop_names = Cop::Cop.registry.names
  departments = Cop::Cop.registry.departments.map(&:to_s)
  names.each do |name|
    next if cop_names.include?(name)
    next if departments.include?(name)
    next if %w[Syntax Lint/Syntax].include?(name)
    raise IncorrectCopNameError, format_message_from(name, cop_names)
  end
end

def validate_exclude_limit_option

def validate_exclude_limit_option
  return if @options[:exclude_limit] =~ /^\d+$/
  # Emulate OptionParser's behavior to make failures consistent regardless
  # of option order.
  raise OptionParser::MissingArgument
end

def validate_parallel

def validate_parallel
  return unless @options.key?(:parallel)
  if @options[:cache] == 'false'
    raise ArgumentError, '-P/--parallel uses caching to speed up ' \
                         'execution, so combining with --cache false is ' \
                         'not allowed.'
  end
  combos = {
    auto_gen_config: '-P/--parallel uses caching to speed up execution, ' \
                     'while --auto-gen-config needs a non-cached run, ' \
                     'so they cannot be combined.',
    fail_fast: '-P/--parallel can not be combined with -F/--fail-fast.',
    auto_correct: '-P/--parallel can not be combined with --auto-correct.'
  }
  combos.each { |key, msg| raise ArgumentError, msg if @options.key?(key) }
end