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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/lib/pdk/answer_file.rb +5 -7
  4. data/lib/pdk/cli.rb +1 -0
  5. data/lib/pdk/cli/console.rb +1 -1
  6. data/lib/pdk/cli/convert.rb +10 -2
  7. data/lib/pdk/cli/exec.rb +2 -1
  8. data/lib/pdk/cli/module/build.rb +1 -1
  9. data/lib/pdk/cli/module/generate.rb +1 -1
  10. data/lib/pdk/cli/release.rb +192 -0
  11. data/lib/pdk/cli/release/prep.rb +39 -0
  12. data/lib/pdk/cli/release/publish.rb +40 -0
  13. data/lib/pdk/cli/update.rb +12 -0
  14. data/lib/pdk/config.rb +1 -1
  15. data/lib/pdk/config/namespace.rb +1 -1
  16. data/lib/pdk/generate/module.rb +11 -17
  17. data/lib/pdk/generate/puppet_object.rb +1 -2
  18. data/lib/pdk/generate/task.rb +1 -1
  19. data/lib/pdk/module.rb +2 -1
  20. data/lib/pdk/module/build.rb +15 -25
  21. data/lib/pdk/module/convert.rb +4 -9
  22. data/lib/pdk/module/metadata.rb +1 -3
  23. data/lib/pdk/module/release.rb +260 -0
  24. data/lib/pdk/module/template_dir.rb +115 -0
  25. data/lib/pdk/module/template_dir/base.rb +268 -0
  26. data/lib/pdk/module/template_dir/git.rb +91 -0
  27. data/lib/pdk/module/template_dir/local.rb +21 -0
  28. data/lib/pdk/module/update.rb +17 -5
  29. data/lib/pdk/module/update_manager.rb +1 -1
  30. data/lib/pdk/report.rb +18 -12
  31. data/lib/pdk/report/event.rb +6 -3
  32. data/lib/pdk/template_file.rb +2 -2
  33. data/lib/pdk/util.rb +17 -6
  34. data/lib/pdk/util/bundler.rb +8 -9
  35. data/lib/pdk/util/changelog_generator.rb +115 -0
  36. data/lib/pdk/util/filesystem.rb +62 -2
  37. data/lib/pdk/util/git.rb +60 -8
  38. data/lib/pdk/util/puppet_version.rb +4 -5
  39. data/lib/pdk/util/ruby_version.rb +3 -3
  40. data/lib/pdk/util/template_uri.rb +49 -40
  41. data/lib/pdk/util/version.rb +4 -4
  42. data/lib/pdk/validate/metadata/metadata_syntax.rb +2 -2
  43. data/lib/pdk/validate/puppet/puppet_epp.rb +2 -4
  44. data/lib/pdk/validate/puppet/puppet_syntax.rb +2 -4
  45. data/lib/pdk/validate/tasks/metadata_lint.rb +2 -2
  46. data/lib/pdk/validate/yaml/syntax.rb +3 -3
  47. data/lib/pdk/version.rb +1 -1
  48. data/locales/pdk.pot +401 -149
  49. metadata +11 -3
  50. data/lib/pdk/module/templatedir.rb +0 -391
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.14.1
4
+ version: 1.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet, Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-01 00:00:00.000000000 Z
11
+ date: 2019-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -309,6 +309,9 @@ files:
309
309
  - lib/pdk/cli/new/task.rb
310
310
  - lib/pdk/cli/new/test.rb
311
311
  - lib/pdk/cli/new/transport.rb
312
+ - lib/pdk/cli/release.rb
313
+ - lib/pdk/cli/release/prep.rb
314
+ - lib/pdk/cli/release/publish.rb
312
315
  - lib/pdk/cli/test.rb
313
316
  - lib/pdk/cli/test/unit.rb
314
317
  - lib/pdk/cli/update.rb
@@ -345,7 +348,11 @@ files:
345
348
  - lib/pdk/module/build.rb
346
349
  - lib/pdk/module/convert.rb
347
350
  - lib/pdk/module/metadata.rb
348
- - lib/pdk/module/templatedir.rb
351
+ - lib/pdk/module/release.rb
352
+ - lib/pdk/module/template_dir.rb
353
+ - lib/pdk/module/template_dir/base.rb
354
+ - lib/pdk/module/template_dir/git.rb
355
+ - lib/pdk/module/template_dir/local.rb
349
356
  - lib/pdk/module/update.rb
350
357
  - lib/pdk/module/update_manager.rb
351
358
  - lib/pdk/report.rb
@@ -354,6 +361,7 @@ files:
354
361
  - lib/pdk/tests/unit.rb
355
362
  - lib/pdk/util.rb
356
363
  - lib/pdk/util/bundler.rb
364
+ - lib/pdk/util/changelog_generator.rb
357
365
  - lib/pdk/util/env.rb
358
366
  - lib/pdk/util/filesystem.rb
359
367
  - lib/pdk/util/git.rb
@@ -1,391 +0,0 @@
1
- require 'pdk'
2
-
3
- module PDK
4
- module Module
5
- class TemplateDir
6
- attr_accessor :module_metadata
7
- attr_reader :uri
8
-
9
- # Initialises the TemplateDir object with the path or URL to the template
10
- # and the block of code to run to be run while the template is available.
11
- #
12
- # The template directory is only guaranteed to be available on disk
13
- # within the scope of the block passed to this method.
14
- #
15
- # @param uri [PDK::Util::TemplateURI] The path to a directory to use as the
16
- # template or a URI to a git repository.
17
- # @param module_metadata [Hash] A Hash containing the module metadata.
18
- # Defaults to an empty Hash.
19
- # @yieldparam self [PDK::Module::TemplateDir] The initialised object with
20
- # the template available on disk.
21
- #
22
- # @example Using a git repository as a template
23
- # PDK::Module::TemplateDir.new('https://github.com/puppetlabs/pdk-templates') do |t|
24
- # t.render do |filename, content|
25
- # File.open(filename, 'w') do |file|
26
- # file.write(content)
27
- # end
28
- # end
29
- # end
30
- #
31
- # @raise [ArgumentError] If no block is given to this method.
32
- # @raise [PDK::CLI::FatalError] (see #clone_repo)
33
- # @raise [ArgumentError] (see #validate_module_template!)
34
- #
35
- # @api public
36
- def initialize(uri, module_metadata = {}, init = false)
37
- require 'pdk/analytics'
38
- require 'pdk/util/template_uri'
39
- require 'pdk/util/git'
40
-
41
- unless block_given?
42
- raise ArgumentError, _('%{class_name} must be initialized with a block.') % { class_name: self.class.name }
43
- end
44
- unless uri.is_a? PDK::Util::TemplateURI
45
- raise ArgumentError, _('PDK::Module::TemplateDir.new must be initialized with a PDK::Util::TemplateURI, got a %{uri_type}') % { uri_type: uri.class }
46
- end
47
-
48
- if PDK::Util::Git.repo?(uri.git_remote)
49
- # This is either a bare local repo or a remote. either way it needs cloning.
50
- @path = clone_template_repo(uri)
51
- temp_dir_clone = true
52
- else
53
- # if it is a local path & non-bare repo then we can use it directly.
54
- # Still have to check the branch.
55
- @path = uri.shell_path
56
- # We don't do a checkout of local-path repos. There are lots of edge
57
- # cases or user un-expectations.
58
- if PDK::Util::Git.work_tree?(@path)
59
- PDK.logger.warn _("Repository '%{repo}' has a work-tree; skipping git reset.") % {
60
- repo: @path,
61
- }
62
- end
63
- end
64
- @uri = uri
65
-
66
- @init = init
67
- @moduleroot_dir = File.join(@path, 'moduleroot')
68
- @moduleroot_init = File.join(@path, 'moduleroot_init')
69
- @dirs = [@moduleroot_dir]
70
- @dirs << @moduleroot_init if @init
71
- @object_dir = File.join(@path, 'object_templates')
72
-
73
- validate_module_template!
74
-
75
- @module_metadata = module_metadata
76
-
77
- template_type = uri.default? ? 'default' : 'custom'
78
- PDK.analytics.event('TemplateDir', 'initialize', label: template_type)
79
-
80
- yield self
81
- ensure
82
- # If we cloned a git repo to get the template, remove the clone once
83
- # we're done with it.
84
- if temp_dir_clone
85
- require 'fileutils'
86
- FileUtils.remove_dir(@path)
87
- end
88
- end
89
-
90
- # Retrieve identifying metadata for the template.
91
- #
92
- # For git repositories, this will return the URL to the repository and
93
- # a reference to the HEAD.
94
- #
95
- # @return [Hash{String => String}] A hash of identifying metadata.
96
- #
97
- # @api public
98
- def metadata
99
- require 'pdk/util/version'
100
-
101
- {
102
- 'pdk-version' => PDK::Util::Version.version_string,
103
- 'template-url' => uri.metadata_format,
104
- 'template-ref' => cache_template_ref(@path),
105
- }
106
- end
107
-
108
- # Loop through the files in the template, yielding each rendered file to
109
- # the supplied block.
110
- #
111
- # @yieldparam dest_path [String] The path of the destination file,
112
- # relative to the root of the module.
113
- # @yieldparam dest_content [String] The rendered content of the
114
- # destination file.
115
- #
116
- # @raise [PDK::CLI::FatalError] If the template fails to render.
117
- #
118
- # @return [void]
119
- #
120
- # @api public
121
- def render
122
- require 'pdk/template_file'
123
-
124
- PDK::Module::TemplateDir.files_in_template(@dirs).each do |template_file, template_loc|
125
- template_file = template_file.to_s
126
- PDK.logger.debug(_("Rendering '%{template}'...") % { template: template_file })
127
- dest_path = template_file.sub(%r{\.erb\Z}, '')
128
- config = config_for(dest_path)
129
-
130
- dest_status = if template_loc.start_with?(@moduleroot_init)
131
- :init
132
- else
133
- :manage
134
- end
135
-
136
- if config['unmanaged']
137
- dest_status = :unmanage
138
- elsif config['delete']
139
- dest_status = :delete
140
- else
141
- begin
142
- dest_content = PDK::TemplateFile.new(File.join(template_loc, template_file), configs: config, template_dir: self).render
143
- rescue => error
144
- error_msg = _(
145
- "Failed to render template '%{template}'\n" \
146
- '%{exception}: %{message}',
147
- ) % { template: template_file, exception: error.class, message: error.message }
148
- raise PDK::CLI::FatalError, error_msg
149
- end
150
- end
151
-
152
- yield dest_path, dest_content, dest_status
153
- end
154
- end
155
-
156
- # Searches the template directory for template files that can be used to
157
- # render files for the specified object type.
158
- #
159
- # @param object_type [Symbol] The object type, e.g. (`:class`,
160
- # `:defined_type`, `:fact`, etc).
161
- #
162
- # @return [Hash{Symbol => String}] if the templates are available in the
163
- # template dir, otherwise `nil`. The returned hash can contain two keys,
164
- # :object contains the path on disk to the template for the object, :spec
165
- # contains the path on disk to the template for the object's spec file
166
- # (if available).
167
- #
168
- # @api public
169
- def object_template_for(object_type)
170
- object_path = File.join(@object_dir, "#{object_type}.erb")
171
- type_path = File.join(@object_dir, "#{object_type}_type.erb")
172
- device_path = File.join(@object_dir, "#{object_type}_device.erb")
173
- spec_path = File.join(@object_dir, "#{object_type}_spec.erb")
174
- type_spec_path = File.join(@object_dir, "#{object_type}_type_spec.erb")
175
-
176
- if File.file?(object_path) && File.readable?(object_path)
177
- result = { object: object_path }
178
- result[:type] = type_path if File.file?(type_path) && File.readable?(type_path)
179
- result[:spec] = spec_path if File.file?(spec_path) && File.readable?(spec_path)
180
- result[:device] = device_path if File.file?(device_path) && File.readable?(device_path)
181
- result[:type_spec] = type_spec_path if File.file?(type_spec_path) && File.readable?(type_spec_path)
182
- result
183
- else
184
- nil
185
- end
186
- end
187
-
188
- # Generate a hash of data to be used when rendering object templates.
189
- #
190
- # Read `config_defaults.yml` from the root of the template directory (if
191
- # it exists) build a hash of values from the value of the `:global`
192
- # key.
193
- #
194
- # @return [Hash] The data that will be available to the template via the
195
- # `@configs` instance variable.
196
- #
197
- # @api private
198
- def object_config
199
- config_for(nil)
200
- end
201
-
202
- # Validate the content of the template directory.
203
- #
204
- # @raise [ArgumentError] If the specified path is not a directory.
205
- # @raise [ArgumentError] If the template directory does not contain
206
- # a directory called 'moduleroot'.
207
- #
208
- # @return [void]
209
- #
210
- # @api private
211
- def validate_module_template!
212
- # rubocop:disable Style/GuardClause
213
- unless File.directory?(@path)
214
- require 'pdk/util'
215
-
216
- if PDK::Util.package_install? && File.fnmatch?(File.join(PDK::Util.package_cachedir, '*'), @path)
217
- raise ArgumentError, _('The built-in template has substantially changed. Please run "pdk convert" on your module to continue.')
218
- else
219
- raise ArgumentError, _("The specified template '%{path}' is not a directory.") % { path: @path }
220
- end
221
- end
222
-
223
- unless File.directory?(@moduleroot_dir)
224
- raise ArgumentError, _("The template at '%{path}' does not contain a 'moduleroot/' directory.") % { path: @path }
225
- end
226
-
227
- unless File.directory?(@moduleroot_init)
228
- # rubocop:disable Metrics/LineLength
229
- 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: @path }
230
- # rubocop:enable Metrics/LineLength Style/GuardClause
231
- end
232
- # rubocop:enable Style/GuardClause
233
- end
234
-
235
- # Get a list of template files in the template directory.
236
- #
237
- # @return [Hash{String=>String}] A hash of key file names and
238
- # value locations.
239
- #
240
- # @api public
241
- def self.files_in_template(dirs)
242
- temp_paths = []
243
- dirlocs = []
244
- dirs.each do |dir|
245
- raise ArgumentError, _("The directory '%{dir}' doesn't exist") % { dir: dir } unless Dir.exist?(dir)
246
- temp_paths += Dir.glob(File.join(dir, '**', '*'), File::FNM_DOTMATCH).select do |template_path|
247
- if File.file?(template_path) && !File.symlink?(template_path)
248
- dirlocs << dir
249
- end
250
- end
251
- temp_paths.map do |template_path|
252
- template_path.sub!(%r{\A#{Regexp.escape(dir)}#{Regexp.escape(File::SEPARATOR)}}, '')
253
- end
254
- end
255
- Hash[temp_paths.zip dirlocs]
256
- end
257
-
258
- # Generate a hash of data to be used when rendering the specified
259
- # template.
260
- #
261
- # @param dest_path [String] The destination path of the file that the
262
- # data is for, relative to the root of the module.
263
- #
264
- # @return [Hash] The data that will be available to the template via the
265
- # `@configs` instance variable.
266
- #
267
- # @api private
268
- def config_for(dest_path, sync_config_path = nil)
269
- require 'pdk/util'
270
- require 'pdk/analytics'
271
-
272
- module_root = PDK::Util.module_root
273
- sync_config_path ||= File.join(module_root, '.sync.yml') unless module_root.nil?
274
- config_path = File.join(@path, 'config_defaults.yml')
275
-
276
- if @config.nil?
277
- require 'deep_merge'
278
- conf_defaults = read_config(config_path)
279
- @sync_config = read_config(sync_config_path) unless sync_config_path.nil?
280
- @config = conf_defaults
281
- @config.deep_merge!(@sync_config, knockout_prefix: '---') unless @sync_config.nil?
282
- end
283
- file_config = @config.fetch(:global, {})
284
- file_config['module_metadata'] = @module_metadata
285
- file_config.merge!(@config.fetch(dest_path, {})) unless dest_path.nil?
286
- file_config.merge!(@config).tap do |c|
287
- if uri.default?
288
- file_value = if c['unmanaged']
289
- 'unmanaged'
290
- elsif c['delete']
291
- 'deleted'
292
- elsif @sync_config && @sync_config.key?(dest_path)
293
- 'customized'
294
- else
295
- 'default'
296
- end
297
-
298
- PDK.analytics.event('TemplateDir', 'file', label: dest_path, value: file_value)
299
- end
300
- end
301
- end
302
-
303
- # Generates a hash of data from a given yaml file location.
304
- #
305
- # @param loc [String] The path of the yaml config file.
306
- #
307
- # @warn If the specified path is not a valid yaml file. Returns an empty Hash
308
- # if so.
309
- #
310
- # @return [Hash] The data that has been read in from the given yaml file.
311
- #
312
- # @api private
313
- def read_config(loc)
314
- if File.file?(loc) && File.readable?(loc)
315
- require 'yaml'
316
-
317
- begin
318
- YAML.safe_load(File.read(loc), [], [], true)
319
- rescue Psych::SyntaxError => e
320
- PDK.logger.warn _("'%{file}' is not a valid YAML file: %{problem} %{context} at line %{line} column %{column}") % {
321
- file: loc,
322
- problem: e.problem,
323
- context: e.context,
324
- line: e.line,
325
- column: e.column,
326
- }
327
- {}
328
- end
329
- else
330
- {}
331
- end
332
- end
333
-
334
- # @return [String] Path to working directory into which template repo has been cloned and reset
335
- #
336
- # @raise [PDK::CLI::FatalError] If unable to clone the given origin_repo into a tempdir.
337
- # @raise [PDK::CLI::FatalError] If reset HEAD of the cloned repo to desired ref.
338
- #
339
- # @api private
340
- def clone_template_repo(uri)
341
- # @todo When switching this over to using rugged, cache the cloned
342
- # template repo in `%AppData%` or `$XDG_CACHE_DIR` and update before
343
- # use.
344
- require 'pdk/util'
345
- require 'pdk/util/git'
346
-
347
- temp_dir = PDK::Util.make_tmpdir_name('pdk-templates')
348
- origin_repo = uri.git_remote
349
- git_ref = uri.git_ref
350
-
351
- clone_result = PDK::Util::Git.git('clone', origin_repo, temp_dir)
352
-
353
- if clone_result[:exit_code].zero?
354
- checkout_template_ref(temp_dir, git_ref)
355
- else
356
- PDK.logger.error clone_result[:stdout]
357
- PDK.logger.error clone_result[:stderr]
358
- raise PDK::CLI::FatalError, _("Unable to clone git repository at '%{repo}' into '%{dest}'.") % { repo: origin_repo, dest: temp_dir }
359
- end
360
-
361
- PDK::Util.canonical_path(temp_dir)
362
- end
363
-
364
- # @api private
365
- def checkout_template_ref(path, ref)
366
- require 'pdk/util/git'
367
-
368
- if PDK::Util::Git.work_dir_clean?(path)
369
- Dir.chdir(path) do
370
- full_ref = PDK::Util::Git.ls_remote(path, ref)
371
- cache_template_ref(path, full_ref)
372
- reset_result = PDK::Util::Git.git('reset', '--hard', full_ref)
373
- return if reset_result[:exit_code].zero?
374
-
375
- PDK.logger.error reset_result[:stdout]
376
- PDK.logger.error reset_result[:stderr]
377
- raise PDK::CLI::FatalError, _("Unable to checkout '%{ref}' of git repository at '%{path}'.") % { ref: ref, path: path }
378
- end
379
- else
380
- PDK.logger.warn _("Uncommitted changes found when attempting to checkout '%{ref}' of git repository at '%{path}'; skipping git reset.") % { ref: ref, path: path }
381
- end
382
- end
383
-
384
- def cache_template_ref(path, ref = nil)
385
- require 'pdk/util/git'
386
-
387
- @template_ref ||= PDK::Util::Git.describe(File.join(path, '.git'), ref)
388
- end
389
- end
390
- end
391
- end