class LegacyFacter::Util::Loader

Public Class Methods

new(environment_vars = ENV) click to toggle source
# File lib/facter/custom_facts/util/loader.rb, line 7
def initialize(environment_vars = ENV)
  @loaded = []
  @environment_vars = environment_vars
end

Public Instance Methods

load(fact) click to toggle source

Load all resolutions for a single fact.

@api public @param name [Symbol]

# File lib/facter/custom_facts/util/loader.rb, line 16
def load(fact)
  # Now load from the search path
  shortname = fact.to_s.downcase
  load_env(shortname)

  filename = shortname + '.rb'

  paths = search_path
  paths&.each do |dir|
    # Load individual files
    file = File.join(dir, filename)

    load_file(file) if FileTest.file?(file)
  end
end
load_all() click to toggle source

Load all facts from all directories.

@api public

# File lib/facter/custom_facts/util/loader.rb, line 35
def load_all
  return if defined?(@loaded_all)

  load_env

  paths = search_path
  paths&.each do |dir|
    # clean the search path of wrong slashes and backslashes
    dir = dir.gsub(%r{[\/\\]+}, File::SEPARATOR)
    # dir is already an absolute path
    Dir.glob(File.join(dir, '*.rb')).each do |path|
      # exclude dirs that end with .rb
      load_file(path) if FileTest.file?(path)
    end
  end

  @loaded_all = true
end
search_path() click to toggle source

List directories to search for fact files.

Search paths are gathered from the following sources:

  1. $LOAD_PATH entries are expanded to absolute paths

  2. ENV is split and used verbatim

  3. Entries from Facter.search_path are used verbatim

A warning will be generated for paths in Facter.search_path that are not absolute directories.

@api public @return [Array<String>]

# File lib/facter/custom_facts/util/loader.rb, line 67
def search_path
  search_paths = []
  search_paths += $LOAD_PATH.map { |path| File.expand_path('facter', path) }

  if @environment_vars.include?('FACTERLIB')
    search_paths += @environment_vars['FACTERLIB'].split(File::PATH_SEPARATOR)
  end

  search_paths.delete_if { |path| !valid_search_path?(path) }

  Facter::Options.custom_dir.each do |path|
    if valid_search_path?(path)
      search_paths << path
    else
      LegacyFacter.warn "Excluding #{path} from search path. Fact file paths must be an absolute directory"
    end
  end

  search_paths.delete_if { |path| !File.directory?(path) }

  search_paths.uniq
end

Private Instance Methods

kernel_load(file) click to toggle source

Load and execute the Ruby program specified in the file. This exists for testing purposes.

@api private @return [Boolean]

# File lib/facter/custom_facts/util/loader.rb, line 128
def kernel_load(file)
  Kernel.load(file)
end
load_env(fact = nil) click to toggle source

Load facts from the environment. If no name is provided, all will be loaded.

# File lib/facter/custom_facts/util/loader.rb, line 134
def load_env(fact = nil)
  # Load from the environment, if possible
  @environment_vars.each do |name, value|
    # Skip anything that doesn't match our regex.
    next unless name =~ /^facter_?(\w+)$/i

    env_name = Regexp.last_match(1)

    # If a fact name was specified, skip anything that doesn't
    # match it.
    next if fact && (env_name != fact)

    LegacyFacter.add(Regexp.last_match(1), fact_type: :external, is_env: true) do
      has_weight 1_000_000
      setcode { value }
    end

    # Short-cut, if we are only looking for one value.
    break if fact
  end
end
load_file(file) click to toggle source

Load a file and record is paths to prevent duplicate loads.

@api private @params file [String] The *absolute path* to the file to load

# File lib/facter/custom_facts/util/loader.rb, line 105
def load_file(file)
  return if @loaded.include? file

  # We have to specify Kernel.load, because we have a load method.
  begin
    # Store the file path so we don't try to reload it
    @loaded << file
    kernel_load(file)
  rescue ScriptError => e
    # Don't store the path if the file can't be loaded
    # in case it's loadable later on.
    @loaded.delete(file)
    Facter.log_exception(e, "Error loading fact #{file}: #{e.message}")
  rescue StandardError => e
    Facter.log_exception(e, "error while resolving custom facts in #{file} #{e.message}")
  end
end
valid_search_path?(path) click to toggle source

Validate that the given path is valid, ie it is an absolute path.

@api private @param path [String] @return [Boolean]

# File lib/facter/custom_facts/util/loader.rb, line 97
def valid_search_path?(path)
  Pathname.new(path).absolute?
end