lib/rubocop/config_finder.rb
# frozen_string_literal: true
require_relative 'file_finder'
module RuboCop
# This class has methods related to finding configuration path.
# @api private
class ConfigFinder
DOTFILE = '.rubocop.yml'
XDG_CONFIG = 'config.yml'
RUBOCOP_HOME = File.realpath(File.join(File.dirname(__FILE__), '..', '..'))
DEFAULT_FILE = File.join(RUBOCOP_HOME, 'config', 'default.yml')
class << self
include FileFinder
attr_writer :project_root
def find_config_path(target_dir)
find_project_dotfile(target_dir) || find_project_root_dot_config ||
find_user_dotfile || find_user_xdg_config || DEFAULT_FILE
end
# Returns the path RuboCop inferred as the root of the project. No file
# searches will go past this directory.
def project_root
@project_root ||= find_project_root
end
private
def find_project_root
pwd = Dir.pwd
gems_file = find_last_file_upwards('Gemfile', pwd) || find_last_file_upwards('gems.rb', pwd)
return unless gems_file
File.dirname(gems_file)
end
def find_project_dotfile(target_dir)
find_file_upwards(DOTFILE, target_dir, project_root)
end
def find_project_root_dot_config
return unless project_root
dotfile = File.join(project_root, '.config', DOTFILE)
return dotfile if File.exist?(dotfile)
xdg_config = File.join(project_root, '.config', 'rubocop', XDG_CONFIG)
xdg_config if File.exist?(xdg_config)
end
def find_user_dotfile
return unless ENV.key?('HOME')
file = File.join(Dir.home, DOTFILE)
file if File.exist?(file)
end
def find_user_xdg_config
xdg_config_home = expand_path(ENV.fetch('XDG_CONFIG_HOME', '~/.config'))
xdg_config = File.join(xdg_config_home, 'rubocop', XDG_CONFIG)
xdg_config if File.exist?(xdg_config)
end
def expand_path(path)
File.expand_path(path)
rescue ArgumentError
# Could happen because HOME or ID could not be determined. Fall back on
# using the path literally in that case.
path
end
end
end
end