class Puppet::Pops::Loader::ModuleLoaders::AbstractPathBasedModuleLoader

Attributes

module_name[R]

The name of the module, or nil, if this is a global “component”

path[R]

The path to the location of the module/component - semantics determined by subclass

private_loader[RW]

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

smart_paths[R]

A map of type to smart-paths that help with minimizing the number of paths to scan

Public Instance Methods

existing_path(resolved_path) click to toggle source

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
find(typed_name) click to toggle source

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
get_contents(effective_path) click to toggle source

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
get_source_ref(relative_path) click to toggle source

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
meaningful_to_search?(smart_path) click to toggle source

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

Public Class Methods

new(parent_loader, loaders, module_name, path, loader_name) click to toggle source

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