class Facter::Util::Loader
Load facts on demand.
Public Class Methods
# File lib/facter/util/loader.rb, line 8 def initialize(environment_vars = ENV) @loaded = [] @environment_vars = environment_vars end
Public Instance Methods
Load all resolutions for a single fact.
@api public @param name [Symbol]
# File lib/facter/util/loader.rb, line 17 def load(fact) # Now load from the search path shortname = fact.to_s.downcase load_env(shortname) filename = shortname + ".rb" paths = search_path unless paths.nil? paths.each do |dir| # Load individual files file = File.join(dir, filename) load_file(file) if File.file?(file) end end end
Load all facts from all directories.
@api public
# File lib/facter/util/loader.rb, line 38 def load_all return if defined?(@loaded_all) load_env paths = search_path unless paths.nil? paths.each do |dir| # 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 File.file?(path) end end end @loaded_all = true end
List directories to search for fact files.
Search paths are gathered from the following sources:
-
$LOAD_PATH entries are expanded to absolute paths
-
ENV is split and used verbatim
-
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/util/loader.rb, line 70 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.search_path.each do |path| if valid_search_path?(path) search_paths << path else Facter.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
Load and execute the Ruby program specified in the file. This exists for testing purposes.
@api private @return [Boolean]
# File lib/facter/util/loader.rb, line 129 def kernel_load(file) Kernel.load(file) end
Load facts from the environment. If no name is provided, all will be loaded.
# File lib/facter/util/loader.rb, line 135 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 = $1 # If a fact name was specified, skip anything that doesn't # match it. next if fact and env_name != fact Facter.add($1) 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 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/util/loader.rb, line 108 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 => detail # 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(detail, "Error loading fact #{file}: #{detail.message}") end end
Validate that the given path is valid, ie it is an absolute path.
@api private @param path [String] @return [Boolean]
# File lib/facter/util/loader.rb, line 100 def valid_search_path?(path) Pathname.new(path).absolute? end