lib/pdk/generate/puppet_object.rb in pdk-akerl-1.9.1.1 vs lib/pdk/generate/puppet_object.rb in pdk-akerl-1.14.0.1
- old
+ new
@@ -1,14 +1,5 @@
-require 'fileutils'
-
-require 'pdk'
-require 'pdk/logger'
-require 'pdk/module/metadata'
-require 'pdk/module/templatedir'
-require 'pdk/template_file'
-require 'pdk/util/filesystem'
-
module PDK
module Generate
class PuppetObject
attr_reader :module_dir
attr_reader :object_name
@@ -27,11 +18,11 @@
# will contain the object.
# @param object_name [String] The name of the object.
# @param options [Hash{Symbol => Object}]
#
# @api public
- def initialize(module_dir, object_name, options = {})
+ def initialize(module_dir, object_name, options)
@module_dir = module_dir
@options = options
@object_name = object_name
if [:class, :defined_type].include?(object_type) # rubocop:disable Style/GuardClause
@@ -43,10 +34,14 @@
[module_name, object_name].join('::')
end
end
end
+ def spec_only?
+ @options[:spec_only]
+ end
+
# @abstract Subclass and implement {#template_data} to provide data to
# the templates during rendering. Implementations of this method should
# return a Hash!{Symbol => Object}.
def template_data
raise NotImplementedError
@@ -79,10 +74,17 @@
# of the tests for the object being generated.
def target_type_spec_path
nil
end
+ # @abstract Subclass and implement {#target_device_path}. Implementations
+ # of this method should return a String containing the destination path
+ # of the device class being generated.
+ def target_device_path
+ nil
+ end
+
# Retrieves the type of the object being generated, e.g. :class,
# :defined_type, etc. This is specified in the subclass' OBJECT_TYPE
# constant.
#
# @return [Symbol] the type of the object being generated.
@@ -90,27 +92,72 @@
# @api private
def object_type
self.class::OBJECT_TYPE
end
+ # Retrieves the type of the object being generated as represented in
+ # the JSON output of puppet-strings.
+ #
+ # @return [String] the type of the object being generated or nil if
+ # there is no mapping.
+ #
+ # @api private
+ def self.puppet_strings_type
+ return nil unless const_defined?(:PUPPET_STRINGS_TYPE)
+
+ self::PUPPET_STRINGS_TYPE
+ end
+
+ # Returns an array of possible target path strings.
+ def targets
+ targets = [
+ target_spec_path,
+ target_type_spec_path,
+ ]
+
+ unless spec_only?
+ targets += [
+ target_object_path,
+ target_type_path,
+ target_device_path,
+ ]
+ end
+
+ targets.compact
+ end
+
# Check preconditions of this template group. By default this only makes sure that the target files do not
# already exist. Override this (and call super) to add your own preconditions.
#
# @raise [PDK::CLI::ExitWithError] if the target files already exist.
#
# @api public
def check_preconditions
- [target_object_path, target_type_path, target_spec_path, target_type_spec_path].compact.each do |target_file|
- next unless File.exist?(target_file)
+ require 'pdk/util/filesystem'
+ targets.each do |target_file|
+ next unless PDK::Util::Filesystem.exist?(target_file)
+
raise PDK::CLI::ExitWithError, _("Unable to generate %{object_type}; '%{file}' already exists.") % {
file: target_file,
- object_type: object_type,
+ object_type: spec_only? ? 'unit test' : object_type,
}
end
end
+ # Check the preconditions of this template group, behaving as a
+ # predicate rather than raising an exception.
+ #
+ # @return [Boolean] true if the generator is safe to run, otherwise
+ # false.
+ def can_run?
+ check_preconditions
+ true
+ rescue PDK::CLI::ExitWithError
+ false
+ end
+
# Check that the templates can be rendered. Find an appropriate template
# and create the target files from the template. This is the main entry
# point for the class.
#
# @raise [PDK::CLI::ExitWithError] if the target files already exist.
@@ -121,12 +168,13 @@
check_preconditions
with_templates do |template_path, config_hash|
data = template_data.merge(configs: config_hash)
- render_file(target_object_path, template_path[:object], data)
+ render_file(target_object_path, template_path[:object], data) unless spec_only?
render_file(target_type_path, template_path[:type], data) if template_path[:type]
+ render_file(target_device_path, template_path[:device], data) if template_path[:device]
render_file(target_spec_path, template_path[:spec], data) if template_path[:spec]
render_file(target_type_spec_path, template_path[:type_spec], data) if template_path[:type_spec]
end
end
@@ -146,10 +194,12 @@
#
# @return [void]
#
# @api private
def render_file(dest_path, template_path, data)
+ require 'pdk/template_file'
+
write_file(dest_path) do
PDK::TemplateFile.new(template_path, data).render
end
end
@@ -166,16 +216,19 @@
#
# @return [void]
#
# @api private
def write_file(dest_path)
+ require 'pdk/logger'
+ require 'pdk/util/filesystem'
+
PDK.logger.info(_("Creating '%{file}' from template.") % { file: dest_path })
file_content = yield
begin
- FileUtils.mkdir_p(File.dirname(dest_path))
+ PDK::Util::Filesystem.mkdir_p(File.dirname(dest_path))
rescue SystemCallError => e
raise PDK::CLI::FatalError, _("Unable to create directory '%{path}': %{message}") % {
path: File.dirname(dest_path),
message: e.message,
}
@@ -202,28 +255,32 @@
#
# @raise [PDK::CLI::FatalError] if no suitable template could be found.
#
# @api private
def with_templates
+ require 'pdk/logger'
+ require 'pdk/module/templatedir'
+ require 'pdk/util/template_uri'
+
templates.each do |template|
- if template[:url].nil?
- PDK.logger.debug(_('No %{dir_type} template specified; trying next template directory.') % { dir_type: template[:type] })
+ if template[:uri].nil?
+ PDK.logger.debug(_('No %{dir_type} template found; trying next template directory.') % { dir_type: template[:type] })
next
end
- PDK::Module::TemplateDir.new(template[:url]) do |template_dir|
+ PDK::Module::TemplateDir.new(PDK::Util::TemplateURI.new(template[:uri])) do |template_dir|
template_paths = template_dir.object_template_for(object_type)
if template_paths
config_hash = template_dir.object_config
yield template_paths, config_hash
# TODO: refactor to a search-and-execute form instead
return # work is done # rubocop:disable Lint/NonLocalExitFromIterator
elsif template[:allow_fallback]
- PDK.logger.debug(_('Unable to find a %{type} template in %{url}; trying next template directory.') % { type: object_type, url: template[:url] })
+ PDK.logger.debug(_('Unable to find a %{type} template in %{url}; trying next template directory.') % { type: object_type, url: template[:uri] })
else
- raise PDK::CLI::FatalError, _('Unable to find the %{type} template in %{url}.') % { type: object_type, url: template[:url] }
+ raise PDK::CLI::FatalError, _('Unable to find the %{type} template in %{url}.') % { type: object_type, url: template[:uri] }
end
end
end
rescue ArgumentError => e
raise PDK::CLI::ExitWithError, e
@@ -248,41 +305,31 @@
# the lookup process should proceed to the next template directory if
# the template file is not in this template directory.
#
# @api private
def templates
- @templates ||= [
- { type: 'CLI', url: @options[:'template-url'], allow_fallback: false },
- { type: 'metadata', url: module_metadata.data['template-url'], allow_fallback: true },
- { type: 'default', url: PDK::Util.default_template_url, allow_fallback: false },
- ]
+ require 'pdk/util/template_uri'
+
+ @templates ||= PDK::Util::TemplateURI.templates(@options)
end
# Retrieves the name of the module (without the forge username) from the
# module metadata.
#
- # @raise (see #module_metadata)
# @return [String] The name of the module.
#
# @api private
def module_name
- @module_name ||= module_metadata.data['name'].rpartition('-').last
+ require 'pdk/util'
+
+ @module_name ||= PDK::Util.module_metadata['name'].rpartition('-').last
+ rescue ArgumentError => e
+ raise PDK::CLI::FatalError, e
end
- # Parses the metadata.json file for the module.
- #
- # @raise [PDK::CLI::FatalError] if the metadata.json file does not exist,
- # can not be read, or contains invalid metadata.
- #
- # @return [PDK::Module::Metadata] the parsed module metadata.
- #
- # @api private
- def module_metadata
- @module_metadata ||= begin
- PDK::Module::Metadata.from_file(File.join(module_dir, 'metadata.json'))
- rescue ArgumentError => e
- raise PDK::CLI::FatalError, _("'%{dir}' does not contain valid Puppet module metadata: %{msg}") % { dir: module_dir, msg: e.message }
- end
+ # transform a object name into a ruby class name
+ def self.class_name_from_object_name(object_name)
+ object_name.to_s.split('_').map(&:capitalize).join
end
end
end
end