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

#parent

Attributes inherited from Loader

#loader_name

Instance Method Summary collapse

Methods inherited from BaseLoader

#add_entry, #get_entry, #load_typed, #loaded_entry, #promote_entry, #remove_entry, #set_entry

Methods inherited from Loader

#[], #get_entry, #inspect, #load, #load_typed, #loaded_entry, #parent, #set_entry, #to_s

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 (Loader)

    loader with higher priority

  • loaders (Loaders)

    the container for this loader

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



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/puppet/pops/loader/module_loaders.rb', line 83

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

  @module_name = module_name
  @path = path
  @smart_paths = LoaderPaths::SmartPaths.new(self)
  @loaders = loaders
  @loadables = loadables
  unless (loadables - LOADABLE_KINDS).empty?
    raise ArgumentError, 'given loadables are not of supported loadable kind'
  end
  loaders.add_loader_by_name(self)
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”



61
62
63
# File 'lib/puppet/pops/loader/module_loaders.rb', line 61

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



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

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



74
75
76
# File 'lib/puppet/pops/loader/module_loaders.rb', line 74

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



67
68
69
# File 'lib/puppet/pops/loader/module_loaders.rb', line 67

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)


179
180
181
# File 'lib/puppet/pops/loader/module_loaders.rb', line 179

def existing_path(resolved_path)
  raise NotImplementedError.new
end

#find(typed_name) ⇒ 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 (TypedName)

    the type/name to find

Returns:

  • (Loader::NamedEntry, nil found/created entry, or nil if not found)

    Loader::NamedEntry, nil found/created entry, or nil if not found



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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/puppet/pops/loader/module_loaders.rb', line 105

def find(typed_name)
  # This loader is tailored to only find entries in the current runtime
  return nil unless typed_name.name_authority == Pcore::RUNTIME_NAME_AUTHORITY

  # 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
    when :resource_type_pp
    when :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)


189
190
191
# File 'lib/puppet/pops/loader/module_loaders.rb', line 189

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)


199
200
201
# File 'lib/puppet/pops/loader/module_loaders.rb', line 199

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.



97
98
99
# File 'lib/puppet/pops/loader/module_loaders.rb', line 97

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)


170
171
172
# File 'lib/puppet/pops/loader/module_loaders.rb', line 170

def meaningful_to_search?(smart_path)
  raise NotImplementedError.new
end