Class: PDK::Module::TemplateDir::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/pdk/module/template_dir/base.rb

Direct Known Subclasses

Git, Local

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri, module_metadata = {}, init = false) {|self| ... } ⇒ Base

Initialises the TemplateDir object with the path or URL to the template and the block of code to run to be run while the template is available.

The template directory is only guaranteed to be available on disk within the scope of the block passed to this method.

template or a URI to a git repository. Defaults to an empty Hash. the template available on disk.

Examples:

Using a git repository as a template

PDK::Module::TemplateDir::Base.new('https://github.com/puppetlabs/pdk-templates') do |t|
  t.render do |filename, content|
    File.open(filename, 'w') do |file|
      file.write(content)
    end
  end
end

Parameters:

  • uri (PDK::Util::TemplateURI)

    The path to a directory to use as the

  • module_metadata (Hash) (defaults to: {})

    A Hash containing the module metadata.

Yield Parameters:

Raises:

  • (ArgumentError)

    If no block is given to this method.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/pdk/module/template_dir/base.rb', line 37

def initialize(uri,  = {}, init = false)
  unless block_given?
    raise ArgumentError, _('%{class_name} must be initialized with a block.') % { class_name: self.class.name }
  end
  unless uri.is_a? PDK::Util::TemplateURI
    raise ArgumentError, _('%{class_name} must be initialized with a PDK::Util::TemplateURI, got a %{uri_type}') % { uri_type: uri.class, class_name: self.class.name }
  end

  @path, @is_temporary_path = template_path(uri)
  @uri = uri

  @init = init
  @moduleroot_dir = PDK::Module::TemplateDir.moduleroot_dir(@path)
  @moduleroot_init = PDK::Module::TemplateDir.moduleroot_init(@path)
  @dirs = [@moduleroot_dir]
  @dirs << @moduleroot_init if @init
  @object_dir = File.join(@path, 'object_templates')

  PDK::Module::TemplateDir.validate_module_template!(@path)

  @module_metadata = 

  template_type = uri.default? ? 'default' : 'custom'
  PDK.analytics.event('TemplateDir', 'initialize', label: template_type)

  yield self
ensure
  # If the the path is temporary, clean it up
  if @is_temporary_path
    PDK::Util::Filesystem.rm_rf(@path)
  end
end

Instance Attribute Details

#module_metadataObject

Returns the value of attribute module_metadata.



7
8
9
# File 'lib/pdk/module/template_dir/base.rb', line 7

def 
  @module_metadata
end

#uriObject (readonly)

Returns the value of attribute uri.



8
9
10
# File 'lib/pdk/module/template_dir/base.rb', line 8

def uri
  @uri
end

Instance Method Details

#config_for(dest_path, sync_config_path = nil) ⇒ Hash

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.

Generate a hash of data to be used when rendering the specified template.

data is for, relative to the root of the module.

‘@configs` instance variable.

Parameters:

  • dest_path (String)

    The destination path of the file that the

Returns:

  • (Hash)

    The data that will be available to the template via the



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/pdk/module/template_dir/base.rb', line 193

def config_for(dest_path, sync_config_path = nil)
  require 'pdk/util'
  require 'pdk/analytics'

  module_root = PDK::Util.module_root
  sync_config_path ||= File.join(module_root, '.sync.yml') unless module_root.nil?
  config_path = File.join(@path, 'config_defaults.yml')

  if @config.nil?
    require 'deep_merge'
    conf_defaults = read_config(config_path)
    @sync_config = read_config(sync_config_path) unless sync_config_path.nil?
    @config = conf_defaults
    @config.deep_merge!(@sync_config, knockout_prefix: '---') unless @sync_config.nil?
  end
  file_config = @config.fetch(:global, {})
  file_config['module_metadata'] = @module_metadata
  file_config.merge!(@config.fetch(dest_path, {})) unless dest_path.nil?
  file_config.merge!(@config).tap do |c|
    if uri.default?
      file_value = if c['unmanaged']
                     'unmanaged'
                   elsif c['delete']
                     'deleted'
                   elsif @sync_config && @sync_config.key?(dest_path)
                     'customized'
                   else
                     'default'
                   end

      PDK.analytics.event('TemplateDir', 'file', label: dest_path, value: file_value)
    end
  end
end

#metadataHash{String => String}

This method is abstract.

Retrieve identifying metadata for the template.

For git repositories, this will return the URL to the repository and a reference to the HEAD.

For plain fileystem directories, this will return the URL to the repository only.

Returns:

  • (Hash{String => String})

    A hash of identifying metadata.



81
82
83
84
85
86
87
# File 'lib/pdk/module/template_dir/base.rb', line 81

def 
  {
    'pdk-version'  => PDK::Util::Version.version_string,
    'template-url' => nil,
    'template-ref' => nil,
  }
end

#object_configHash

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.

Generate a hash of data to be used when rendering object templates.

Read ‘config_defaults.yml` from the root of the template directory (if it exists) build a hash of values from the value of the `:global` key.

‘@configs` instance variable.

Returns:

  • (Hash)

    The data that will be available to the template via the



179
180
181
# File 'lib/pdk/module/template_dir/base.rb', line 179

def object_config
  config_for(nil)
end

#object_template_for(object_type) ⇒ Hash{Symbol => String}

Searches the template directory for template files that can be used to render files for the specified object type.

‘:defined_type`, `:fact`, etc).

template dir, otherwise ‘nil`. The returned hash can contain two keys, :object contains the path on disk to the template for the object, :spec contains the path on disk to the template for the object’s spec file (if available).

Parameters:

  • object_type (Symbol)

    The object type, e.g. (‘:class`,

Returns:

  • (Hash{Symbol => String})

    if the templates are available in the



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/pdk/module/template_dir/base.rb', line 150

def object_template_for(object_type)
  object_path = File.join(@object_dir, "#{object_type}.erb")
  type_path = File.join(@object_dir, "#{object_type}_type.erb")
  device_path = File.join(@object_dir, "#{object_type}_device.erb")
  spec_path = File.join(@object_dir, "#{object_type}_spec.erb")
  type_spec_path = File.join(@object_dir, "#{object_type}_type_spec.erb")

  if PDK::Util::Filesystem.file?(object_path) && PDK::Util::Filesystem.readable?(object_path)
    result = { object: object_path }
    result[:type] = type_path if PDK::Util::Filesystem.file?(type_path) && PDK::Util::Filesystem.readable?(type_path)
    result[:spec] = spec_path if PDK::Util::Filesystem.file?(spec_path) && PDK::Util::Filesystem.readable?(spec_path)
    result[:device] = device_path if PDK::Util::Filesystem.file?(device_path) && PDK::Util::Filesystem.readable?(device_path)
    result[:type_spec] = type_spec_path if PDK::Util::Filesystem.file?(type_spec_path) && PDK::Util::Filesystem.readable?(type_spec_path)
    result
  else
    nil
  end
end

#read_config(loc) ⇒ Hash

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.

Generates a hash of data from a given yaml file location.

if so.

Parameters:

  • loc (String)

    The path of the yaml config file.

Returns:

  • (Hash)

    The data that has been read in from the given yaml file.



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/pdk/module/template_dir/base.rb', line 238

def read_config(loc)
  if PDK::Util::Filesystem.file?(loc) && PDK::Util::Filesystem.readable?(loc)
    require 'yaml'

    begin
      YAML.safe_load(PDK::Util::Filesystem.read_file(loc), [], [], true)
    rescue Psych::SyntaxError => e
      PDK.logger.warn _("'%{file}' is not a valid YAML file: %{problem} %{context} at line %{line} column %{column}") % {
        file:    loc,
        problem: e.problem,
        context: e.context,
        line:    e.line,
        column:  e.column,
      }
      {}
    end
  else
    {}
  end
end

#render {|dest_path, dest_content| ... } ⇒ void

This method returns an undefined value.

Loop through the files in the template, yielding each rendered file to the supplied block.

relative to the root of the module. destination file.

Yield Parameters:

  • dest_path (String)

    The path of the destination file,

  • dest_content (String)

    The rendered content of the

Raises:



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
# File 'lib/pdk/module/template_dir/base.rb', line 102

def render
  require 'pdk/template_file'

  PDK::Module::TemplateDir.files_in_template(@dirs).each do |template_file, template_loc|
    template_file = template_file.to_s
    PDK.logger.debug(_("Rendering '%{template}'...") % { template: template_file })
    dest_path = template_file.sub(%r{\.erb\Z}, '')
    config = config_for(dest_path)

    dest_status = if template_loc.start_with?(@moduleroot_init)
                    :init
                  else
                    :manage
                  end

    if config['unmanaged']
      dest_status = :unmanage
    elsif config['delete']
      dest_status = :delete
    else
      begin
        dest_content = PDK::TemplateFile.new(File.join(template_loc, template_file), configs: config, template_dir: self).render
      rescue => error
        error_msg = _(
          "Failed to render template '%{template}'\n" \
          '%{exception}: %{message}',
        ) % { template: template_file, exception: error.class, message: error.message }
        raise PDK::CLI::FatalError, error_msg
      end
    end

    yield dest_path, dest_content, dest_status
  end
end

#template_path(uri) ⇒ 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.

Returns The path to the Template and whether this path is temporary. Temporary paths are deleted once the object has yielded.

Returns:

  • (Path, Boolean)

    The path to the Template and whether this path is temporary. Temporary paths are deleted once the object has yielded



262
263
264
# File 'lib/pdk/module/template_dir/base.rb', line 262

def template_path(uri)
  [uri.shell_path, false]
end