lib/reek/configuration/configuration_file_finder.rb in reek-4.5.1 vs lib/reek/configuration/configuration_file_finder.rb in reek-4.5.2

- old
+ new

@@ -15,45 +15,105 @@ # 3. Having a file ending with .reek in your HOME directory # # The order in which ConfigurationFileFinder tries to find such a # configuration file is exactly like above. module ConfigurationFileFinder - module_function + TOO_MANY_CONFIGURATION_FILES_MESSAGE = <<-EOS.freeze - def find_and_load(path: nil) - load_from_file(find(path: path)) - end + Error: Found multiple configuration files %s + while scanning directory %s. - # :reek:ControlParameter - def find(path: nil, current: Pathname.pwd, home: Pathname.new(Dir.home)) - path || find_by_dir(current) || find_in_dir(home) - end + Reek supports only one configuration file. You have 2 options now: + 1) Remove all offending files. + 2) Be specific about which one you want to load via the -c switch. - def find_by_dir(start) - start.ascend do |dir| - found = find_in_dir(dir) - return found if found + EOS + + class << self + # + # Finds and loads a configuration file from a given path. + # + # @return [Hash] + # + def find_and_load(path: nil) + load_from_file(find(path: path)) end - end - def find_in_dir(dir) - files = dir.children.select(&:file?).sort - files.find { |file| file.to_s.end_with?('.reek') } - end + # + # Tries to find a configuration file via: + # * given path (e.g. via cli switch) + # * ascending down from the current directory + # * looking into the home directory + # + # @return [File|nil] + # + # :reek:ControlParameter + def find(path: nil, current: Pathname.pwd, home: Pathname.new(Dir.home)) + path || find_by_dir(current) || find_in_dir(home) + end - # :reek:TooManyStatements: { max_statements: 6 } - def load_from_file(path) - return {} unless path - begin - configuration = YAML.load_file(path) || {} - rescue => error - raise ConfigFileException, "Invalid configuration file #{path}, error is #{error}" + # + # Loads a configuration file from a given path. + # Raises on invalid data. + # + # @param path [String] + # @return [Hash] + # + # :reek:TooManyStatements: { max_statements: 6 } + def load_from_file(path) + return {} unless path + begin + configuration = YAML.load_file(path) || {} + rescue => error + raise ConfigFileException, "Invalid configuration file #{path}, error is #{error}" + end + + unless configuration.is_a? Hash + raise ConfigFileException, "Invalid configuration file \"#{path}\" -- Not a hash" + end + configuration end - unless configuration.is_a? Hash - raise ConfigFileException, "Invalid configuration file \"#{path}\" -- Not a hash" + private + + # + # Recursively traverse directories down to find a configuration file. + # + # @return [File|nil] + # + def find_by_dir(start) + start.ascend do |dir| + file = find_in_dir(dir) + return file if file + end end - configuration + + # + # Checks a given directory for a configuration file and returns it. + # Raises an exception if we find more than one. + # + # @return [File|nil] + # + # :reek:FeatureEnvy + def find_in_dir(dir) + found = dir.children.select { |item| item.file? && item.to_s.end_with?('.reek') }.sort + if found.size > 1 + escalate_too_many_configuration_files found, dir + else + found.first + end + end + + # + # Writes a proper warning message to STDERR and then exits the program. + # + # @return [undefined] + # + def escalate_too_many_configuration_files(found, directory) + offensive_files = found.map { |file| "'#{file.basename}'" }.join(', ') + warn format(TOO_MANY_CONFIGURATION_FILES_MESSAGE, offensive_files, directory) + exit 1 + end end end end end