pdk 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f22acd513e00856fbadcd4c5090b2787df655426
4
- data.tar.gz: 6636287e1acef4c9ba87f52b4b853c922e4ce92b
3
+ metadata.gz: 5501e7effa501cd2ba488735cc9abb8257ffef6a
4
+ data.tar.gz: e4f7a88496280db89b0ee46a42a7b8feacc24594
5
5
  SHA512:
6
- metadata.gz: 2ce7e0faffaac9a2484c23dc1e88f9b240e0d768d63c8c793439f9a560a95cfa31a8745b510d4c84b83e410639bae7eb004f9d91732fd7740b4650581f71969a
7
- data.tar.gz: d7a9e5bae06899f4972add88c8bc49053b257ce7aa10fb38537ea5101ea0e9ceae56e62e212bff6e07e372c558b6f38e9a9dc8ae290a6048d8fb7f72a64ddd0d
6
+ metadata.gz: 736c543069aa1b1d3eb79c8de901e91cf2491328fc3104f7bd660c37cafd88712583d471cbd2f4afd37b9c49890bfcb60c5b2857121f3cabb81841662fa53557
7
+ data.tar.gz: 5b5b03c6ac83fca4d730cba0db0277441d9bb062ed5f13ebecf24836d237db11856e6811f276ec2dcfafe28fd5c86a009958ef9e894021d14ba8a1e4d0a15af8
data/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
5
 
6
+ ## [v0.3.0](https://github.com/puppetlabs/pdk/tree/v0.3.0) (2017-06-29)
7
+ [Full Changelog](https://github.com/puppetlabs/pdk/compare/v0.2.0...v0.3.0)
8
+
9
+ **Implemented enhancements:**
10
+
11
+ - \(MAINT\) Add support for stacktrace to Report::Event class [\#112](https://github.com/puppetlabs/pdk/pull/112) ([scotje](https://github.com/scotje))
12
+ - \(MAINT\) Various CLI::Exec improvements and updates [\#111](https://github.com/puppetlabs/pdk/pull/111) ([scotje](https://github.com/scotje))
13
+ - \(SDK-148\) Add "test unit --list" [\#107](https://github.com/puppetlabs/pdk/pull/107) ([james-stocks](https://github.com/james-stocks))
14
+ - \(SDK-137\) Add puppet syntax validation [\#105](https://github.com/puppetlabs/pdk/pull/105) ([bmjen](https://github.com/bmjen))
15
+ - \(SDK-285\) Add --auto-correct flag to validators that support it [\#104](https://github.com/puppetlabs/pdk/pull/104) ([rodjek](https://github.com/rodjek))
16
+ - \(SDK-284\) Add guidance for users during new module interview [\#103](https://github.com/puppetlabs/pdk/pull/103) ([rodjek](https://github.com/rodjek))
17
+ - \(SDK-147\) Add 'test unit' runner and basic output formatting [\#98](https://github.com/puppetlabs/pdk/pull/98) ([scotje](https://github.com/scotje))
18
+
19
+ **Fixed bugs:**
20
+
21
+ - \(SDK-297\) Fixes writing reports to a file [\#119](https://github.com/puppetlabs/pdk/pull/119) ([bmjen](https://github.com/bmjen))
22
+ - \(SDK-290\) Make sure that all usernames are processed when creating a new module [\#108](https://github.com/puppetlabs/pdk/pull/108) ([austb](https://github.com/austb))
23
+ - \(SDK-277\) Exit cleanly if pdk commands are run outside of a module [\#100](https://github.com/puppetlabs/pdk/pull/100) ([rodjek](https://github.com/rodjek))
24
+
6
25
  ## [v0.2.0](https://github.com/puppetlabs/pdk/tree/v0.2.0) (2017-06-21)
7
26
  [Full Changelog](https://github.com/puppetlabs/pdk/compare/v0.1.0...v0.2.0)
8
27
 
data/README.md CHANGED
@@ -52,12 +52,48 @@ pdk validate
52
52
  This displays results in the console:
53
53
 
54
54
  ```
55
- Running validations on `new_module`:
56
- * ruby syntax: OK!
57
- * puppet syntax: OK!
55
+ pdk (INFO): Running all available validators...
56
+ [✔] Checking for missing Gemfile dependencies
57
+ [✔] Checking metadata.json
58
+ [✔] Checking Ruby code style
58
59
  [...]
59
60
  ```
60
61
 
62
+ Specific validators can be run by providing the validator name (or a comma
63
+ separated list of names) as an argument to `pdk validate`.
64
+
65
+ ```
66
+ $ pdk validate metadata
67
+ [✔] Checking for missing Gemfile dependencies
68
+ [✔] Checking metadata.json
69
+ ```
70
+
71
+ By default each validator will automatically determine which files in the
72
+ module that it should validate, however validations can be run on specific
73
+ files or directories by providing them as arguments to `pdk validate`
74
+
75
+ ```
76
+ $ pdk validate lib/
77
+ [✔] Checking for missing Gemfile dependencies
78
+ [✔] Checking Ruby code style
79
+ ```
80
+
81
+ Some validators support automatic correction of detected problems (for example,
82
+ both rubocop and puppet-lint can automatically correct many common code style
83
+ problems). To enable this functionality, run `pdk validate` with the
84
+ `--auto-correct` option.
85
+
86
+ ```
87
+ $ pdk validate --auto-correct
88
+ pdk (INFO): Running all available validators...
89
+ [✔] Checking for missing Gemfile dependencies
90
+ [✔] Checking metadata.json
91
+ [✔] Checking Puppet manifest style
92
+ [✔] Checking Puppet manifest syntax
93
+ [✔] Checking Ruby code style
94
+ manifests/init.pp:1:10: corrected: double quoted string containing no variables
95
+ ```
96
+
61
97
  ### Run unit tests
62
98
 
63
99
  The default template sets up [rspec](http://rspec.info/) for Ruby-level unit testing, and [rspec-puppet](https://github.com/rodjek/rspec-puppet/) for catalog-level unit testing.
@@ -262,3 +298,13 @@ bundle binstubs pdk --path ~/bin
262
298
  ```
263
299
 
264
300
  Bug reports and pull requests are welcome on GitHub at https://github.com/puppetlabs/pdk.
301
+
302
+ ### Release Process
303
+
304
+ 1. Bump the version in `lib/pdk/version.rb`.
305
+ 1. In a clean checkout of master, run `bundle exec rake changelog`.
306
+ 1. Edit PR titles and tags, until `bundle exec rake changelog` output makes sense.
307
+ 1. Commit and PR the changes.
308
+ 1. When the PR is merged, get a clean checkout of the merged commit, and run `bundle exec rake release[upstream]` (where "upstream" is your local name of the puppetlabs remote)
309
+ 1. Profit!
310
+ 1. Update `lib/pdk/version.rb` with `x.y.z-pre`, commit, and PR to prepare for next release.
data/lib/pdk/cli.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'cri'
2
2
 
3
3
  require 'pdk/cli/errors'
4
+ require 'pdk/cli/util'
4
5
  require 'pdk/cli/util/option_normalizer'
5
6
  require 'pdk/cli/util/option_validator'
6
7
  require 'pdk/generators/module'
data/lib/pdk/cli/exec.rb CHANGED
@@ -55,6 +55,7 @@ module PDK
55
55
  attr_reader :argv
56
56
  attr_reader :context
57
57
  attr_accessor :timeout
58
+ attr_accessor :environment
58
59
 
59
60
  def initialize(*argv)
60
61
  @argv = argv
@@ -70,6 +71,9 @@ module PDK
70
71
 
71
72
  # Default to running things in the system context.
72
73
  @context = :system
74
+
75
+ # Extra environment vars to add to base set.
76
+ @environment = {}
73
77
  end
74
78
 
75
79
  def context=(new_context)
@@ -84,19 +88,32 @@ module PDK
84
88
  @success_message = opts.delete(:success)
85
89
  @failure_message = opts.delete(:failure)
86
90
 
87
- @spinner = TTY::Spinner.new("[:spinner] #{message}", opts)
91
+ @spinner = Gem.win_platform? ? WindowsSpinner.new(message, opts) : TTY::Spinner.new("[:spinner] #{message}", opts)
88
92
  end
89
93
 
90
94
  def execute!
91
95
  # Start spinning if configured.
92
96
  @spinner.auto_spin if @spinner
93
97
 
98
+ # Add custom env vars.
99
+ @environment.each do |k, v|
100
+ @process.environment[k] = v
101
+ end
102
+
94
103
  if context == :module
95
104
  # TODO: we should probably more carefully manage PATH and maybe other things too
96
105
  @process.environment['GEM_HOME'] = File.join(PDK::Util.cachedir, 'bundler', 'ruby', RbConfig::CONFIG['ruby_version'])
97
106
  @process.environment['GEM_PATH'] = pdk_gem_path
98
107
 
99
- Dir.chdir(PDK::Util.module_root) do
108
+ mod_root = PDK::Util.module_root
109
+
110
+ unless mod_root
111
+ @spinner.error
112
+
113
+ raise PDK::CLI::FatalError, _('Current working directory is not part of a module. (No metadata.json was found.)')
114
+ end
115
+
116
+ Dir.chdir(mod_root) do
100
117
  ::Bundler.with_clean_env do
101
118
  run_process!
102
119
  end
@@ -132,15 +149,12 @@ module PDK
132
149
  protected
133
150
 
134
151
  def run_process!
152
+ command_string = argv.join(' ')
153
+ PDK.logger.debug(_("Executing '%{command}'") % { command: command_string })
135
154
  begin
136
155
  @process.start
137
156
  rescue ChildProcess::LaunchError => e
138
- msg = if @process.respond_to?(:argv)
139
- _("Failed to execute '%{command}': %{message}") % { command: @process.argv.join(' '), message: e.message }
140
- else
141
- _('Failed to execute process: %{message}') % { message: e.message }
142
- end
143
- raise PDK::CLI::FatalError, msg
157
+ raise PDK::CLI::FatalError, _("Failed to execute '%{command}': %{message}") % { command: command_string, message: e.message }
144
158
  end
145
159
 
146
160
  if timeout
@@ -160,7 +174,6 @@ module PDK
160
174
  end
161
175
 
162
176
  def find_pdk_gem_path
163
- # /opt/puppetlabs/sdk/private/ruby/2.1.9/lib/ruby/gems/2.1.0
164
177
  package_gem_path = File.join(PDK::CLI::Exec.pdk_basedir, 'private', 'ruby', RUBY_VERSION, 'lib', 'ruby', 'gems', RbConfig::CONFIG['ruby_version'])
165
178
 
166
179
  if File.directory?(package_gem_path)
@@ -171,6 +184,30 @@ module PDK
171
184
  end
172
185
  end
173
186
  end
187
+
188
+ # This is a placeholder until we integrate ansicon into Windows packaging
189
+ # or come up with some other progress indicator for Windows.
190
+ class WindowsSpinner
191
+ def initialize(message, _opts = {})
192
+ @message = message
193
+ end
194
+
195
+ def auto_spin
196
+ $stderr.print @message << '...'
197
+ end
198
+
199
+ def success(message = '')
200
+ message ||= 'done.'
201
+
202
+ $stderr.print message << "\n"
203
+ end
204
+
205
+ def error(message = '')
206
+ message ||= 'FAILED'
207
+
208
+ $stderr.print message << "\n"
209
+ end
210
+ end
174
211
  end
175
212
  end
176
213
  end
@@ -1,4 +1,3 @@
1
-
2
1
  module PDK::CLI
3
2
  @new_class_cmd = @new_cmd.define_command do
4
3
  name 'class'
@@ -10,6 +9,8 @@ module PDK::CLI
10
9
  run do |opts, args, _cmd|
11
10
  require 'pdk/generators/puppet_class'
12
11
 
12
+ PDK::CLI::Util.ensure_in_module!
13
+
13
14
  class_name = args[0]
14
15
  module_dir = Dir.pwd
15
16
 
@@ -1,3 +1,5 @@
1
+ require 'pdk/cli/util/option_validator'
2
+ require 'pdk/report'
1
3
 
2
4
  module PDK::CLI
3
5
  @test_unit_cmd = @test_cmd.define_command do
@@ -7,32 +9,49 @@ module PDK::CLI
7
9
 
8
10
  flag nil, :list, _('list all available unit tests and their descriptions')
9
11
 
10
- option nil, :tests, _('a comma-separated list of tests to run'), argument: :required do |values|
11
- OptionValidator.list(values)
12
+ option nil, :tests, _('a comma-separated list of tests to run'), argument: :required, default: '' do |values|
13
+ PDK::CLI::Util::OptionValidator.comma_separated_list?(values)
12
14
  end
13
15
 
14
- option nil, :runner_options, _('options to pass through to the actual test-runner'), argument: :required
16
+ # TODO
17
+ # option nil, :runner_options, _("options to pass through to the actual test-runner"), argument: :required
15
18
 
16
19
  run do |opts, _args, _cmd|
17
20
  require 'pdk/tests/unit'
18
21
 
22
+ PDK::CLI::Util.ensure_in_module!
23
+
19
24
  report = nil
20
25
 
21
26
  if opts[:list]
22
- puts _('List of all available unit tests: (TODO)')
23
- end
24
-
25
- if opts[:tests]
26
- tests = opts.fetch(:tests)
27
+ examples = PDK::Test::Unit.list
28
+ if examples.empty?
29
+ puts _('No examples found.')
30
+ else
31
+ puts _('Examples:')
32
+ examples.each do |example|
33
+ puts _("%{id}\t%{description}" % { id: example[:id], description: example[:full_description] })
34
+ end
35
+ end
36
+ else
37
+ report = PDK::Report.new
38
+ report_formats = if opts[:format]
39
+ PDK::CLI::Util::OptionNormalizer.report_formats(opts[:format])
40
+ else
41
+ [{
42
+ method: PDK::Report.default_format,
43
+ target: PDK::Report.default_target,
44
+ }]
45
+ end
46
+
47
+ exit_code = PDK::Test::Unit.invoke(report, opts)
48
+
49
+ report_formats.each do |format|
50
+ report.send(format[:method], format[:target])
51
+ end
52
+
53
+ exit exit_code
27
54
  end
28
-
29
- # Note: Reporting may be delegated to the validation tool itself.
30
- if opts[:'report-file']
31
- format = opts.fetch(:'report-format', PDK::Report.default_format)
32
- report = Report.new(opts.fetch(:'report-file'), format)
33
- end
34
-
35
- PDK::Test::Unit.invoke(tests, report)
36
55
  end
37
56
  end
38
57
  end
@@ -0,0 +1,15 @@
1
+ module PDK
2
+ module CLI
3
+ module Util
4
+ # Ensures the calling code is being run from inside a module directory.
5
+ #
6
+ # @raise [PDK::CLI::FatalError] if the current directory or parents do
7
+ # not contain a `metadata.json` file.
8
+ def ensure_in_module!
9
+ message = _('This command must be run from inside a module (no metadata.json found)')
10
+ raise PDK::CLI::FatalError, message if PDK::Util.module_root.nil?
11
+ end
12
+ module_function :ensure_in_module!
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,52 @@
1
+ require 'tty-prompt'
2
+
3
+ module PDK
4
+ module CLI
5
+ module Util
6
+ class Interview < TTY::Prompt::AnswersCollector
7
+ def pastel
8
+ @pastel ||= Pastel.new
9
+ end
10
+
11
+ def add_questions(questions)
12
+ questions.each do |question|
13
+ add_question(question)
14
+ end
15
+ end
16
+
17
+ def add_question(options = {})
18
+ (@questions ||= {})[options[:name]] = options
19
+ end
20
+
21
+ def num_questions
22
+ @questions.count
23
+ end
24
+
25
+ def run
26
+ i = 1
27
+ num_questions = @questions.count
28
+ @questions.each do |question_name, question|
29
+ @name = question_name
30
+ puts pastel.bold(_('[Q %{current_number}/%{questions_total}]') % { current_number: i, questions_total: num_questions })
31
+ puts pastel.bold(question[:question])
32
+ puts question[:help]
33
+ ask(_('-->')) do |q|
34
+ q.required(question.fetch(:required, false))
35
+
36
+ if question.key?(:validate_pattern)
37
+ q.validate(question[:validate_pattern], question[:validate_message])
38
+ end
39
+
40
+ q.default(question[:default]) if question.key?(:default)
41
+ end
42
+ i += 1
43
+ puts ''
44
+ end
45
+ @answers
46
+ rescue TTY::Prompt::Reader::InputInterrupt
47
+ nil
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -42,7 +42,7 @@ module PDK
42
42
  target = $stderr
43
43
  end
44
44
 
45
- { method: "to_#{format}".to_sym, target: target }
45
+ { method: "write_#{format}".to_sym, target: target }
46
46
  end
47
47
  end
48
48
 
@@ -3,11 +3,18 @@ require 'pdk/util/bundler'
3
3
  module PDK::CLI
4
4
  @validate_cmd = @base_cmd.define_command do
5
5
  name 'validate'
6
- usage _('validate [options]')
6
+ usage _('validate [validators] [options] [targets]')
7
7
  summary _('Run static analysis tests.')
8
- description _('Run metadata, puppet, or ruby validation.')
8
+ description _(
9
+ "Run metadata, puppet, or ruby validation.\n\n" \
10
+ '[validators] is an optional comma separated list of validators to use. ' \
11
+ "If not specified, all validators will be used.\n\n" \
12
+ '[targets] is an optional space separated list of files or directories to be validated. ' \
13
+ 'If not specified, the validators will be run against all applicable files in the module.',
14
+ )
9
15
 
10
16
  flag nil, :list, _('list all available validators')
17
+ flag :a, 'auto-correct', _('automatically correct problems (where possible)')
11
18
 
12
19
  run do |opts, args, _cmd|
13
20
  validator_names = PDK::Validate.validators.map { |v| v.name }
@@ -19,6 +26,8 @@ module PDK::CLI
19
26
  exit 0
20
27
  end
21
28
 
29
+ PDK::CLI::Util.ensure_in_module!
30
+
22
31
  if args[0]
23
32
  # This may be a single validator, a list of validators, or a target.
24
33
  if Util::OptionValidator.comma_separated_list?(args[0])
@@ -60,6 +69,7 @@ module PDK::CLI
60
69
  end
61
70
 
62
71
  options = targets.empty? ? {} : { targets: targets }
72
+ options[:auto_correct] = true if opts.key?(:'auto-correct')
63
73
 
64
74
  exit_code = 0
65
75
 
@@ -1,13 +1,14 @@
1
1
  require 'etc'
2
2
  require 'pathname'
3
3
  require 'fileutils'
4
+ require 'tty-prompt'
4
5
 
5
6
  require 'pdk'
6
7
  require 'pdk/logger'
7
8
  require 'pdk/module/metadata'
8
9
  require 'pdk/module/templatedir'
9
10
  require 'pdk/cli/exec'
10
- require 'pdk/cli/input'
11
+ require 'pdk/cli/util/interview'
11
12
  require 'pdk/util'
12
13
  require 'pdk/util/version'
13
14
 
@@ -17,26 +18,13 @@ module PDK
17
18
  DEFAULT_TEMPLATE = 'https://github.com/puppetlabs/pdk-module-template'.freeze
18
19
 
19
20
  def self.invoke(opts = {})
20
- defaults = {
21
- 'name' => "#{Etc.getlogin}-#{opts[:name]}",
22
- 'version' => '0.1.0',
23
- 'dependencies' => [
24
- { 'name' => 'puppetlabs-stdlib', 'version_requirement' => '>= 4.13.1 < 5.0.0' },
25
- ],
26
- }
27
-
28
- defaults['license'] = opts[:license] if opts.key? :license
29
21
  target_dir = File.expand_path(opts[:target_dir])
30
22
 
31
23
  if File.exist?(target_dir)
32
24
  raise PDK::CLI::FatalError, _("The destination directory '%{dir}' already exists") % { dir: target_dir }
33
25
  end
34
26
 
35
- metadata = PDK::Module::Metadata.new(defaults)
36
-
37
- module_interview(metadata, opts) unless opts[:'skip-interview'] # @todo Build way to get info by answers file
38
-
39
- metadata.update!('pdk-version' => PDK::Util::Version.version_string)
27
+ metadata = prepare_metadata(opts)
40
28
 
41
29
  temp_target_dir = PDK::Util.make_tmpdir_name('pdk-module-target')
42
30
 
@@ -63,6 +51,31 @@ module PDK
63
51
  FileUtils.mv(temp_target_dir, target_dir)
64
52
  end
65
53
 
54
+ def self.prepare_metadata(opts)
55
+ username = Etc.getlogin.gsub(%r{[^0-9a-z]}i, '')
56
+ username = 'username' if username == ''
57
+ if Etc.getlogin != username
58
+ PDK.logger.warn(_('Your username is not a valid Forge username, proceeding with the username %{username}' % { username: username }))
59
+ end
60
+
61
+ defaults = {
62
+ 'name' => "#{username}-#{opts[:name]}",
63
+ 'version' => '0.1.0',
64
+ 'dependencies' => [
65
+ { 'name' => 'puppetlabs-stdlib', 'version_requirement' => '>= 4.13.1 < 5.0.0' },
66
+ ],
67
+ }
68
+ defaults['license'] = opts[:license] if opts.key? :license
69
+
70
+ metadata = PDK::Module::Metadata.new(defaults)
71
+
72
+ module_interview(metadata, opts) unless opts[:'skip-interview'] # @todo Build way to get info by answers file
73
+
74
+ metadata.update!('pdk-version' => PDK::Util::Version.version_string)
75
+
76
+ metadata
77
+ end
78
+
66
79
  def self.prepare_module_directory(target_dir)
67
80
  [
68
81
  File.join(target_dir, 'manifests'),
@@ -77,63 +90,98 @@ module PDK
77
90
  end
78
91
 
79
92
  def self.module_interview(metadata, opts = {})
80
- puts _(
81
- 'We need to create a metadata.json file for this module. Please answer the ' \
82
- 'following questions; if the question is not applicable to this module, feel free ' \
83
- 'to leave it blank.',
84
- )
85
-
86
- begin
87
- puts ''
88
- forge_user = PDK::CLI::Input.get(_('What is your Puppet Forge username?'), metadata.data['author'])
89
- metadata.update!('name' => "#{forge_user}-#{opts[:name]}")
90
- rescue StandardError => e
91
- PDK.logger.error(_("We're sorry, we could not parse your module name: %{message}") % { message: e.message })
92
- retry
93
- end
93
+ questions = [
94
+ {
95
+ name: 'name',
96
+ question: _('What is your Puppet Forge username?'),
97
+ help: _('This will be used when uploading your module to the Forge. You can opt out of this at any time.'),
98
+ required: true,
99
+ validate_pattern: %r{\A[a-z0-9]+\Z}i,
100
+ validate_message: _('Forge usernames can only contain lowercase letters and numbers'),
101
+ default: metadata.data['author'],
102
+ },
103
+ {
104
+ name: 'version',
105
+ question: _('What version is this module?'),
106
+ help: _('Puppet uses Semantic Versioning (semver.org) to version modules.'),
107
+ required: true,
108
+ validate_pattern: %r{\A[0-9]+\.[0-9]+\.[0-9]+},
109
+ validate_message: _('Semantic Version numbers must be in the form MAJOR.MINOR.PATCH'),
110
+ default: metadata.data['version'],
111
+ },
112
+ {
113
+ name: 'author',
114
+ question: _('Who wrote this module?'),
115
+ help: _('The person who gets credit for creating the module. '),
116
+ required: true,
117
+ default: metadata.data['author'],
118
+ },
119
+ {
120
+ name: 'license',
121
+ question: _('What license does this module code fall under?'),
122
+ help: _('This should be an identifier from https://spdk.org/licenses/. Common values are "Apache-2.0", "MIT", or "proprietary".'),
123
+ required: true,
124
+ default: metadata.data['license'],
125
+ },
126
+ {
127
+ name: 'summary',
128
+ question: _('How would you describe this module in a single sentence?'),
129
+ help: _('To help other Puppet users understand what the module does.'),
130
+ required: true,
131
+ default: metadata.data['summary'],
132
+ },
133
+ {
134
+ name: 'source',
135
+ question: _("Where is this modules's source code repository?"),
136
+ help: _('Usually a GitHub URL'),
137
+ required: true,
138
+ default: metadata.data['source'],
139
+ },
140
+ {
141
+ name: 'project_page',
142
+ question: _('Where can others go to learn more about this module?'),
143
+ help: _('A web site that offers full information about your module.'),
144
+ default: metadata.data['project_page'],
145
+ },
146
+ {
147
+ name: 'issues_url',
148
+ question: _('Where can others go to file issues about this module?'),
149
+ help: _('A web site with a public bug tracker for your module.'),
150
+ default: metadata.data['issues_url'],
151
+ },
152
+ ]
153
+
154
+ prompt = TTY::Prompt.new
155
+
156
+ interview = PDK::CLI::Util::Interview.new(prompt)
157
+
158
+ questions.reject! { |q| q[:name] == 'license' } if opts.key?(:license)
159
+
160
+ interview.add_questions(questions)
94
161
 
95
- begin
96
- puts "\n" + _('Puppet uses Semantic Versioning (semver.org) to version modules.')
97
- module_version = PDK::CLI::Input.get(_('What version is this module?'), metadata.data['version'])
98
- metadata.update!('version' => module_version)
99
- rescue StandardError => e
100
- PDK.logger.error(_("We're sorry, we could not parse that as a Semantic Version: %{message}") % { message: e.message })
101
- retry
102
- end
162
+ puts _(
163
+ "\nWe need to create a metadata.json file for this module, so we're going to ask you %{count} quick questions.\n" \
164
+ "If the question is not applicable to this module, just leave the answer blank.\n\n",
165
+ ) % { count: interview.num_questions }
103
166
 
104
- puts ''
105
- module_author = PDK::CLI::Input.get(_('Who wrote this module?'), metadata.data['author'])
106
- metadata.update!('author' => module_author)
167
+ answers = interview.run
107
168
 
108
- unless opts.key?(:license)
109
- puts ''
110
- module_license = PDK::CLI::Input.get(_('What license does this module code fall under?'), metadata.data['license'])
111
- metadata.update!('license' => module_license)
169
+ if answers.nil?
170
+ puts _('Interview cancelled, aborting...')
171
+ exit 0
112
172
  end
113
173
 
114
- puts ''
115
- module_summary = PDK::CLI::Input.get(_('How would you describe this module in a single sentence?'), metadata.data['summary'])
116
- metadata.update!('summary' => module_summary)
174
+ answers['name'] = "#{answers['name']}-#{opts[:name]}"
175
+ metadata.update!(answers)
117
176
 
118
- puts ''
119
- module_source = PDK::CLI::Input.get(_("Where is this module's source code repository?"), metadata.data['source'])
120
- metadata.update!('source' => module_source)
121
-
122
- puts ''
123
- module_page = PDK::CLI::Input.get(_('Where can others go to learn more about this module?'), metadata.data['project_page'])
124
- metadata.update!('project_page' => module_page)
125
-
126
- puts ''
127
- module_issues = PDK::CLI::Input.get(_('Where can others go to file issues about this module?'), metadata.data['issues_url'])
128
- metadata.update!('issues_url' => module_issues)
129
-
130
- puts
177
+ puts '-' * 40
178
+ puts _('SUMMARY')
131
179
  puts '-' * 40
132
180
  puts metadata.to_json
133
181
  puts '-' * 40
134
182
  puts
135
183
 
136
- unless PDK::CLI::Input.get(_('About to generate this module; continue?'), 'Y') =~ %r{^y(es)?$}i # rubocop:disable Style/GuardClause
184
+ unless prompt.yes?(_('About to generate this module; continue?')) # rubocop:disable Style/GuardClause
137
185
  puts _('Aborting...')
138
186
  exit 0
139
187
  end