class RuboCop::Config

directories are inspected.
during a run of the rubocop program, if files in several
file from which it was read. Several different Configs can be used
and all its cops. A Config is associated with a YAML configuration
This class represents the configuration of the RuboCop application

def add_excludes_from_higher_level(highest_config)

def add_excludes_from_higher_level(highest_config)
  return unless highest_config.for_all_cops['Exclude']
  excludes = for_all_cops['Exclude'] ||= []
  highest_config.for_all_cops['Exclude'].each do |path|
    unless path.is_a?(Regexp) || absolute?(path)
      path = File.join(File.dirname(highest_config.loaded_path), path)
    end
    excludes << path unless excludes.include?(path)
  end
end

def add_missing_namespaces

def add_missing_namespaces
  keys.each do |k|
    q = Cop::Cop.qualified_cop_name(k, loaded_path)
    next if q == k
    self[q] = self[k]
    delete(k)
  end
end

def base_dir_for_path_parameters

directory since that wouldn't work.
config/default.yml, for example, are not relative to RuboCop's config
relative to the current directory. This is so that paths in
to the directory where that file is. Paths in other config files are
Paths specified in .rubocop.yml and .rubocop_todo.yml files are relative
def base_dir_for_path_parameters
  config_files = [ConfigLoader::DOTFILE, ConfigLoader::AUTO_GENERATED_FILE]
  @base_dir_for_path_parameters ||=
    if config_files.include?(File.basename(loaded_path)) &&
       loaded_path != File.join(Dir.home, ConfigLoader::DOTFILE)
      File.expand_path(File.dirname(loaded_path))
    else
      Dir.pwd
    end
end

def check_obsolete_parameter(cop, parameter, alternative = nil)

def check_obsolete_parameter(cop, parameter, alternative = nil)
  if self[cop] && self[cop].key?(parameter)
    raise ValidationError, "obsolete parameter #{parameter} (for #{cop}) " \
                          "found in #{loaded_path}" \
                          "#{"\n" if alternative}#{alternative}"
  end
end

def check_target_ruby

def check_target_ruby
  return unless target_ruby_version
  unless KNOWN_RUBIES.include?(target_ruby_version)
    msg = "Unknown Ruby version #{target_ruby_version.inspect} found "
    msg +=
      case @target_ruby_version_source
      when :dot_ruby_version
        'in `.ruby-version`.'
      when :rubocop_yml
        "in `TargetRubyVersion` parameter (in #{loaded_path})." \
      end
    msg += "\nKnown versions: #{KNOWN_RUBIES.join(', ')}"
    raise ValidationError, msg
  end
end

def cop_enabled?(cop)

def cop_enabled?(cop)
  department = cop.cop_type.to_s.capitalize!
  if (dept_config = self[department])
    return false if dept_config['Enabled'] == false
  end
  for_cop(cop).empty? || for_cop(cop)['Enabled']
end

def deprecation_check

def deprecation_check
  %w(Exclude Include).each do |key|
    plural = "#{key}s"
    next unless for_all_cops[plural]
    for_all_cops[key] = for_all_cops[plural] # Stay backwards compatible.
    for_all_cops.delete(plural)
    yield "AllCops/#{plural} was renamed to AllCops/#{key}"
  end
end

def file_to_exclude?(file)

def file_to_exclude?(file)
  file = File.expand_path(file)
  patterns_to_exclude.any? do |pattern|
    match_path?(pattern, file)
  end
end

def file_to_include?(file)

def file_to_include?(file)
  relative_file_path = path_relative_to_config(file)
  # Optimization to quickly decide if the given file is hidden (on the top
  # level) and can not be matched by any pattern.
  is_hidden = relative_file_path.start_with?('.') &&
              !relative_file_path.start_with?('..')
  return false if is_hidden && !possibly_include_hidden?
  absolute_file_path = File.expand_path(file)
  patterns_to_include.any? do |pattern|
    match_path?(pattern, relative_file_path) ||
      match_path?(pattern, absolute_file_path)
  end
end

def for_all_cops

def for_all_cops
  @for_all_cops ||= self['AllCops'] || {}
end

def for_cop(cop)

def for_cop(cop)
  @for_cop[cop.respond_to?(:cop_name) ? cop.cop_name : cop]
end

def initialize(hash = {}, loaded_path = nil)

def initialize(hash = {}, loaded_path = nil)
  @loaded_path = loaded_path
  @for_cop = Hash.new do |h, cop|
    h[cop] = self[Cop::Cop.qualified_cop_name(cop, loaded_path)] || {}
  end
  replace(hash)
end

def make_excludes_absolute

def make_excludes_absolute
  each_key do |key|
    validate_section_presence(key)
    next unless self[key]['Exclude']
    self[key]['Exclude'].map! do |exclude_elem|
      if exclude_elem.is_a?(String) && !absolute?(exclude_elem)
        File.expand_path(File.join(base_dir_for_path_parameters,
                                   exclude_elem))
      else
        exclude_elem
      end
    end
  end
end

def path_relative_to_config(path)

def path_relative_to_config(path)
  relative_path(path, base_dir_for_path_parameters)
end

def patterns_to_exclude

def patterns_to_exclude
  @patterns_to_exclude ||= for_all_cops['Exclude']
end

def patterns_to_include

def patterns_to_include
  @patterns_to_include ||= for_all_cops['Include']
end

def possibly_include_hidden?

files, false if that's definitely not possible.
Returns true if there's a chance that an Include pattern matches hidden
def possibly_include_hidden?
  @possibly_include_hidden ||= patterns_to_include.any? do |s|
    s.is_a?(Regexp) || s.start_with?('.') || s.include?('/.')
  end
end

def reject_obsolete_cops

def reject_obsolete_cops
  OBSOLETE_COPS.each do |cop_name, message|
    next unless key?(cop_name) || key?(cop_name.split('/').last)
    message += "\n(obsolete configuration found in #{loaded_path}, please" \
               ' update it)'
    raise ValidationError, message
  end
end

def reject_obsolete_parameters

def reject_obsolete_parameters
  check_obsolete_parameter('Style/SpaceAroundOperators',
                           'MultiSpaceAllowedForOperators',
                           'If your intention was to allow extra spaces ' \
                           'for alignment, please use AllowForAlignment: ' \
                           'true instead.')
  check_obsolete_parameter('AllCops', 'RunRailsCops',
                           "Use the following configuration instead:\n" \
                           "Rails:\n  Enabled: true")
end

def target_ruby_version

def target_ruby_version
  @target_ruby_version ||=
    if File.file?('.ruby-version')
      @target_ruby_version_source = :dot_ruby_version
      File.read('.ruby-version').to_f
    else
      @target_ruby_version_source = :rubocop_yml
      for_all_cops['TargetRubyVersion']
    end
end

def validate

def validate
  # Don't validate RuboCop's own files. Avoids infinite recursion.
  base_config_path = File.expand_path(File.join(ConfigLoader::RUBOCOP_HOME,
                                                'config'))
  return if File.expand_path(loaded_path).start_with?(base_config_path)
  valid_cop_names, invalid_cop_names = keys.partition do |key|
    ConfigLoader.default_configuration.key?(key)
  end
  reject_obsolete_cops
  warn_about_unrecognized_cops(invalid_cop_names)
  reject_obsolete_parameters
  check_target_ruby
  validate_parameter_names(valid_cop_names)
  validate_enforced_styles(valid_cop_names)
end

def validate_enforced_styles(valid_cop_names)

def validate_enforced_styles(valid_cop_names)
  valid_cop_names.each do |name|
    next unless (style = self[name]['EnforcedStyle'])
    valid = ConfigLoader.default_configuration[name]['SupportedStyles']
    next if valid.include?(style)
    msg = "invalid EnforcedStyle '#{style}' for #{name} found in " \
          "#{loaded_path}\n" \
          "Valid choices are: #{valid.join(', ')}"
    raise ValidationError, msg
  end
end

def validate_parameter_names(valid_cop_names)

def validate_parameter_names(valid_cop_names)
  valid_cop_names.each do |name|
    validate_section_presence(name)
    self[name].each_key do |param|
      next if COMMON_PARAMS.include?(param) ||
              ConfigLoader.default_configuration[name].key?(param)
      warn Rainbow("Warning: unrecognized parameter #{name}:#{param} " \
                   "found in #{loaded_path}").yellow
    end
  end
end

def validate_section_presence(name)

def validate_section_presence(name)
  return unless key?(name) && self[name].nil?
  raise ValidationError, "empty section #{name} found in #{loaded_path}"
end

def warn_about_unrecognized_cops(invalid_cop_names)

def warn_about_unrecognized_cops(invalid_cop_names)
  invalid_cop_names.each do |name|
    if name == 'Syntax'
      raise ValidationError,
            "configuration for Syntax cop found in #{loaded_path}\n" \
            'This cop cannot be configured.'
    end
    # There could be a custom cop with this name. If so, don't warn
    next if Cop::Cop.all.any? { |c| c.match?([name]) }
    warn Rainbow("Warning: unrecognized cop #{name} found in " \
                 "#{loaded_path}").yellow
  end
end