Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(PDK-1364) Allow non-git template directories to be used #803

Merged
merged 8 commits into from
Dec 4, 2019
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ AllCops:
# package testing gems
- package-testing/vendor/**/*
- package-testing/vendor/**/.*
- tmp/**/*

Layout/IndentHeredoc:
Description: The `squiggly` style would be preferable, but is only available from ruby 2.3. We'll enable this when we can.
Expand Down
5 changes: 2 additions & 3 deletions lib/pdk/generate/module.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ def self.validate_options(opts)
end

def self.invoke(opts = {})
require 'pdk/module/templatedir'
require 'pdk/util'
require 'pdk/util/template_uri'
require 'pathname'
Expand Down Expand Up @@ -48,7 +47,7 @@ def self.invoke(opts = {})
template_uri = PDK::Util::TemplateURI.new(opts)

begin
PDK::Module::TemplateDir.new(template_uri, metadata.data, true) do |templates|
PDK::Module::TemplateDir.with(template_uri, metadata.data, true) do |templates|
templates.render do |file_path, file_content, file_status|
next if file_status == :delete
file = Pathname.new(temp_target_dir) + file_path
Expand Down Expand Up @@ -88,7 +87,7 @@ def self.invoke(opts = {})
end
end

PDK.logger.info _('Module \'%{name}\' generated at path \'%{path}\', from template \'%{url}\'.') % { name: opts[:module_name], path: target_dir, url: template_uri.git_remote }
PDK.logger.info _('Module \'%{name}\' generated at path \'%{path}\', from template \'%{url}\'.') % { name: opts[:module_name], path: target_dir, url: template_uri.bare_uri }
PDK.logger.info(_('In your module directory, add classes with the \'pdk new class\' command.'))
end
rescue Errno::EACCES => e
Expand Down
3 changes: 1 addition & 2 deletions lib/pdk/generate/puppet_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ def write_file(dest_path)
# @api private
def with_templates
require 'pdk/logger'
require 'pdk/module/templatedir'
require 'pdk/util/template_uri'

templates.each do |template|
Expand All @@ -269,7 +268,7 @@ def with_templates
next
end

PDK::Module::TemplateDir.new(PDK::Util::TemplateURI.new(template[:uri])) do |template_dir|
PDK::Module::TemplateDir.with(PDK::Util::TemplateURI.new(template[:uri])) do |template_dir|
template_paths = template_dir.object_template_for(object_type)

if template_paths
Expand Down
2 changes: 1 addition & 1 deletion lib/pdk/module.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Module
autoload :Build, 'pdk/module/build'
autoload :Convert, 'pdk/module/convert'
autoload :Metadata, 'pdk/module/metadata'
autoload :TemplateDir, 'pdk/module/templatedir'
autoload :TemplateDir, 'pdk/module/template_dir'
autoload :UpdateManager, 'pdk/module/update_manager'
autoload :Update, 'pdk/module/update'

Expand Down
3 changes: 1 addition & 2 deletions lib/pdk/module/convert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,11 @@ def needs_bundle_update?
end

def stage_changes!
require 'pdk/module/templatedir'
require 'pdk/util/filesystem'

metadata_path = 'metadata.json'

PDK::Module::TemplateDir.new(template_uri, nil, true) do |templates|
PDK::Module::TemplateDir.with(template_uri, nil, true) do |templates|
new_metadata = update_metadata(metadata_path, templates.metadata)
templates.module_metadata = new_metadata.data unless new_metadata.nil?

Expand Down
115 changes: 115 additions & 0 deletions lib/pdk/module/template_dir.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
require 'pdk'

module PDK
module Module
module TemplateDir
# Creates a 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.
#
# @param uri [PDK::Util::TemplateURI] The path to a directory to use as the
# template or a URI to a git repository.
# @param module_metadata [Hash] A Hash containing the module metadata.
# Defaults to an empty Hash.
# @yieldparam self [PDK::Module::TemplateDir] The initialised object with
# the template available on disk.
#
# @example Using a git repository as a template
# PDK::Module::TemplateDir.with('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
#
# @raise [ArgumentError] If no block is given to this method.
# @raise [PDK::CLI::FatalError] (see #clone_repo)
# @raise [ArgumentError] (see #validate_module_template!)
#
# @api public
def self.with(uri, module_metadata = {}, init = false)
unless block_given?
raise ArgumentError, _('%{class_name} must be initialized with a block.') % { class_name: self.class.name }
glennsarti marked this conversation as resolved.
Show resolved Hide resolved
end
unless uri.is_a? PDK::Util::TemplateURI
raise ArgumentError, _('PDK::Module::TemplateDir.for must be initialized with a PDK::Util::TemplateURI, got a %{uri_type}') % { uri_type: uri.class }
glennsarti marked this conversation as resolved.
Show resolved Hide resolved
end

if PDK::Util::Git.repo?(uri.bare_uri)
require 'pdk/module/template_dir/git'
PDK::Module::TemplateDir::Git.new(uri, module_metadata, init) { |value| yield value }
else
require 'pdk/module/template_dir/local'
PDK::Module::TemplateDir::Local.new(uri, module_metadata, init) { |value| yield value }
end
end

def self.moduleroot_dir(template_root_dir)
File.join(template_root_dir, 'moduleroot')
end

def self.moduleroot_init(template_root_dir)
File.join(template_root_dir, 'moduleroot_init')
end

# Validate the content of the template directory.
#
# @raise [ArgumentError] If the specified path is not a directory.
# @raise [ArgumentError] If the template directory does not contain
# a directory called 'moduleroot'.
#
# @return [void]
#
# @api public
def self.validate_module_template!(template_root_dir)
# rubocop:disable Style/GuardClause
unless PDK::Util::Filesystem.directory?(template_root_dir)
require 'pdk/util'

if PDK::Util.package_install? && PDK::Util::Filesystem.fnmatch?(File.join(PDK::Util.package_cachedir, '*'), template_root_dir)
raise ArgumentError, _('The built-in template has substantially changed. Please run "pdk convert" on your module to continue.')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the situation here that they must have an old template_root_dir in their metadata and that template path no longer exists in the package's cache area?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha, well we won't worry about it right now then. :)

else
raise ArgumentError, _("The specified template '%{path}' is not a directory.") % { path: template_root_dir }
end
end

unless PDK::Util::Filesystem.directory?(moduleroot_dir(template_root_dir))
raise ArgumentError, _("The template at '%{path}' does not contain a 'moduleroot/' directory.") % { path: template_root_dir }
end

unless PDK::Util::Filesystem.directory?(moduleroot_init(template_root_dir))
# rubocop:disable Metrics/LineLength
raise ArgumentError, _("The template at '%{path}' does not contain a 'moduleroot_init/' directory, which indicates you are using an older style of template. Before continuing please use the --template-url flag when running the pdk new commands to pass a new style template.") % { path: template_root_dir }
# rubocop:enable Metrics/LineLength
end
# rubocop:enable Style/GuardClause
end

# Get a list of template files in the template directory.
#
# @return [Hash{String=>String}] A hash of key file names and
# value locations.
#
# @api public
def self.files_in_template(dirs)
temp_paths = []
dirlocs = []
dirs.each do |dir|
raise ArgumentError, _("The directory '%{dir}' doesn't exist") % { dir: dir } unless PDK::Util::Filesystem.directory?(dir)
temp_paths += PDK::Util::Filesystem.glob(File.join(dir, '**', '*'), File::FNM_DOTMATCH).select do |template_path|
if PDK::Util::Filesystem.file?(template_path) && !PDK::Util::Filesystem.symlink?(template_path)
dirlocs << dir
end
end
temp_paths.map do |template_path|
template_path.sub!(%r{\A#{Regexp.escape(dir)}#{Regexp.escape(File::SEPARATOR)}}, '')
end
end
Hash[temp_paths.zip dirlocs]
end
end
end
end
Loading