The name of the module, or nil, if this is a global “component”
The path to the location of the module/component - semantics determined by subclass
A Module Loader has a private loader, it is lazily obtained on request to provide the visibility for entities contained in the module. Since a ModuleLoader also represents an environment and it is created a different way, this loader can be set explicitly by the loaders bootstrap logic.
@api private
A map of type to smart-paths that help with minimizing the number of paths to scan
Abstract method that subclasses override to answer if the given relative path exists, and if so returns that path
@param resolved_path [String] a path resolved by a smart path against the loader’s root (if it has one) @return [Boolean] true if the file exists
# File lib/puppet/pops/loader/module_loaders.rb, line 151 def existing_path(resolved_path) raise NotImplementedError.new end
Finds typed/named entity in this module @param typed_name [Puppet::Pops::Loader::TypedName] the type/name to find @return [Puppet::Pops::Loader::Loader::NamedEntry, nil found/created entry, or nil if not found
# File lib/puppet/pops/loader/module_loaders.rb, line 82 def find(typed_name) # Assume it is a global name, and that all parts of the name should be used when looking up name_part_index = 0 name_parts = typed_name.name_parts # Certain types and names can be disqualified up front if name_parts.size > 1 # The name is in a name space. # Then entity cannot possible be in this module unless the name starts with the module name. # Note: If "module" represents a "global component", the module_name is nil and cannot match which is # ok since such a "module" cannot have namespaced content). # return nil unless name_parts[0] == module_name # Skip the first part of the name when computing the path since the path already contains the name of the # module name_part_index = 1 else # The name is in the global name space. # The only globally name-spaced elements that may be loaded from modules are functions and resource types case typed_name.type when :function when :resource_type else # anything else cannot possibly be in this module # TODO: should not be allowed anyway... may have to revisit this decision return nil end end # Get the paths that actually exist in this module (they are lazily processed once and cached). # The result is an array (that may be empty). # Find the file to instantiate, and instantiate the entity if file is found origin = nil if (smart_path = smart_paths.effective_paths(typed_name.type).find do |sp| origin = sp.effective_path(typed_name, name_part_index) existing_path(origin) end) value = smart_path.instantiator.create(self, typed_name, origin, get_contents(origin)) # cache the entry and return it set_entry(typed_name, value, origin) else nil end end
Abstract method that subclasses override to produce the content of the effective path. It should either succeed and return a String or fail with an exception.
@param effective_path [String] a path as resolved by a smart path @return [String] the content of the file
# File lib/puppet/pops/loader/module_loaders.rb, line 161 def get_contents(effective_path) raise NotImplementedError.new end
Abstract method that subclasses override to produce a source reference String used to identify the system resource (resource in the URI sense).
@param relative_path [String] a path relative to the module’s root @return [String] a reference to the source file (in file system, zip file, or elsewhere).
# File lib/puppet/pops/loader/module_loaders.rb, line 171 def get_source_ref(relative_path) raise NotImplementedError.new end
Abstract method that subclasses override that checks if it is meaningful to search using a generic smart path. This optimization is performed to not be tricked into searching an empty directory over and over again. The implementation may perform a deep search for file content other than directories and cache this in and index. It is guaranteed that a call to meaningful_to_search? takes place before checking any other path with relative_path_exists?.
This optimization exists because many modules have been created from a template and they have empty directories for functions, types, etc. (It is also the place to create a cached index of the content).
@param smart_path [String] a path relative to the module’s root @return [Boolean] true if there is content in the directory appointed by the relative path
# File lib/puppet/pops/loader/module_loaders.rb, line 142 def meaningful_to_search?(smart_path) raise NotImplementedError.new end
Initialize a kind of ModuleLoader for one module @param parent_loader [Puppet::Pops::Loader] loader with higher priority @param #module_name [String] the name of the module (non qualified name), may be nil for a global “component” @param path [String] the path to the root of the module (semantics defined by subclass) @param loader_name [String] a name that is used for human identification (useful when #module_name is nil)
# File lib/puppet/pops/loader/module_loaders.rb, line 69 def initialize(parent_loader, loaders, module_name, path, loader_name) super parent_loader, loader_name @module_name = module_name @path = path @smart_paths = Puppet::Pops::Loader::LoaderPaths::SmartPaths.new(self) @loaders = loaders end