pdk 1.14.1 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
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