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
@@ -47,7 +47,7 @@ module PDK
47
47
  end
48
48
 
49
49
  def self.bolt_analytics_config
50
- file = File.expand_path('~/.puppetlabs/bolt/analytics.yaml')
50
+ file = PDK::Util::Filesystem.expand_path('~/.puppetlabs/bolt/analytics.yaml')
51
51
  PDK::Config::YAML.new(file: file)
52
52
  rescue PDK::Config::LoadError => e
53
53
  PDK.logger.debug _('Unable to load %{file}: %{message}') % {
@@ -27,7 +27,7 @@ module PDK
27
27
  # used for settings which a randomly generated, instead of being deterministic, e.g. analytics user-id
28
28
  # @param block [Proc] a block that is evaluated within the new instance.
29
29
  def initialize(name = nil, file: nil, parent: nil, persistent_defaults: false, &block)
30
- @file = File.expand_path(file) unless file.nil?
30
+ @file = PDK::Util::Filesystem.expand_path(file) unless file.nil?
31
31
  @settings = {}
32
32
  @name = name.to_s
33
33
  @parent = parent
@@ -3,8 +3,6 @@ require 'pdk'
3
3
  module PDK
4
4
  module Generate
5
5
  class Module
6
- extend PDK::Util::Filesystem
7
-
8
6
  def self.validate_options(opts)
9
7
  require 'pdk/cli/util/option_validator'
10
8
 
@@ -16,28 +14,26 @@ module PDK
16
14
  raise PDK::CLI::ExitWithError, error_msg
17
15
  end
18
16
 
19
- target_dir = File.expand_path(opts[:target_dir])
20
- raise PDK::CLI::ExitWithError, _("The destination directory '%{dir}' already exists") % { dir: target_dir } if File.exist?(target_dir)
17
+ target_dir = PDK::Util::Filesystem.expand_path(opts[:target_dir])
18
+ raise PDK::CLI::ExitWithError, _("The destination directory '%{dir}' already exists") % { dir: target_dir } if PDK::Util::Filesystem.exist?(target_dir)
21
19
  end
22
20
 
23
21
  def self.invoke(opts = {})
24
- require 'pdk/module/templatedir'
25
22
  require 'pdk/util'
26
23
  require 'pdk/util/template_uri'
27
- require 'fileutils'
28
24
  require 'pathname'
29
25
 
30
26
  validate_options(opts) unless opts[:module_name].nil?
31
27
 
32
28
  metadata = prepare_metadata(opts)
33
29
 
34
- target_dir = File.expand_path(opts[:target_dir] || opts[:module_name])
30
+ target_dir = PDK::Util::Filesystem.expand_path(opts[:target_dir] || opts[:module_name])
35
31
  parent_dir = File.dirname(target_dir)
36
32
 
37
33
  begin
38
34
  test_file = File.join(parent_dir, '.pdk-test-writable')
39
- write_file(test_file, 'This file was created by the Puppet Development Kit to test if this folder was writable, you can safely remove this file.')
40
- FileUtils.rm_f(test_file)
35
+ PDK::Util::Filesystem.write_file(test_file, 'This file was created by the Puppet Development Kit to test if this folder was writable, you can safely remove this file.')
36
+ PDK::Util::Filesystem.rm_f(test_file)
41
37
  rescue Errno::EACCES
42
38
  raise PDK::CLI::FatalError, _("You do not have permission to write to '%{parent_dir}'") % {
43
39
  parent_dir: parent_dir,
@@ -51,12 +47,12 @@ module PDK
51
47
  template_uri = PDK::Util::TemplateURI.new(opts)
52
48
 
53
49
  begin
54
- PDK::Module::TemplateDir.new(template_uri, metadata.data, true) do |templates|
50
+ PDK::Module::TemplateDir.with(template_uri, metadata.data, true) do |templates|
55
51
  templates.render do |file_path, file_content, file_status|
56
52
  next if file_status == :delete
57
53
  file = Pathname.new(temp_target_dir) + file_path
58
54
  file.dirname.mkpath
59
- write_file(file, file_content)
55
+ PDK::Util::Filesystem.write_file(file, file_content)
60
56
  end
61
57
 
62
58
  # Add information about the template used to generate the module to the
@@ -83,7 +79,7 @@ module PDK
83
79
  end
84
80
 
85
81
  begin
86
- if FileUtils.mv(temp_target_dir, target_dir)
82
+ if PDK::Util::Filesystem.mv(temp_target_dir, target_dir)
87
83
  unless opts[:'skip-bundle-install']
88
84
  Dir.chdir(target_dir) do
89
85
  require 'pdk/util/bundler'
@@ -91,7 +87,7 @@ module PDK
91
87
  end
92
88
  end
93
89
 
94
- PDK.logger.info _('Module \'%{name}\' generated at path \'%{path}\', from template \'%{url}\'.') % { name: opts[:module_name], path: target_dir, url: template_uri.git_remote }
90
+ PDK.logger.info _('Module \'%{name}\' generated at path \'%{path}\', from template \'%{url}\'.') % { name: opts[:module_name], path: target_dir, url: template_uri.bare_uri }
95
91
  PDK.logger.info(_('In your module directory, add classes with the \'pdk new class\' command.'))
96
92
  end
97
93
  rescue Errno::EACCES => e
@@ -139,8 +135,6 @@ module PDK
139
135
  end
140
136
 
141
137
  def self.prepare_module_directory(target_dir)
142
- require 'fileutils'
143
-
144
138
  [
145
139
  File.join(target_dir, 'examples'),
146
140
  File.join(target_dir, 'files'),
@@ -149,7 +143,7 @@ module PDK
149
143
  File.join(target_dir, 'tasks'),
150
144
  ].each do |dir|
151
145
  begin
152
- FileUtils.mkdir_p(dir)
146
+ PDK::Util::Filesystem.mkdir_p(dir)
153
147
  rescue SystemCallError => e
154
148
  raise PDK::CLI::FatalError, _("Unable to create directory '%{dir}': %{message}") % {
155
149
  dir: dir,
@@ -269,7 +263,7 @@ module PDK
269
263
 
270
264
  interview.add_questions(questions)
271
265
 
272
- if File.file?('metadata.json')
266
+ if PDK::Util::Filesystem.file?('metadata.json')
273
267
  puts _(
274
268
  "\nWe need to update the metadata.json file for this module, so we\'re going to ask you %{count} " \
275
269
  "questions.\n",
@@ -260,7 +260,6 @@ module PDK
260
260
  # @api private
261
261
  def with_templates
262
262
  require 'pdk/logger'
263
- require 'pdk/module/templatedir'
264
263
  require 'pdk/util/template_uri'
265
264
 
266
265
  templates.each do |template|
@@ -269,7 +268,7 @@ module PDK
269
268
  next
270
269
  end
271
270
 
272
- PDK::Module::TemplateDir.new(PDK::Util::TemplateURI.new(template[:uri])) do |template_dir|
271
+ PDK::Module::TemplateDir.with(PDK::Util::TemplateURI.new(template[:uri])) do |template_dir|
273
272
  template_paths = template_dir.object_template_for(object_type)
274
273
 
275
274
  if template_paths
@@ -54,7 +54,7 @@ module PDK
54
54
  error = _("A task named '%{name}' already exists in this module; defined in %{file}")
55
55
  allowed_extensions = %w[.md .conf]
56
56
 
57
- Dir.glob(File.join(module_dir, 'tasks', "#{task_name}.*")).each do |file|
57
+ PDK::Util::Filesystem.glob(File.join(module_dir, 'tasks', "#{task_name}.*")).each do |file|
58
58
  next if allowed_extensions.include?(File.extname(file))
59
59
 
60
60
  raise PDK::CLI::ExitWithError, error % { name: task_name, file: file }
@@ -3,7 +3,8 @@ module PDK
3
3
  autoload :Build, 'pdk/module/build'
4
4
  autoload :Convert, 'pdk/module/convert'
5
5
  autoload :Metadata, 'pdk/module/metadata'
6
- autoload :TemplateDir, 'pdk/module/templatedir'
6
+ autoload :Release, 'pdk/module/release'
7
+ autoload :TemplateDir, 'pdk/module/template_dir'
7
8
  autoload :UpdateManager, 'pdk/module/update_manager'
8
9
  autoload :Update, 'pdk/module/update'
9
10
 
@@ -11,8 +11,8 @@ module PDK
11
11
  attr_reader :target_dir
12
12
 
13
13
  def initialize(options = {})
14
- @module_dir = File.expand_path(options[:module_dir] || Dir.pwd)
15
- @target_dir = File.expand_path(options[:'target-dir'] || File.join(module_dir, 'pkg'))
14
+ @module_dir = PDK::Util::Filesystem.expand_path(options[:module_dir] || Dir.pwd)
15
+ @target_dir = PDK::Util::Filesystem.expand_path(options[:'target-dir'] || File.join(module_dir, 'pkg'))
16
16
  end
17
17
 
18
18
  # Read and parse the values from metadata.json for the module that is
@@ -47,7 +47,7 @@ module PDK
47
47
  # Verify if there is an existing package in the target directory and prompts
48
48
  # the user if they want to overwrite it.
49
49
  def package_already_exists?
50
- File.exist? package_file
50
+ PDK::Util::Filesystem.exist?(package_file)
51
51
  end
52
52
 
53
53
  # Check if the module is PDK Compatible. If not, then prompt the user if
@@ -67,20 +67,16 @@ module PDK
67
67
  #
68
68
  # If the directory already exists, remove it first.
69
69
  def create_build_dir
70
- require 'fileutils'
71
-
72
70
  cleanup_build_dir
73
71
 
74
- FileUtils.mkdir_p(build_dir)
72
+ PDK::Util::Filesystem.mkdir_p(build_dir)
75
73
  end
76
74
 
77
75
  # Remove the temporary build directory and all its contents from disk.
78
76
  #
79
77
  # @return nil.
80
78
  def cleanup_build_dir
81
- require 'fileutils'
82
-
83
- FileUtils.rm_rf(build_dir, secure: true)
79
+ PDK::Util::Filesystem.rm_rf(build_dir, secure: true)
84
80
  end
85
81
 
86
82
  # Combine the module name and version into a Forge-compatible dash
@@ -115,18 +111,17 @@ module PDK
115
111
  # @return nil.
116
112
  def stage_path(path)
117
113
  require 'pathname'
118
- require 'fileutils'
119
114
 
120
115
  relative_path = Pathname.new(path).relative_path_from(Pathname.new(module_dir))
121
116
  dest_path = File.join(build_dir, relative_path)
122
117
 
123
- if File.directory?(path)
124
- FileUtils.mkdir_p(dest_path, mode: File.stat(path).mode)
125
- elsif File.symlink?(path)
118
+ if PDK::Util::Filesystem.directory?(path)
119
+ PDK::Util::Filesystem.mkdir_p(dest_path, mode: PDK::Util::Filesystem.stat(path).mode)
120
+ elsif PDK::Util::Filesystem.symlink?(path)
126
121
  warn_symlink(path)
127
122
  else
128
123
  validate_ustar_path!(relative_path.to_path)
129
- FileUtils.cp(path, dest_path, preserve: true)
124
+ PDK::Util::Filesystem.cp(path, dest_path, preserve: true)
130
125
  end
131
126
  rescue ArgumentError => e
132
127
  raise PDK::CLI::ExitWithError, _(
@@ -142,7 +137,7 @@ module PDK
142
137
  #
143
138
  # @return [Boolean] true if the path matches and should be ignored.
144
139
  def ignored_path?(path)
145
- path = path.to_s + '/' if File.directory?(path)
140
+ path = path.to_s + '/' if PDK::Util::Filesystem.directory?(path)
146
141
 
147
142
  !ignored_files.match_paths([path], module_dir).empty?
148
143
  end
@@ -224,23 +219,22 @@ module PDK
224
219
  #
225
220
  # @return nil.
226
221
  def build_package
227
- require 'fileutils'
228
222
  require 'zlib'
229
223
  require 'minitar'
230
224
  require 'find'
231
225
 
232
- FileUtils.rm_f(package_file)
226
+ PDK::Util::Filesystem.rm_f(package_file)
233
227
 
234
228
  Dir.chdir(target_dir) do
235
229
  begin
236
- gz = Zlib::GzipWriter.new(File.open(package_file, 'wb'))
230
+ gz = Zlib::GzipWriter.new(File.open(package_file, 'wb')) # rubocop:disable PDK/FileOpen
237
231
  tar = Minitar::Output.new(gz)
238
232
  Find.find(release_name) do |entry|
239
233
  entry_meta = {
240
234
  name: entry,
241
235
  }
242
236
 
243
- orig_mode = File.stat(entry).mode
237
+ orig_mode = PDK::Util::Filesystem.stat(entry).mode
244
238
  min_mode = Minitar.dir?(entry) ? 0o755 : 0o644
245
239
 
246
240
  entry_meta[:mode] = orig_mode | min_mode
@@ -272,7 +266,7 @@ module PDK
272
266
  File.join(module_dir, '.pdkignore'),
273
267
  File.join(module_dir, '.pmtignore'),
274
268
  File.join(module_dir, '.gitignore'),
275
- ].find { |file| File.file?(file) && File.readable?(file) }
269
+ ].find { |file| PDK::Util::Filesystem.file?(file) && PDK::Util::Filesystem.readable?(file) }
276
270
  end
277
271
 
278
272
  # Instantiate a new PathSpec class and populate it with the pattern(s) of
@@ -288,11 +282,7 @@ module PDK
288
282
  ignored = if ignore_file.nil?
289
283
  PathSpec.new
290
284
  else
291
- fd = File.open(ignore_file, 'rb:UTF-8')
292
- data = fd.read
293
- fd.close
294
-
295
- PathSpec.new(data)
285
+ PathSpec.new(PDK::Util::Filesystem.read_file(ignore_file, open_args: 'rb:UTF-8'))
296
286
  end
297
287
 
298
288
  if File.realdirpath(target_dir).start_with?(File.realdirpath(module_dir))
@@ -112,12 +112,11 @@ module PDK
112
112
  end
113
113
 
114
114
  def stage_changes!
115
- require 'pdk/module/templatedir'
116
115
  require 'pdk/util/filesystem'
117
116
 
118
117
  metadata_path = 'metadata.json'
119
118
 
120
- PDK::Module::TemplateDir.new(template_uri, nil, true) do |templates|
119
+ PDK::Module::TemplateDir.with(template_uri, nil, true) do |templates|
121
120
  new_metadata = update_metadata(metadata_path, templates.metadata)
122
121
  templates.module_metadata = new_metadata.data unless new_metadata.nil?
123
122
 
@@ -251,13 +250,9 @@ module PDK
251
250
  def full_report(path)
252
251
  require 'pdk/report'
253
252
 
254
- File.open(path, 'w') do |f|
255
- f.write("/* Report generated by PDK at #{Time.now} */")
256
- update_manager.changes[:modified].each do |_, diff|
257
- f.write("\n\n\n" + diff)
258
- end
259
- f.write("\n")
260
- end
253
+ report = ["/* Report generated by PDK at #{Time.now} */"]
254
+ report.concat(update_manager.changes[:modified].map { |_, diff| "\n\n\n#{diff}" })
255
+ PDK::Util::Filesystem.write_file(path, report.join)
261
256
  PDK::Report.default_target.puts(_("\nYou can find a report of differences in %{path}.\n\n") % { path: path })
262
257
  end
263
258
 
@@ -5,8 +5,6 @@ module PDK
5
5
  class Metadata
6
6
  attr_accessor :data
7
7
 
8
- include PDK::Util::Filesystem
9
-
10
8
  OPERATING_SYSTEMS = {
11
9
  'RedHat based Linux' => [
12
10
  {
@@ -127,7 +125,7 @@ module PDK
127
125
  end
128
126
 
129
127
  def write!(path)
130
- write_file(path, to_json)
128
+ PDK::Util::Filesystem.write_file(path, to_json)
131
129
  end
132
130
 
133
131
  def forge_ready?
@@ -0,0 +1,260 @@
1
+ require 'pdk'
2
+
3
+ module PDK
4
+ module Module
5
+ class Release
6
+ def self.invoke(module_path, options = {})
7
+ new(module_path, options).run
8
+ end
9
+
10
+ attr_reader :options
11
+
12
+ attr_reader :module_path
13
+
14
+ def initialize(module_path, options = {})
15
+ @options = options
16
+
17
+ # TODO: Currently the release process can ONLY be run if the working directory IS the module root. However, in the future
18
+ # this WILL change, so we have the API arguments for it, but only accept `nil` for the first parameter
19
+ raise PDK::CLI::ExitWithError, _('Running the release process outside of the working directory is not supported') unless module_path.nil?
20
+
21
+ if module_path.nil?
22
+ module_path = PDK::Util.module_root
23
+ raise PDK::CLI::ExitWithError, _('The module release process requires a valid module path') % { module_path: module_path } if module_path.nil?
24
+ end
25
+ raise PDK::CLI::ExitWithError, _('%{module_path} is not a valid module') % { module_path: module_path } unless PDK::Util.in_module_root?(module_path)
26
+ @module_path = module_path
27
+ end
28
+
29
+ def run
30
+ # Pre-release checks
31
+ unless force?
32
+ raise PDK::CLI::ExitWithError, _('The module is not PDK compatible') if requires_pdk_compatibility? && !pdk_compatible?
33
+ raise PDK::CLI::ExitWithError, _('The module is not Forge compatible') if requires_forge_compatibility? && !forge_compatible?
34
+ end
35
+
36
+ # Note that these checks are duplicated in the run_publish method, however it's a much better
37
+ # experience to fail early, than going through the whole process, only to error at the end knowing full well
38
+ # it'll fail anyway.
39
+ validate_publish_options!
40
+
41
+ run_validations(options) unless skip_validation?
42
+
43
+ PDK.logger.info _('Releasing %{module_name} - from version %{module_version}') % {
44
+ module_name: module_metadata.data['name'],
45
+ module_version: module_metadata.data['version'],
46
+ }
47
+
48
+ PDK::Util::ChangelogGenerator.generate_changelog unless skip_changelog?
49
+
50
+ # Calculate the new module version
51
+ new_version = specified_version
52
+ if new_version.nil? && !skip_changelog?
53
+ new_version = PDK::Util::ChangelogGenerator.compute_next_version(module_metadata.data['version'])
54
+ end
55
+ new_version = module_metadata.data['version'] if new_version.nil?
56
+
57
+ if new_version != module_metadata.data['version']
58
+ PDK.logger.info _('Updating version to %{module_version}') % {
59
+ module_version: new_version,
60
+ }
61
+
62
+ # Set the new version in metadata file
63
+ module_metadata.data['version'] = new_version
64
+ write_module_metadata!
65
+
66
+ # Update the changelog with the correct version
67
+ PDK::Util::ChangelogGenerator.generate_changelog unless skip_changelog?
68
+ end
69
+
70
+ run_documentation(options) unless skip_documentation?
71
+
72
+ run_dependency_checker(options) unless skip_dependency?
73
+
74
+ if skip_build?
75
+ # Even if we're skipping the build, we still need the name of the tarball
76
+ # Use the specified package path if set
77
+ package_file = specified_package if package_file.nil?
78
+ # Use the default as a last resort
79
+ package_file = default_package_filename if package_file.nil?
80
+ else
81
+ package_file = run_build(options)
82
+ end
83
+
84
+ run_publish(options.dup, package_file) unless skip_publish?
85
+ end
86
+
87
+ def module_metadata
88
+ @module_metada ||= PDK::Module::Metadata.from_file(File.join(module_path, 'metadata.json'))
89
+ end
90
+
91
+ def write_module_metadata!
92
+ module_metadata.write!(File.join(module_path, 'metadata.json'))
93
+ clear_cached_data
94
+ end
95
+
96
+ def default_package_filename
97
+ return @default_tarball_filename unless @default_tarball_filename.nil?
98
+ builder = PDK::Module::Build.new(module_dir: module_path)
99
+ @default_tarball_filename = builder.package_file
100
+ end
101
+
102
+ def run_validations(opts)
103
+ # TODO: Surely I can use a pre-existing class for this?
104
+ PDK::CLI::Util.validate_puppet_version_opts(opts)
105
+
106
+ PDK::CLI::Util.module_version_check
107
+
108
+ report = PDK::Report.new
109
+ puppet_env = PDK::CLI::Util.puppet_from_opts_or_env(opts)
110
+ PDK::Util::PuppetVersion.fetch_puppet_dev if opts[:'puppet-dev']
111
+ PDK::Util::RubyVersion.use(puppet_env[:ruby_version])
112
+
113
+ opts = opts.merge(puppet_env[:gemset])
114
+
115
+ PDK::Util::Bundler.ensure_bundle!(puppet_env[:gemset])
116
+
117
+ validators = PDK::Validate.validators
118
+ validators.each do |validator|
119
+ validator_exit_code = validator.invoke(report, opts.dup)
120
+ raise PDK::CLI::ExitWithError, _('An error occured during validation') unless validator_exit_code.zero?
121
+ end
122
+ end
123
+
124
+ def run_documentation(_opts)
125
+ PDK.logger.info _('Updating documentation using puppet strings')
126
+ docs_command = PDK::CLI::Exec::InteractiveCommand.new(PDK::CLI::Exec.bundle_bin, 'exec', 'puppet', 'strings', 'generate', '--format', 'markdown', '--out', 'REFERENCE.md')
127
+ docs_command.context = :module
128
+ result = docs_command.execute!
129
+ raise PDK::CLI::ExitWithError, _('An error occured generating the module documentation: %{stdout}') % { stdout: result[:stdout] } unless result[:exit_code].zero?
130
+ end
131
+
132
+ def run_dependency_checker(_opts)
133
+ # run dependency-checker and output dependent modules list
134
+ PDK.logger.info _('Running dependency checks')
135
+
136
+ dep_command = PDK::CLI::Exec::Command.new('dependency-checker', 'metadata.json')
137
+ dep_command.context = :module
138
+ result = dep_command.execute!
139
+
140
+ raise PDK::CLI::ExitWithError, _('An error occured checking the module dependencies: %{stdout}') % { stdout: result[:stdout] } unless result[:exit_code].zero?
141
+ end
142
+
143
+ # @return [String] Path to the built tarball
144
+ def run_build(opts)
145
+ PDK::Module::Build.invoke(opts.dup)
146
+ end
147
+
148
+ def run_publish(_opts, tarball_path)
149
+ validate_publish_options!
150
+ raise PDK::CLI::ExitWithError, _('Module tarball %{tarball_path} does not exist') % { tarball_path: tarball_path } unless PDK::Util::Filesystem.file?(tarball_path)
151
+
152
+ # TODO: Replace this code when the upload functionality is added to the forge ruby gem
153
+ require 'base64'
154
+ file_data = Base64.encode64(PDK::Util::Filesystem.read_file(tarball_path, open_args: 'rb'))
155
+
156
+ PDK.logger.info _('Uploading tarball to puppet forge...')
157
+ uri = URI(forge_upload_url)
158
+ require 'net/http'
159
+ request = Net::HTTP::Post.new(uri.path)
160
+ request['Authorization'] = 'Bearer ' + forge_token
161
+ request['Content-Type'] = 'application/json'
162
+ data = { file: file_data }
163
+
164
+ request.body = data.to_json
165
+
166
+ require 'openssl'
167
+ use_ssl = uri.class == URI::HTTPS
168
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: use_ssl) do |http|
169
+ http.request(request)
170
+ end
171
+
172
+ raise PDK::CLI::ExitWithError, _('Error uploading to Puppet Forge: %{result}') % { result: response } unless response.is_a?(Net::HTTPSuccess)
173
+ PDK.logger.info _('Publish to Forge was successful')
174
+ end
175
+
176
+ def validate_publish_options!
177
+ return if skip_publish?
178
+ raise PDK::CLI::ExitWithError, _('Missing forge-upload-url option') unless forge_upload_url
179
+ raise PDK::CLI::ExitWithError, _('Missing forge-token option') unless forge_token
180
+ end
181
+
182
+ def force?
183
+ options[:force]
184
+ end
185
+
186
+ def skip_build?
187
+ options[:'skip-build']
188
+ end
189
+
190
+ def skip_changelog?
191
+ options[:'skip-changelog']
192
+ end
193
+
194
+ def skip_dependency?
195
+ options[:'skip-dependency']
196
+ end
197
+
198
+ def skip_documentation?
199
+ options[:'skip-documentation']
200
+ end
201
+
202
+ def skip_publish?
203
+ options[:'skip-publish']
204
+ end
205
+
206
+ def skip_validation?
207
+ options[:'skip-validation']
208
+ end
209
+
210
+ def specified_version
211
+ options[:version]
212
+ end
213
+
214
+ def specified_package
215
+ options[:file]
216
+ end
217
+
218
+ def forge_token
219
+ options[:'forge-token']
220
+ end
221
+
222
+ def forge_upload_url
223
+ options[:'forge-upload-url']
224
+ end
225
+
226
+ def requires_pdk_compatibility?
227
+ # Validation, Changelog and Dependency checks require the
228
+ # module to be PDK Compatible
229
+ !(skip_validation? && skip_changelog? && skip_dependency?)
230
+ end
231
+
232
+ def requires_forge_compatibility?
233
+ # Pushing to the for requires the metadata to be forge compatible
234
+ !skip_publish?
235
+ end
236
+
237
+ #:nocov:
238
+ # These are just convenience methods and are tested elsewhere
239
+ def forge_compatible?
240
+ module_metadata.forge_ready?
241
+ end
242
+
243
+ def pdk_compatible?
244
+ return @pdk_compatible unless @pdk_compatible.nil?
245
+
246
+ builder = PDK::Module::Build.new(module_dir: module_path)
247
+ @pdk_compatible = builder.module_pdk_compatible?
248
+ end
249
+ #:nocov:
250
+
251
+ private
252
+
253
+ def clear_cached_data
254
+ @module_metadata = nil
255
+ @pdk_compatible = nil
256
+ @default_tarball_filename = nil
257
+ end
258
+ end
259
+ end
260
+ end