Class: Puppet::Pops::Loader::ModuleLoaders::AbstractPathBasedModuleLoader Private

Inherits:
BaseLoader show all
Defined in:
lib/puppet/pops/loader/module_loaders.rb

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Direct Known Subclasses

FileBased

Constant Summary

Constants inherited from Loader

Loader::LOADABLE_KINDS

Instance Attribute Summary collapse

Attributes inherited from BaseLoader

#loader_name, #parent

Instance Method Summary collapse

Methods inherited from BaseLoader

#add_entry, #get_entry, #load_typed, #promote_entry, #set_entry

Methods inherited from Loader

#[], #get_entry, #load, #load_typed, #parent, #set_entry

Constructor Details

#initialize(parent_loader, loaders, module_name, path, loader_name, loadables) ⇒ AbstractPathBasedModuleLoader

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initialize a kind of ModuleLoader for one module

Parameters:

  • parent_loader (Puppet::Pops::Loader)

    loader with higher priority

  • module_name (String)

    the name of the module (non qualified name), may be nil for a global “component”

  • path (String)

    the path to the root of the module (semantics defined by subclass)

  • loader_name (String)

    a name that is used for human identification (useful when module_name is nil)



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/puppet/pops/loader/module_loaders.rb', line 72

def initialize(parent_loader, loaders, module_name, path, loader_name, loadables)
  super parent_loader, loader_name

  @module_name = module_name
  @path = path
  @smart_paths = Puppet::Pops::Loader::LoaderPaths::SmartPaths.new(self)
  @loaders = loaders
  @loadables = loadables
  unless (loadables - LOADABLE_KINDS).empty?
    raise ArgumentError, 'given loadables are not of supported loadable kind'
  end
end

Instance Attribute Details

#module_nameObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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



51
52
53
# File 'lib/puppet/pops/loader/module_loaders.rb', line 51

def module_name
  @module_name
end

#pathObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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



54
55
56
# File 'lib/puppet/pops/loader/module_loaders.rb', line 54

def path
  @path
end

#private_loaderObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Produces the private loader for the module. If this module is not already resolved, this will trigger resolution



64
65
66
# File 'lib/puppet/pops/loader/module_loaders.rb', line 64

def private_loader
  @private_loader
end

#smart_pathsObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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



57
58
59
# File 'lib/puppet/pops/loader/module_loaders.rb', line 57

def smart_paths
  @smart_paths
end

Instance Method Details

#existing_path(resolved_path) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Abstract method that subclasses override to answer if the given relative path exists, and if so returns that path

Parameters:

  • resolved_path (String)

    a path resolved by a smart path against the loader’s root (if it has one)

Returns:

  • (Boolean)

    true if the file exists

Raises:

  • (NotImplementedError)


162
163
164
# File 'lib/puppet/pops/loader/module_loaders.rb', line 162

def existing_path(resolved_path)
  raise NotImplementedError.new
end

#find(typed_name) ⇒ Puppet::Pops::Loader::Loader::NamedEntry, ...

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Finds typed/named entity in this module

Parameters:

  • typed_name (Puppet::Pops::Loader::TypedName)

    the type/name to find

Returns:



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/puppet/pops/loader/module_loaders.rb', line 93

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) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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.

Parameters:

  • effective_path (String)

    a path as resolved by a smart path

Returns:

  • (String)

    the content of the file

Raises:

  • (NotImplementedError)


172
173
174
# File 'lib/puppet/pops/loader/module_loaders.rb', line 172

def get_contents(effective_path)
  raise NotImplementedError.new
end

#get_source_ref(relative_path) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Abstract method that subclasses override to produce a source reference String used to identify the system resource (resource in the URI sense).

Parameters:

  • relative_path (String)

    a path relative to the module’s root

Returns:

  • (String)

    a reference to the source file (in file system, zip file, or elsewhere).

Raises:

  • (NotImplementedError)


182
183
184
# File 'lib/puppet/pops/loader/module_loaders.rb', line 182

def get_source_ref(relative_path)
  raise NotImplementedError.new
end

#loadablesObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



85
86
87
# File 'lib/puppet/pops/loader/module_loaders.rb', line 85

def loadables
  @loadables
end

#meaningful_to_search?(smart_path) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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).

Parameters:

  • smart_path (String)

    a path relative to the module’s root

Returns:

  • (Boolean)

    true if there is content in the directory appointed by the relative path

Raises:

  • (NotImplementedError)


153
154
155
# File 'lib/puppet/pops/loader/module_loaders.rb', line 153

def meaningful_to_search?(smart_path)
  raise NotImplementedError.new
end