pdk 1.14.1 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/lib/pdk/answer_file.rb +5 -7
- data/lib/pdk/cli.rb +1 -0
- data/lib/pdk/cli/console.rb +1 -1
- data/lib/pdk/cli/convert.rb +10 -2
- data/lib/pdk/cli/exec.rb +2 -1
- data/lib/pdk/cli/module/build.rb +1 -1
- data/lib/pdk/cli/module/generate.rb +1 -1
- data/lib/pdk/cli/release.rb +192 -0
- data/lib/pdk/cli/release/prep.rb +39 -0
- data/lib/pdk/cli/release/publish.rb +40 -0
- data/lib/pdk/cli/update.rb +12 -0
- data/lib/pdk/config.rb +1 -1
- data/lib/pdk/config/namespace.rb +1 -1
- data/lib/pdk/generate/module.rb +11 -17
- data/lib/pdk/generate/puppet_object.rb +1 -2
- data/lib/pdk/generate/task.rb +1 -1
- data/lib/pdk/module.rb +2 -1
- data/lib/pdk/module/build.rb +15 -25
- data/lib/pdk/module/convert.rb +4 -9
- data/lib/pdk/module/metadata.rb +1 -3
- data/lib/pdk/module/release.rb +260 -0
- data/lib/pdk/module/template_dir.rb +115 -0
- data/lib/pdk/module/template_dir/base.rb +268 -0
- data/lib/pdk/module/template_dir/git.rb +91 -0
- data/lib/pdk/module/template_dir/local.rb +21 -0
- data/lib/pdk/module/update.rb +17 -5
- data/lib/pdk/module/update_manager.rb +1 -1
- data/lib/pdk/report.rb +18 -12
- data/lib/pdk/report/event.rb +6 -3
- data/lib/pdk/template_file.rb +2 -2
- data/lib/pdk/util.rb +17 -6
- data/lib/pdk/util/bundler.rb +8 -9
- data/lib/pdk/util/changelog_generator.rb +115 -0
- data/lib/pdk/util/filesystem.rb +62 -2
- data/lib/pdk/util/git.rb +60 -8
- data/lib/pdk/util/puppet_version.rb +4 -5
- data/lib/pdk/util/ruby_version.rb +3 -3
- data/lib/pdk/util/template_uri.rb +49 -40
- data/lib/pdk/util/version.rb +4 -4
- data/lib/pdk/validate/metadata/metadata_syntax.rb +2 -2
- data/lib/pdk/validate/puppet/puppet_epp.rb +2 -4
- data/lib/pdk/validate/puppet/puppet_syntax.rb +2 -4
- data/lib/pdk/validate/tasks/metadata_lint.rb +2 -2
- data/lib/pdk/validate/yaml/syntax.rb +3 -3
- data/lib/pdk/version.rb +1 -1
- data/locales/pdk.pot +401 -149
- metadata +11 -3
- data/lib/pdk/module/templatedir.rb +0 -391
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
|
3
|
+
module PDK
|
4
|
+
module Module
|
5
|
+
module TemplateDir
|
6
|
+
# Creates a TemplateDir object with the path or URL to the template
|
7
|
+
# and the block of code to run to be run while the template is available.
|
8
|
+
#
|
9
|
+
# The template directory is only guaranteed to be available on disk
|
10
|
+
# within the scope of the block passed to this method.
|
11
|
+
#
|
12
|
+
# @param uri [PDK::Util::TemplateURI] The path to a directory to use as the
|
13
|
+
# template or a URI to a git repository.
|
14
|
+
# @param module_metadata [Hash] A Hash containing the module metadata.
|
15
|
+
# Defaults to an empty Hash.
|
16
|
+
# @yieldparam self [PDK::Module::TemplateDir] The initialised object with
|
17
|
+
# the template available on disk.
|
18
|
+
#
|
19
|
+
# @example Using a git repository as a template
|
20
|
+
# PDK::Module::TemplateDir.with('https://github.com/puppetlabs/pdk-templates') do |t|
|
21
|
+
# t.render do |filename, content|
|
22
|
+
# File.open(filename, 'w') do |file|
|
23
|
+
# file.write(content)
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# @raise [ArgumentError] If no block is given to this method.
|
29
|
+
# @raise [PDK::CLI::FatalError] (see #clone_repo)
|
30
|
+
# @raise [ArgumentError] (see #validate_module_template!)
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def self.with(uri, module_metadata = {}, init = false)
|
34
|
+
unless block_given?
|
35
|
+
raise ArgumentError, _('%{class_name}.with must be passed a block.') % { class_name: name }
|
36
|
+
end
|
37
|
+
unless uri.is_a? PDK::Util::TemplateURI
|
38
|
+
raise ArgumentError, _('%{class_name}.with must be passed a PDK::Util::TemplateURI, got a %{uri_type}') % { uri_type: uri.class, class_name: name }
|
39
|
+
end
|
40
|
+
|
41
|
+
if PDK::Util::Git.repo?(uri.bare_uri)
|
42
|
+
require 'pdk/module/template_dir/git'
|
43
|
+
PDK::Module::TemplateDir::Git.new(uri, module_metadata, init) { |value| yield value }
|
44
|
+
else
|
45
|
+
require 'pdk/module/template_dir/local'
|
46
|
+
PDK::Module::TemplateDir::Local.new(uri, module_metadata, init) { |value| yield value }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.moduleroot_dir(template_root_dir)
|
51
|
+
File.join(template_root_dir, 'moduleroot')
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.moduleroot_init(template_root_dir)
|
55
|
+
File.join(template_root_dir, 'moduleroot_init')
|
56
|
+
end
|
57
|
+
|
58
|
+
# Validate the content of the template directory.
|
59
|
+
#
|
60
|
+
# @raise [ArgumentError] If the specified path is not a directory.
|
61
|
+
# @raise [ArgumentError] If the template directory does not contain
|
62
|
+
# a directory called 'moduleroot'.
|
63
|
+
#
|
64
|
+
# @return [void]
|
65
|
+
#
|
66
|
+
# @api public
|
67
|
+
def self.validate_module_template!(template_root_dir)
|
68
|
+
# rubocop:disable Style/GuardClause
|
69
|
+
unless PDK::Util::Filesystem.directory?(template_root_dir)
|
70
|
+
require 'pdk/util'
|
71
|
+
|
72
|
+
if PDK::Util.package_install? && PDK::Util::Filesystem.fnmatch?(File.join(PDK::Util.package_cachedir, '*'), template_root_dir)
|
73
|
+
raise ArgumentError, _('The built-in template has substantially changed. Please run "pdk convert" on your module to continue.')
|
74
|
+
else
|
75
|
+
raise ArgumentError, _("The specified template '%{path}' is not a directory.") % { path: template_root_dir }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
unless PDK::Util::Filesystem.directory?(moduleroot_dir(template_root_dir))
|
80
|
+
raise ArgumentError, _("The template at '%{path}' does not contain a 'moduleroot/' directory.") % { path: template_root_dir }
|
81
|
+
end
|
82
|
+
|
83
|
+
unless PDK::Util::Filesystem.directory?(moduleroot_init(template_root_dir))
|
84
|
+
# rubocop:disable Metrics/LineLength
|
85
|
+
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 }
|
86
|
+
# rubocop:enable Metrics/LineLength
|
87
|
+
end
|
88
|
+
# rubocop:enable Style/GuardClause
|
89
|
+
end
|
90
|
+
|
91
|
+
# Get a list of template files in the template directory.
|
92
|
+
#
|
93
|
+
# @return [Hash{String=>String}] A hash of key file names and
|
94
|
+
# value locations.
|
95
|
+
#
|
96
|
+
# @api public
|
97
|
+
def self.files_in_template(dirs)
|
98
|
+
temp_paths = []
|
99
|
+
dirlocs = []
|
100
|
+
dirs.each do |dir|
|
101
|
+
raise ArgumentError, _("The directory '%{dir}' doesn't exist") % { dir: dir } unless PDK::Util::Filesystem.directory?(dir)
|
102
|
+
temp_paths += PDK::Util::Filesystem.glob(File.join(dir, '**', '*'), File::FNM_DOTMATCH).select do |template_path|
|
103
|
+
if PDK::Util::Filesystem.file?(template_path) && !PDK::Util::Filesystem.symlink?(template_path)
|
104
|
+
dirlocs << dir
|
105
|
+
end
|
106
|
+
end
|
107
|
+
temp_paths.map do |template_path|
|
108
|
+
template_path.sub!(%r{\A#{Regexp.escape(dir)}#{Regexp.escape(File::SEPARATOR)}}, '')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
Hash[temp_paths.zip dirlocs]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,268 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
|
3
|
+
module PDK
|
4
|
+
module Module
|
5
|
+
module TemplateDir
|
6
|
+
class Base
|
7
|
+
attr_accessor :module_metadata
|
8
|
+
attr_reader :uri
|
9
|
+
|
10
|
+
# Initialises the TemplateDir object with the path or URL to the template
|
11
|
+
# and the block of code to run to be run while the template is available.
|
12
|
+
#
|
13
|
+
# The template directory is only guaranteed to be available on disk
|
14
|
+
# within the scope of the block passed to this method.
|
15
|
+
#
|
16
|
+
# @param uri [PDK::Util::TemplateURI] The path to a directory to use as the
|
17
|
+
# template or a URI to a git repository.
|
18
|
+
# @param module_metadata [Hash] A Hash containing the module metadata.
|
19
|
+
# Defaults to an empty Hash.
|
20
|
+
# @yieldparam self [PDK::Module::TemplateDir] The initialised object with
|
21
|
+
# the template available on disk.
|
22
|
+
#
|
23
|
+
# @example Using a git repository as a template
|
24
|
+
# PDK::Module::TemplateDir::Base.new('https://github.com/puppetlabs/pdk-templates') do |t|
|
25
|
+
# t.render do |filename, content|
|
26
|
+
# File.open(filename, 'w') do |file|
|
27
|
+
# file.write(content)
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# @raise [ArgumentError] If no block is given to this method.
|
33
|
+
# @raise [PDK::CLI::FatalError] (see #clone_repo)
|
34
|
+
# @raise [ArgumentError] (see #validate_module_template!)
|
35
|
+
#
|
36
|
+
# @api public
|
37
|
+
def initialize(uri, module_metadata = {}, init = false)
|
38
|
+
unless block_given?
|
39
|
+
raise ArgumentError, _('%{class_name} must be initialized with a block.') % { class_name: self.class.name }
|
40
|
+
end
|
41
|
+
unless uri.is_a? PDK::Util::TemplateURI
|
42
|
+
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 }
|
43
|
+
end
|
44
|
+
|
45
|
+
@path, @is_temporary_path = template_path(uri)
|
46
|
+
@uri = uri
|
47
|
+
|
48
|
+
@init = init
|
49
|
+
@moduleroot_dir = PDK::Module::TemplateDir.moduleroot_dir(@path)
|
50
|
+
@moduleroot_init = PDK::Module::TemplateDir.moduleroot_init(@path)
|
51
|
+
@dirs = [@moduleroot_dir]
|
52
|
+
@dirs << @moduleroot_init if @init
|
53
|
+
@object_dir = File.join(@path, 'object_templates')
|
54
|
+
|
55
|
+
PDK::Module::TemplateDir.validate_module_template!(@path)
|
56
|
+
|
57
|
+
@module_metadata = module_metadata
|
58
|
+
|
59
|
+
template_type = uri.default? ? 'default' : 'custom'
|
60
|
+
PDK.analytics.event('TemplateDir', 'initialize', label: template_type)
|
61
|
+
|
62
|
+
yield self
|
63
|
+
ensure
|
64
|
+
# If the the path is temporary, clean it up
|
65
|
+
if @is_temporary_path
|
66
|
+
PDK::Util::Filesystem.rm_rf(@path)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Retrieve identifying metadata for the template.
|
71
|
+
#
|
72
|
+
# For git repositories, this will return the URL to the repository and
|
73
|
+
# a reference to the HEAD.
|
74
|
+
#
|
75
|
+
# For plain fileystem directories, this will return the URL to the repository only.
|
76
|
+
#
|
77
|
+
# @return [Hash{String => String}] A hash of identifying metadata.
|
78
|
+
#
|
79
|
+
# @api public
|
80
|
+
# @abstract
|
81
|
+
def metadata
|
82
|
+
{
|
83
|
+
'pdk-version' => PDK::Util::Version.version_string,
|
84
|
+
'template-url' => nil,
|
85
|
+
'template-ref' => nil,
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
89
|
+
# Loop through the files in the template, yielding each rendered file to
|
90
|
+
# the supplied block.
|
91
|
+
#
|
92
|
+
# @yieldparam dest_path [String] The path of the destination file,
|
93
|
+
# relative to the root of the module.
|
94
|
+
# @yieldparam dest_content [String] The rendered content of the
|
95
|
+
# destination file.
|
96
|
+
#
|
97
|
+
# @raise [PDK::CLI::FatalError] If the template fails to render.
|
98
|
+
#
|
99
|
+
# @return [void]
|
100
|
+
#
|
101
|
+
# @api public
|
102
|
+
def render
|
103
|
+
require 'pdk/template_file'
|
104
|
+
|
105
|
+
PDK::Module::TemplateDir.files_in_template(@dirs).each do |template_file, template_loc|
|
106
|
+
template_file = template_file.to_s
|
107
|
+
PDK.logger.debug(_("Rendering '%{template}'...") % { template: template_file })
|
108
|
+
dest_path = template_file.sub(%r{\.erb\Z}, '')
|
109
|
+
config = config_for(dest_path)
|
110
|
+
|
111
|
+
dest_status = if template_loc.start_with?(@moduleroot_init)
|
112
|
+
:init
|
113
|
+
else
|
114
|
+
:manage
|
115
|
+
end
|
116
|
+
|
117
|
+
if config['unmanaged']
|
118
|
+
dest_status = :unmanage
|
119
|
+
elsif config['delete']
|
120
|
+
dest_status = :delete
|
121
|
+
else
|
122
|
+
begin
|
123
|
+
dest_content = PDK::TemplateFile.new(File.join(template_loc, template_file), configs: config, template_dir: self).render
|
124
|
+
rescue => error
|
125
|
+
error_msg = _(
|
126
|
+
"Failed to render template '%{template}'\n" \
|
127
|
+
'%{exception}: %{message}',
|
128
|
+
) % { template: template_file, exception: error.class, message: error.message }
|
129
|
+
raise PDK::CLI::FatalError, error_msg
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
yield dest_path, dest_content, dest_status
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Searches the template directory for template files that can be used to
|
138
|
+
# render files for the specified object type.
|
139
|
+
#
|
140
|
+
# @param object_type [Symbol] The object type, e.g. (`:class`,
|
141
|
+
# `:defined_type`, `:fact`, etc).
|
142
|
+
#
|
143
|
+
# @return [Hash{Symbol => String}] if the templates are available in the
|
144
|
+
# template dir, otherwise `nil`. The returned hash can contain two keys,
|
145
|
+
# :object contains the path on disk to the template for the object, :spec
|
146
|
+
# contains the path on disk to the template for the object's spec file
|
147
|
+
# (if available).
|
148
|
+
#
|
149
|
+
# @api public
|
150
|
+
def object_template_for(object_type)
|
151
|
+
object_path = File.join(@object_dir, "#{object_type}.erb")
|
152
|
+
type_path = File.join(@object_dir, "#{object_type}_type.erb")
|
153
|
+
device_path = File.join(@object_dir, "#{object_type}_device.erb")
|
154
|
+
spec_path = File.join(@object_dir, "#{object_type}_spec.erb")
|
155
|
+
type_spec_path = File.join(@object_dir, "#{object_type}_type_spec.erb")
|
156
|
+
|
157
|
+
if PDK::Util::Filesystem.file?(object_path) && PDK::Util::Filesystem.readable?(object_path)
|
158
|
+
result = { object: object_path }
|
159
|
+
result[:type] = type_path if PDK::Util::Filesystem.file?(type_path) && PDK::Util::Filesystem.readable?(type_path)
|
160
|
+
result[:spec] = spec_path if PDK::Util::Filesystem.file?(spec_path) && PDK::Util::Filesystem.readable?(spec_path)
|
161
|
+
result[:device] = device_path if PDK::Util::Filesystem.file?(device_path) && PDK::Util::Filesystem.readable?(device_path)
|
162
|
+
result[:type_spec] = type_spec_path if PDK::Util::Filesystem.file?(type_spec_path) && PDK::Util::Filesystem.readable?(type_spec_path)
|
163
|
+
result
|
164
|
+
else
|
165
|
+
nil
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# Generate a hash of data to be used when rendering object templates.
|
170
|
+
#
|
171
|
+
# Read `config_defaults.yml` from the root of the template directory (if
|
172
|
+
# it exists) build a hash of values from the value of the `:global`
|
173
|
+
# key.
|
174
|
+
#
|
175
|
+
# @return [Hash] The data that will be available to the template via the
|
176
|
+
# `@configs` instance variable.
|
177
|
+
#
|
178
|
+
# @api private
|
179
|
+
def object_config
|
180
|
+
config_for(nil)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Generate a hash of data to be used when rendering the specified
|
184
|
+
# template.
|
185
|
+
#
|
186
|
+
# @param dest_path [String] The destination path of the file that the
|
187
|
+
# data is for, relative to the root of the module.
|
188
|
+
#
|
189
|
+
# @return [Hash] The data that will be available to the template via the
|
190
|
+
# `@configs` instance variable.
|
191
|
+
#
|
192
|
+
# @api private
|
193
|
+
def config_for(dest_path, sync_config_path = nil)
|
194
|
+
require 'pdk/util'
|
195
|
+
require 'pdk/analytics'
|
196
|
+
|
197
|
+
module_root = PDK::Util.module_root
|
198
|
+
sync_config_path ||= File.join(module_root, '.sync.yml') unless module_root.nil?
|
199
|
+
config_path = File.join(@path, 'config_defaults.yml')
|
200
|
+
|
201
|
+
if @config.nil?
|
202
|
+
require 'deep_merge'
|
203
|
+
conf_defaults = read_config(config_path)
|
204
|
+
@sync_config = read_config(sync_config_path) unless sync_config_path.nil?
|
205
|
+
@config = conf_defaults
|
206
|
+
@config.deep_merge!(@sync_config, knockout_prefix: '---') unless @sync_config.nil?
|
207
|
+
end
|
208
|
+
file_config = @config.fetch(:global, {})
|
209
|
+
file_config['module_metadata'] = @module_metadata
|
210
|
+
file_config.merge!(@config.fetch(dest_path, {})) unless dest_path.nil?
|
211
|
+
file_config.merge!(@config).tap do |c|
|
212
|
+
if uri.default?
|
213
|
+
file_value = if c['unmanaged']
|
214
|
+
'unmanaged'
|
215
|
+
elsif c['delete']
|
216
|
+
'deleted'
|
217
|
+
elsif @sync_config && @sync_config.key?(dest_path)
|
218
|
+
'customized'
|
219
|
+
else
|
220
|
+
'default'
|
221
|
+
end
|
222
|
+
|
223
|
+
PDK.analytics.event('TemplateDir', 'file', label: dest_path, value: file_value)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# Generates a hash of data from a given yaml file location.
|
229
|
+
#
|
230
|
+
# @param loc [String] The path of the yaml config file.
|
231
|
+
#
|
232
|
+
# @warn If the specified path is not a valid yaml file. Returns an empty Hash
|
233
|
+
# if so.
|
234
|
+
#
|
235
|
+
# @return [Hash] The data that has been read in from the given yaml file.
|
236
|
+
#
|
237
|
+
# @api private
|
238
|
+
def read_config(loc)
|
239
|
+
if PDK::Util::Filesystem.file?(loc) && PDK::Util::Filesystem.readable?(loc)
|
240
|
+
require 'yaml'
|
241
|
+
|
242
|
+
begin
|
243
|
+
YAML.safe_load(PDK::Util::Filesystem.read_file(loc), [], [], true)
|
244
|
+
rescue Psych::SyntaxError => e
|
245
|
+
PDK.logger.warn _("'%{file}' is not a valid YAML file: %{problem} %{context} at line %{line} column %{column}") % {
|
246
|
+
file: loc,
|
247
|
+
problem: e.problem,
|
248
|
+
context: e.context,
|
249
|
+
line: e.line,
|
250
|
+
column: e.column,
|
251
|
+
}
|
252
|
+
{}
|
253
|
+
end
|
254
|
+
else
|
255
|
+
{}
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# @return [Path, Boolean] The path to the Template and whether this path is temporary. Temporary paths
|
260
|
+
# are deleted once the object has yielded
|
261
|
+
# @api private
|
262
|
+
def template_path(uri)
|
263
|
+
[uri.shell_path, false]
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
require 'pdk/module/template_dir/base'
|
3
|
+
|
4
|
+
module PDK
|
5
|
+
module Module
|
6
|
+
module TemplateDir
|
7
|
+
class Git < Base
|
8
|
+
def template_path(uri)
|
9
|
+
# We don't do a checkout of local-path repos. There are lots of edge
|
10
|
+
# cases or user un-expectations.
|
11
|
+
if PDK::Util::Git.work_tree?(uri.shell_path)
|
12
|
+
PDK.logger.warn _("Repository '%{repo}' has a work-tree; skipping git reset.") % {
|
13
|
+
repo: uri.shell_path,
|
14
|
+
}
|
15
|
+
[uri.shell_path, false]
|
16
|
+
else
|
17
|
+
# This is either a bare local repo or a remote. either way it needs cloning.
|
18
|
+
# A "remote" can also be git repo on the local filsystem.
|
19
|
+
[clone_template_repo(uri), true]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# For git repositories, this will return the URL to the repository and
|
24
|
+
# a reference to the HEAD.
|
25
|
+
#
|
26
|
+
# @return [Hash{String => String}] A hash of identifying metadata.
|
27
|
+
def metadata
|
28
|
+
super.merge('template-url' => uri.metadata_format, 'template-ref' => cache_template_ref(@path))
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def cache_template_ref(path, ref = nil)
|
34
|
+
require 'pdk/util/git'
|
35
|
+
|
36
|
+
@template_ref ||= PDK::Util::Git.describe(File.join(path, '.git'), ref)
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [String] Path to working directory into which template repo has been cloned and reset
|
40
|
+
#
|
41
|
+
# @raise [PDK::CLI::FatalError] If unable to clone the given origin_repo into a tempdir.
|
42
|
+
# @raise [PDK::CLI::FatalError] If reset HEAD of the cloned repo to desired ref.
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
def clone_template_repo(uri)
|
46
|
+
# @todo When switching this over to using rugged, cache the cloned
|
47
|
+
# template repo in `%AppData%` or `$XDG_CACHE_DIR` and update before
|
48
|
+
# use.
|
49
|
+
require 'pdk/util'
|
50
|
+
require 'pdk/util/git'
|
51
|
+
|
52
|
+
temp_dir = PDK::Util.make_tmpdir_name('pdk-templates')
|
53
|
+
origin_repo = uri.bare_uri
|
54
|
+
git_ref = uri.uri_fragment
|
55
|
+
|
56
|
+
clone_result = PDK::Util::Git.git('clone', origin_repo, temp_dir)
|
57
|
+
|
58
|
+
if clone_result[:exit_code].zero?
|
59
|
+
checkout_template_ref(temp_dir, git_ref)
|
60
|
+
else
|
61
|
+
PDK.logger.error clone_result[:stdout]
|
62
|
+
PDK.logger.error clone_result[:stderr]
|
63
|
+
raise PDK::CLI::FatalError, _("Unable to clone git repository at '%{repo}' into '%{dest}'.") % { repo: origin_repo, dest: temp_dir }
|
64
|
+
end
|
65
|
+
|
66
|
+
PDK::Util.canonical_path(temp_dir)
|
67
|
+
end
|
68
|
+
|
69
|
+
# @api private
|
70
|
+
def checkout_template_ref(path, ref)
|
71
|
+
require 'pdk/util/git'
|
72
|
+
|
73
|
+
if PDK::Util::Git.work_dir_clean?(path)
|
74
|
+
Dir.chdir(path) do
|
75
|
+
full_ref = PDK::Util::Git.ls_remote(path, ref)
|
76
|
+
cache_template_ref(path, full_ref)
|
77
|
+
reset_result = PDK::Util::Git.git('reset', '--hard', full_ref)
|
78
|
+
return if reset_result[:exit_code].zero?
|
79
|
+
|
80
|
+
PDK.logger.error reset_result[:stdout]
|
81
|
+
PDK.logger.error reset_result[:stderr]
|
82
|
+
raise PDK::CLI::FatalError, _("Unable to checkout '%{ref}' of git repository at '%{path}'.") % { ref: ref, path: path }
|
83
|
+
end
|
84
|
+
else
|
85
|
+
PDK.logger.warn _("Uncommitted changes found when attempting to checkout '%{ref}' of git repository at '%{path}'; skipping git reset.") % { ref: ref, path: path }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|