pdk-akerl 1.9.1.1 → 1.14.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +180 -0
  3. data/README.md +43 -4
  4. data/lib/pdk.rb +4 -2
  5. data/lib/pdk/analytics.rb +44 -0
  6. data/lib/pdk/analytics/client/google_analytics.rb +141 -0
  7. data/lib/pdk/analytics/client/noop.rb +23 -0
  8. data/lib/pdk/analytics/util.rb +17 -0
  9. data/lib/pdk/answer_file.rb +4 -1
  10. data/lib/pdk/cli.rb +50 -3
  11. data/lib/pdk/cli/build.rb +10 -4
  12. data/lib/pdk/cli/bundle.rb +10 -8
  13. data/lib/pdk/cli/config.rb +20 -0
  14. data/lib/pdk/cli/config/get.rb +24 -0
  15. data/lib/pdk/cli/console.rb +148 -0
  16. data/lib/pdk/cli/convert.rb +7 -2
  17. data/lib/pdk/cli/exec.rb +22 -190
  18. data/lib/pdk/cli/exec/command.rb +238 -0
  19. data/lib/pdk/cli/exec/interactive_command.rb +114 -0
  20. data/lib/pdk/cli/exec_group.rb +6 -6
  21. data/lib/pdk/cli/module/build.rb +0 -2
  22. data/lib/pdk/cli/module/generate.rb +4 -2
  23. data/lib/pdk/cli/new.rb +2 -0
  24. data/lib/pdk/cli/new/class.rb +2 -2
  25. data/lib/pdk/cli/new/defined_type.rb +4 -2
  26. data/lib/pdk/cli/new/module.rb +5 -0
  27. data/lib/pdk/cli/new/provider.rb +4 -2
  28. data/lib/pdk/cli/new/task.rb +4 -1
  29. data/lib/pdk/cli/new/test.rb +53 -0
  30. data/lib/pdk/cli/new/transport.rb +27 -0
  31. data/lib/pdk/cli/test.rb +0 -1
  32. data/lib/pdk/cli/test/unit.rb +18 -13
  33. data/lib/pdk/cli/update.rb +25 -3
  34. data/lib/pdk/cli/util.rb +111 -14
  35. data/lib/pdk/cli/util/interview.rb +10 -2
  36. data/lib/pdk/cli/util/option_validator.rb +4 -0
  37. data/lib/pdk/cli/util/spinner.rb +13 -0
  38. data/lib/pdk/cli/validate.rb +16 -5
  39. data/lib/pdk/config.rb +121 -0
  40. data/lib/pdk/config/analytics_schema.json +26 -0
  41. data/lib/pdk/config/errors.rb +5 -0
  42. data/lib/pdk/config/json.rb +34 -0
  43. data/lib/pdk/config/json_schema_namespace.rb +143 -0
  44. data/lib/pdk/config/json_schema_setting.rb +53 -0
  45. data/lib/pdk/config/json_with_schema.rb +50 -0
  46. data/lib/pdk/config/namespace.rb +332 -0
  47. data/lib/pdk/config/setting.rb +132 -0
  48. data/lib/pdk/config/yaml.rb +43 -0
  49. data/lib/pdk/config/yaml_with_schema.rb +59 -0
  50. data/lib/pdk/generate.rb +10 -3
  51. data/lib/pdk/generate/defined_type.rb +1 -0
  52. data/lib/pdk/generate/module.rb +62 -35
  53. data/lib/pdk/generate/provider.rb +0 -5
  54. data/lib/pdk/generate/puppet_class.rb +1 -0
  55. data/lib/pdk/generate/puppet_object.rb +88 -41
  56. data/lib/pdk/generate/transport.rb +87 -0
  57. data/lib/pdk/logger.rb +21 -1
  58. data/lib/pdk/module.rb +2 -2
  59. data/lib/pdk/module/build.rb +103 -10
  60. data/lib/pdk/module/convert.rb +85 -19
  61. data/lib/pdk/module/metadata.rb +17 -12
  62. data/lib/pdk/module/templatedir.rb +108 -40
  63. data/lib/pdk/module/update.rb +27 -15
  64. data/lib/pdk/module/update_manager.rb +23 -15
  65. data/lib/pdk/report.rb +4 -3
  66. data/lib/pdk/report/event.rb +8 -6
  67. data/lib/pdk/template_file.rb +1 -1
  68. data/lib/pdk/tests/unit.rb +48 -21
  69. data/lib/pdk/util.rb +29 -63
  70. data/lib/pdk/util/bundler.rb +19 -15
  71. data/lib/pdk/util/filesystem.rb +64 -1
  72. data/lib/pdk/util/git.rb +52 -1
  73. data/lib/pdk/util/puppet_strings.rb +123 -0
  74. data/lib/pdk/util/puppet_version.rb +27 -12
  75. data/lib/pdk/util/ruby_version.rb +30 -7
  76. data/lib/pdk/util/template_uri.rb +281 -0
  77. data/lib/pdk/util/vendored_file.rb +28 -24
  78. data/lib/pdk/util/version.rb +7 -8
  79. data/lib/pdk/util/windows.rb +1 -0
  80. data/lib/pdk/util/windows/api_types.rb +0 -7
  81. data/lib/pdk/util/windows/file.rb +1 -1
  82. data/lib/pdk/util/windows/string.rb +1 -1
  83. data/lib/pdk/validate/base_validator.rb +12 -14
  84. data/lib/pdk/validate/metadata/metadata_json_lint.rb +0 -4
  85. data/lib/pdk/validate/metadata/metadata_syntax.rb +5 -3
  86. data/lib/pdk/validate/metadata_validator.rb +0 -2
  87. data/lib/pdk/validate/puppet/puppet_epp.rb +137 -0
  88. data/lib/pdk/validate/puppet/puppet_lint.rb +0 -3
  89. data/lib/pdk/validate/puppet/puppet_syntax.rb +5 -5
  90. data/lib/pdk/validate/puppet_validator.rb +2 -3
  91. data/lib/pdk/validate/ruby/rubocop.rb +1 -6
  92. data/lib/pdk/validate/ruby_validator.rb +0 -2
  93. data/lib/pdk/validate/tasks/metadata_lint.rb +9 -5
  94. data/lib/pdk/validate/tasks/name.rb +5 -3
  95. data/lib/pdk/validate/tasks_validator.rb +0 -2
  96. data/lib/pdk/validate/yaml/syntax.rb +6 -4
  97. data/lib/pdk/validate/yaml_validator.rb +0 -2
  98. data/lib/pdk/version.rb +1 -1
  99. data/locales/pdk.pot +634 -307
  100. metadata +100 -45
@@ -0,0 +1,132 @@
1
+ module PDK
2
+ class Config
3
+ # A class for describing the setting of a {PDK::Config} setting.
4
+ #
5
+ # Generally, this is never instantiated manually, but is instead
6
+ # instantiated by passing a block to {PDK::Config::Namespace#setting}.
7
+ #
8
+ # @example
9
+ #
10
+ # PDK::Config::Namespace.new('analytics') do
11
+ # setting :disabled do
12
+ # validate PDK::Config::Validator.boolean
13
+ # default_to { false }
14
+ # end
15
+ # end
16
+ class Setting
17
+ attr_reader :namespace
18
+
19
+ # It is possible to have multiple setting definitions for the same setting; for example, defining a default value with a lambda, but the
20
+ # the validation is within a JSON schema document. These are expressed as two settings objects, and uses a single linked list to join them
21
+ # together:
22
+ #
23
+ # (PDK::Config::JSONSchemaSetting) --previous_setting--> (PDK::Config::Setting)
24
+ #
25
+ # So in the example above, calling `default` the on the first object in the list will:
26
+ # 1. Look at `default` on PDK::Config::JSONSchemaSetting
27
+ # 2. If a default could not be found then it calls `default` on previous_setting
28
+ # 3. If a default could not be found then it calls `default` on previous_setting.previous_setting
29
+ # 4. and so on down the linked list (chain) of settings
30
+ attr_writer :previous_setting
31
+
32
+ # Initialises an empty setting definition.
33
+ #
34
+ # @param name [String,Symbol] the name of the setting.
35
+ # @param namespace [PDK::Config::Namespace] The namespace this setting belongs to
36
+ def initialize(name, namespace, initial_value = nil)
37
+ @name = name.to_s
38
+ @validators = []
39
+ @namespace = namespace
40
+ @value = initial_value
41
+ end
42
+
43
+ def qualified_name
44
+ [namespace.name, @name].join('.')
45
+ end
46
+
47
+ def value # rubocop:disable Style/TrivialAccessors
48
+ @value
49
+ end
50
+
51
+ def value=(obj)
52
+ validate!(obj)
53
+ @value = obj
54
+ end
55
+
56
+ def to_s
57
+ @value.to_s
58
+ end
59
+
60
+ # Assign a validator to the setting. Subclasses should not override this method.
61
+ #
62
+ # @param validator [Hash{Symbol => [Proc,String]}]
63
+ # @option validator [Proc] :proc a lambda that takes the setting to be
64
+ # validated as the argument and returns `true` if the setting is valid.
65
+ # @option validator [String] :message a description of what the validator
66
+ # is testing for, that is displayed to the user as part of the error
67
+ # message for invalid settings.
68
+ #
69
+ # @raise [ArgumentError] if not passed a Hash.
70
+ # @raise [ArgumentError] if the Hash doesn't have a `:proc` key that
71
+ # contains a Proc.
72
+ # @raise [ArgumentError] if the Hash doesn't have a `:message` key that
73
+ # contains a String.
74
+ #
75
+ # @return [nil]
76
+ def validate(validator)
77
+ raise ArgumentError, _('`validator` must be a Hash') unless validator.is_a?(Hash)
78
+ raise ArgumentError, _('the :proc key must contain a Proc') unless validator.key?(:proc) && validator[:proc].is_a?(Proc)
79
+ raise ArgumentError, _('the :message key must contain a String') unless validator.key?(:message) && validator[:message].is_a?(String)
80
+
81
+ @validators << validator
82
+ end
83
+
84
+ # Validate a setting against the assigned validators.
85
+ #
86
+ # @param setting [Object] the setting being validated.
87
+ #
88
+ # @raise [ArgumentError] if any of the assigned validators fail to
89
+ # validate the setting.
90
+ #
91
+ # @return [nil]
92
+ def validate!(value)
93
+ @validators.each do |validator|
94
+ next if validator[:proc].call(value)
95
+
96
+ raise ArgumentError, _('%{key} %{message}') % {
97
+ key: qualified_name,
98
+ message: validator[:message],
99
+ }
100
+ end
101
+ end
102
+
103
+ # Assign a default value proc for the setting. Subclasses should not override this method.
104
+ #
105
+ # @param block [Proc] a block that is lazy evaluated when necessary in
106
+ # order to determine the default setting.
107
+ #
108
+ # @return [nil]
109
+ def default_to(&block)
110
+ raise ArgumentError, _('must be passed a block') unless block_given?
111
+ @default_to = block
112
+ end
113
+
114
+ # Evaluate the default setting.
115
+ #
116
+ # @return [Object,nil] the result of evaluating the block given to
117
+ # {#default_to}, or `nil` if the setting has no default.
118
+ def default
119
+ return @default_to.call if default_block?
120
+ # If there is a previous setting in the chain, use its default
121
+ @previous_setting.nil? ? nil : @previous_setting.default
122
+ end
123
+
124
+ private
125
+
126
+ # @return [Boolean] true if the setting has a default setting block. Subclasses should not override this method.
127
+ def default_block?
128
+ !@default_to.nil?
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,43 @@
1
+ require 'pdk/config/namespace'
2
+ require 'pdk/config/setting'
3
+
4
+ module PDK
5
+ class Config
6
+ # Parses a YAML document.
7
+ #
8
+ # @see PDK::Config::Namespace.parse_file
9
+ class YAML < Namespace
10
+ def parse_file(filename)
11
+ raise unless block_given?
12
+ data = load_data(filename)
13
+ return if data.nil? || data.empty?
14
+
15
+ require 'yaml'
16
+
17
+ data = ::YAML.safe_load(data, [Symbol], [], true)
18
+ return if data.nil?
19
+
20
+ data.each { |k, v| yield k, PDK::Config::Setting.new(k, self, v) }
21
+ rescue Psych::SyntaxError => e
22
+ raise PDK::Config::LoadError, _('Syntax error when loading %{file}: %{error}') % {
23
+ file: filename,
24
+ error: "#{e.problem} #{e.context}",
25
+ }
26
+ rescue Psych::DisallowedClass => e
27
+ raise PDK::Config::LoadError, _('Unsupported class in %{file}: %{error}') % {
28
+ file: filename,
29
+ error: e.message,
30
+ }
31
+ end
32
+
33
+ # Serializes object data into a YAML string.
34
+ #
35
+ # @see PDK::Config::Namespace.serialize_data
36
+ def serialize_data(data)
37
+ require 'yaml'
38
+
39
+ ::YAML.dump(data)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,59 @@
1
+ require 'pdk/config/json_schema_namespace'
2
+
3
+ module PDK
4
+ class Config
5
+ # Parses a YAML document with a JSON schema.
6
+ #
7
+ # @see PDK::Config::Namespace.parse_file
8
+ class YAMLWithSchema < JSONSchemaNamespace
9
+ def parse_file(filename)
10
+ raise unless block_given?
11
+ data = load_data(filename)
12
+ data = '' if data.nil?
13
+ require 'yaml'
14
+ require 'json-schema'
15
+
16
+ @raw_data = ::YAML.safe_load(data, [Symbol], [], true)
17
+ @raw_data = {} if @raw_data.nil?
18
+
19
+ begin
20
+ # Ensure the parsed document is actually valid
21
+ validate_document!(@raw_data)
22
+ rescue ::JSON::Schema::ValidationError => e
23
+ raise PDK::Config::LoadError, _('The configuration file %{filename} is not valid: %{message}') % {
24
+ filename: filename,
25
+ message: e.message,
26
+ }
27
+ end
28
+
29
+ require 'pdk/config/json_schema_setting'
30
+
31
+ schema_property_names.each do |key|
32
+ yield key, PDK::Config::JSONSchemaSetting.new(key, self, @raw_data[key])
33
+ end
34
+
35
+ # Remove all of the "known" settings from the schema and
36
+ # we're left with the settings that we don't manage.
37
+ self.unmanaged_settings = @raw_data.reject { |k, _| schema_property_names.include?(k) }
38
+ rescue Psych::SyntaxError => e
39
+ raise PDK::Config::LoadError, _('Syntax error when loading %{file}: %{error}') % {
40
+ file: filename,
41
+ error: "#{e.problem} #{e.context}",
42
+ }
43
+ rescue Psych::DisallowedClass => e
44
+ raise PDK::Config::LoadError, _('Unsupported class in %{file}: %{error}') % {
45
+ file: filename,
46
+ error: e.message,
47
+ }
48
+ end
49
+
50
+ # Serializes object data into a YAML string.
51
+ #
52
+ # @see PDK::Config::Namespace.serialize_data
53
+ def serialize_data(data)
54
+ require 'yaml'
55
+ ::YAML.dump(data)
56
+ end
57
+ end
58
+ end
59
+ end
data/lib/pdk/generate.rb CHANGED
@@ -3,9 +3,16 @@ require 'pdk/generate/module'
3
3
  require 'pdk/generate/provider'
4
4
  require 'pdk/generate/puppet_class'
5
5
  require 'pdk/generate/task'
6
- require 'pdk/module/metadata'
7
- require 'pdk/module/templatedir'
6
+ require 'pdk/generate/transport'
8
7
 
9
8
  module PDK
10
- module Generate; end
9
+ module Generate
10
+ GENERATORS = [
11
+ PDK::Generate::DefinedType,
12
+ PDK::Generate::Provider,
13
+ PDK::Generate::PuppetClass,
14
+ PDK::Generate::Task,
15
+ PDK::Generate::Transport,
16
+ ].freeze
17
+ end
11
18
  end
@@ -4,6 +4,7 @@ module PDK
4
4
  module Generate
5
5
  class DefinedType < PuppetObject
6
6
  OBJECT_TYPE = :defined_type
7
+ PUPPET_STRINGS_TYPE = 'defined_types'.freeze
7
8
 
8
9
  # Prepares the data needed to render the new defined type template.
9
10
  #
@@ -1,18 +1,4 @@
1
- require 'etc'
2
- require 'pathname'
3
- require 'fileutils'
4
- require 'tty-prompt'
5
-
6
- require 'pdk'
7
- require 'pdk/logger'
8
- require 'pdk/module/metadata'
9
- require 'pdk/module/templatedir'
10
- require 'pdk/cli/exec'
11
- require 'pdk/cli/util'
12
- require 'pdk/cli/util/interview'
13
- require 'pdk/cli/util/option_validator'
14
- require 'pdk/util'
15
- require 'pdk/util/version'
1
+ require 'pdk/util/filesystem'
16
2
 
17
3
  module PDK
18
4
  module Generate
@@ -20,6 +6,8 @@ module PDK
20
6
  extend PDK::Util::Filesystem
21
7
 
22
8
  def self.validate_options(opts)
9
+ require 'pdk/cli/util/option_validator'
10
+
23
11
  unless PDK::CLI::Util::OptionValidator.valid_module_name?(opts[:module_name])
24
12
  error_msg = _(
25
13
  "'%{module_name}' is not a valid module name.\n" \
@@ -33,6 +21,12 @@ module PDK
33
21
  end
34
22
 
35
23
  def self.invoke(opts = {})
24
+ require 'pdk/module/templatedir'
25
+ require 'pdk/util'
26
+ require 'pdk/util/template_uri'
27
+ require 'fileutils'
28
+ require 'pathname'
29
+
36
30
  validate_options(opts) unless opts[:module_name].nil?
37
31
 
38
32
  metadata = prepare_metadata(opts)
@@ -54,11 +48,12 @@ module PDK
54
48
 
55
49
  prepare_module_directory(temp_target_dir)
56
50
 
57
- template_url = opts.fetch(:'template-url', PDK::Util.default_template_url)
51
+ template_uri = PDK::Util::TemplateURI.new(opts)
58
52
 
59
53
  begin
60
- PDK::Module::TemplateDir.new(template_url, metadata.data, true) do |templates|
61
- templates.render do |file_path, file_content|
54
+ PDK::Module::TemplateDir.new(template_uri, metadata.data, true) do |templates|
55
+ templates.render do |file_path, file_content, file_status|
56
+ next if file_status == :delete
62
57
  file = Pathname.new(temp_target_dir) + file_path
63
58
  file.dirname.mkpath
64
59
  write_file(file, file_content)
@@ -74,21 +69,29 @@ module PDK
74
69
  raise PDK::CLI::ExitWithError, e
75
70
  end
76
71
 
77
- if template_url == PDK::Util.puppetlabs_template_url
78
- # If the user specifies our template via the command line, remove the
79
- # saved template-url answer.
72
+ # Only update the answers files after metadata has been written.
73
+ require 'pdk/answer_file'
74
+ if template_uri.default?
75
+ # If the user specifies our default template url via the command
76
+ # line, remove the saved template-url answer so that the template_uri
77
+ # resolution can find new default URLs in the future.
80
78
  PDK.answers.update!('template-url' => nil) if opts.key?(:'template-url')
81
79
  else
82
- # Save the template-url answer if the module was generated using
83
- # a template other than ours.
84
- PDK.answers.update!('template-url' => template_url)
80
+ # Save the template-url answers if the module was generated using a
81
+ # template/reference other than ours.
82
+ PDK.answers.update!('template-url' => template_uri.metadata_format)
85
83
  end
86
84
 
87
85
  begin
88
86
  if FileUtils.mv(temp_target_dir, target_dir)
89
- Dir.chdir(target_dir) { PDK::Util::Bundler.ensure_bundle! } unless opts[:'skip-bundle-install']
87
+ unless opts[:'skip-bundle-install']
88
+ Dir.chdir(target_dir) do
89
+ require 'pdk/util/bundler'
90
+ PDK::Util::Bundler.ensure_bundle!
91
+ end
92
+ end
90
93
 
91
- PDK.logger.info(_('Module \'%{name}\' generated at path \'%{path}\', from template \'%{template_url}\'.') % { name: opts[:module_name], path: target_dir, template_url: template_url })
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 }
92
95
  PDK.logger.info(_('In your module directory, add classes with the \'pdk new class\' command.'))
93
96
  end
94
97
  rescue Errno::EACCES => e
@@ -101,6 +104,8 @@ module PDK
101
104
  end
102
105
 
103
106
  def self.username_from_login
107
+ require 'etc'
108
+
104
109
  login = Etc.getlogin || ''
105
110
  login_clean = login.downcase.gsub(%r{[^0-9a-z]}i, '')
106
111
  login_clean = 'username' if login_clean.empty?
@@ -115,6 +120,9 @@ module PDK
115
120
  end
116
121
 
117
122
  def self.prepare_metadata(opts = {})
123
+ require 'pdk/answer_file'
124
+ require 'pdk/module/metadata'
125
+
118
126
  opts[:username] = (opts[:username] || PDK.answers['forge_username'] || username_from_login).downcase
119
127
 
120
128
  defaults = PDK::Module::Metadata::DEFAULTS.dup
@@ -122,7 +130,7 @@ module PDK
122
130
  defaults['name'] = "#{opts[:username]}-#{opts[:module_name]}" unless opts[:module_name].nil?
123
131
  defaults['author'] = PDK.answers['author'] unless PDK.answers['author'].nil?
124
132
  defaults['license'] = PDK.answers['license'] unless PDK.answers['license'].nil?
125
- defaults['license'] = opts[:license] if opts.key? :license
133
+ defaults['license'] = opts[:license] if opts.key?(:license)
126
134
 
127
135
  metadata = PDK::Module::Metadata.new(defaults)
128
136
  module_interview(metadata, opts) unless opts[:'skip-interview']
@@ -131,6 +139,8 @@ module PDK
131
139
  end
132
140
 
133
141
  def self.prepare_module_directory(target_dir)
142
+ require 'fileutils'
143
+
134
144
  [
135
145
  File.join(target_dir, 'examples'),
136
146
  File.join(target_dir, 'files'),
@@ -150,6 +160,9 @@ module PDK
150
160
  end
151
161
 
152
162
  def self.module_interview(metadata, opts = {})
163
+ require 'pdk/module/metadata'
164
+ require 'pdk/cli/util/interview'
165
+
153
166
  questions = [
154
167
  {
155
168
  name: 'module_name',
@@ -197,6 +210,7 @@ module PDK
197
210
  question: _('What operating systems does this module support?'),
198
211
  help: _('Use the up and down keys to move between the choices, space to select and enter to continue.'),
199
212
  required: true,
213
+ type: :multi_select,
200
214
  choices: PDK::Module::Metadata::OPERATING_SYSTEMS,
201
215
  default: PDK::Module::Metadata::DEFAULT_OPERATING_SYSTEMS.map do |os_name|
202
216
  # tty-prompt uses a 1-index
@@ -250,22 +264,32 @@ module PDK
250
264
  else
251
265
  questions.reject! { |q| q[:name] == 'module_name' } if opts.key?(:module_name)
252
266
  questions.reject! { |q| q[:name] == 'license' } if opts.key?(:license)
253
- questions.reject! { |q| q[:forge_only] } unless opts.key?(:'full-interview')
267
+ questions.reject! { |q| q[:forge_only] } unless opts[:'full-interview']
254
268
  end
255
269
 
256
270
  interview.add_questions(questions)
257
271
 
258
- action = File.file?('metadata.json') ? _('update') : _('create')
272
+ if File.file?('metadata.json')
273
+ puts _(
274
+ "\nWe need to update the metadata.json file for this module, so we\'re going to ask you %{count} " \
275
+ "questions.\n",
276
+ ) % {
277
+ count: interview.num_questions,
278
+ }
279
+ else
280
+ puts _(
281
+ "\nWe need to create the metadata.json file for this module, so we\'re going to ask you %{count} " \
282
+ "questions.\n",
283
+ ) % {
284
+ count: interview.num_questions,
285
+ }
286
+ end
287
+
259
288
  puts _(
260
- "\nWe need to %{action} the metadata.json file for this module, so we\'re going to ask you %{count} " \
261
- "questions.\n" \
262
289
  'If the question is not applicable to this module, accept the default option ' \
263
290
  'shown after each question. You can modify any answers at any time by manually updating ' \
264
291
  "the metadata.json file.\n\n",
265
- ) % {
266
- count: interview.num_questions,
267
- action: action,
268
- }
292
+ )
269
293
 
270
294
  answers = interview.run
271
295
 
@@ -293,6 +317,8 @@ module PDK
293
317
  metadata.update!(answers)
294
318
 
295
319
  if opts[:prompt].nil? || opts[:prompt]
320
+ require 'pdk/cli/util'
321
+
296
322
  continue = PDK::CLI::Util.prompt_for_yes(
297
323
  _('Metadata will be generated based on this information, continue?'),
298
324
  prompt: prompt,
@@ -305,6 +331,7 @@ module PDK
305
331
  end
306
332
  end
307
333
 
334
+ require 'pdk/answer_file'
308
335
  PDK.answers.update!(
309
336
  {
310
337
  'forge_username' => opts[:username],