pdk 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +11 -0
  4. data/lib/pdk/answer_file.rb +1 -1
  5. data/lib/pdk/cli.rb +16 -6
  6. data/lib/pdk/cli/bundle.rb +5 -3
  7. data/lib/pdk/cli/errors.rb +10 -1
  8. data/lib/pdk/cli/exec.rb +9 -4
  9. data/lib/pdk/cli/module.rb +14 -0
  10. data/lib/pdk/cli/module/generate.rb +40 -0
  11. data/lib/pdk/cli/new.rb +2 -1
  12. data/lib/pdk/cli/new/class.rb +1 -1
  13. data/lib/pdk/cli/new/defined_type.rb +27 -0
  14. data/lib/pdk/cli/new/module.rb +1 -11
  15. data/lib/pdk/cli/util.rb +3 -3
  16. data/lib/pdk/cli/util/command_redirector.rb +26 -0
  17. data/lib/pdk/cli/util/interview.rb +17 -6
  18. data/lib/pdk/cli/util/option_normalizer.rb +3 -3
  19. data/lib/pdk/cli/validate.rb +9 -9
  20. data/lib/pdk/generate.rb +1 -0
  21. data/lib/pdk/generators/defined_type.rb +49 -0
  22. data/lib/pdk/generators/module.rb +113 -23
  23. data/lib/pdk/generators/puppet_class.rb +2 -2
  24. data/lib/pdk/generators/puppet_object.rb +3 -3
  25. data/lib/pdk/module/metadata.rb +7 -7
  26. data/lib/pdk/module/templatedir.rb +3 -3
  27. data/lib/pdk/report/event.rb +43 -12
  28. data/lib/pdk/tests/unit.rb +51 -17
  29. data/lib/pdk/util.rb +3 -3
  30. data/lib/pdk/util/bundler.rb +5 -5
  31. data/lib/pdk/util/version.rb +5 -2
  32. data/lib/pdk/util/windows.rb +6 -0
  33. data/lib/pdk/validators/base_validator.rb +1 -1
  34. data/lib/pdk/validators/metadata/metadata_json_lint.rb +2 -2
  35. data/lib/pdk/validators/metadata/metadata_syntax.rb +2 -2
  36. data/lib/pdk/validators/puppet/puppet_lint.rb +1 -1
  37. data/lib/pdk/validators/puppet/puppet_syntax.rb +1 -1
  38. data/lib/pdk/validators/ruby/rubocop.rb +1 -1
  39. data/lib/pdk/version.rb +1 -1
  40. data/lib/puppet/util/windows/api_types.rb +9 -5
  41. data/locales/pdk.pot +314 -180
  42. metadata +16 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fcc06dd1bb15914599e1f9549ce2e32c8e405956
4
- data.tar.gz: e55eea6fef1c132bb4f8e768f831027c915e78b8
3
+ metadata.gz: daa54ac61ef8e82a47ab9d6b0cbd190b2261a8a9
4
+ data.tar.gz: f90e5b3f2c554d1da7594967e9b3a500f28f1869
5
5
  SHA512:
6
- metadata.gz: 967bf04aec5d1e9f9fc2a6d9c3ae1c71d571ccbe4d29558a6c4582f5656866e1bdd68b3824edc036bb2fc2766cff78fce79513433401746adbb4cbfe73e37822
7
- data.tar.gz: fad2d24ea55c88ebcbaee911c731e374d96d5f4e3d1d6c8e66229e5f256e5a7fb985534deffb8312698cdcf266bddc95788d58c5cd893d34d6fc3316394049bb
6
+ metadata.gz: b2d4b1f197c7ca9d8acd269aa4a1ad83760a6b3238cc6dcd2330bc91324687fe370aeccc6a5756bea99ff812f2f6603f7eac1541c21fd6a01660acddd0bb7d41
7
+ data.tar.gz: 81515d3bf458e1e432fe985c47cb1f481267886a0a525bb5209af81925e4868c7f27b5df35069bcb1b554d145f9d6f74a823b0ada33c8f2c1f431098319e4bff
@@ -3,6 +3,32 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
5
 
6
+ ## [v1.1.0](https://github.com/puppetlabs/pdk/tree/v1.1.0) (2017-09-13)
7
+
8
+ [Full Changelog](https://github.com/puppetlabs/pdk/compare/v1.0.1...v1.1.0)
9
+
10
+ **Implemented enhancements:**
11
+
12
+ - \(PDK-369\) Improve error context for pdk test unit failures [\#294](https://github.com/puppetlabs/pdk/pull/294) ([rodjek](https://github.com/rodjek))
13
+ - \(PDK-415\) Convert user-input related problems from FATAL to ERROR [\#293](https://github.com/puppetlabs/pdk/pull/293) ([rodjek](https://github.com/rodjek))
14
+ - \(PDK-465\) Improve output from spec\_prep/spec\_clean failures [\#290](https://github.com/puppetlabs/pdk/pull/290) ([rodjek](https://github.com/rodjek))
15
+ - \(PDK-465\) Add vendored git to PATH for package installs [\#287](https://github.com/puppetlabs/pdk/pull/287) ([rodjek](https://github.com/rodjek))
16
+ - \(PDK-370\) Adds a 'pdk module generate' redirect to 'pdk new module'. [\#286](https://github.com/puppetlabs/pdk/pull/286) ([bmjen](https://github.com/bmjen))
17
+ - \(PDK-459\) Improve error message when the generation target exists [\#285](https://github.com/puppetlabs/pdk/pull/285) ([DavidS](https://github.com/DavidS))
18
+ - \(PDK-461\) Update childprocess to current version [\#282](https://github.com/puppetlabs/pdk/pull/282) ([DavidS](https://github.com/DavidS))
19
+ - \(PDK-459\) Add defined type generator [\#280](https://github.com/puppetlabs/pdk/pull/280) ([rodjek](https://github.com/rodjek))
20
+ - \(MAINT\) Copy-edited all the user-visible messages [\#276](https://github.com/puppetlabs/pdk/pull/276) ([jbondpdx](https://github.com/jbondpdx))
21
+ - \(PDK-365\) Inform and prompt user following new module generate [\#270](https://github.com/puppetlabs/pdk/pull/270) ([bmjen](https://github.com/bmjen))
22
+ - \(maint\) Debug output GEM\_HOME and GEM\_PATH before executing module commands [\#268](https://github.com/puppetlabs/pdk/pull/268) ([james-stocks](https://github.com/james-stocks))
23
+ - \(SDK-336\) Add operating system question to the new module interview [\#262](https://github.com/puppetlabs/pdk/pull/262) ([rodjek](https://github.com/rodjek))
24
+
25
+ **Fixed bugs:**
26
+
27
+ - Remove EOL style cop from default configuration [\#267](https://github.com/puppetlabs/pdk/issues/267)
28
+ - \(PDK-450\) remove stdlib dependency [\#278](https://github.com/puppetlabs/pdk/pull/278) ([DavidS](https://github.com/DavidS))
29
+ - \(PDK-420\) Ensure Puppet and Puppet::Util modules are defined [\#277](https://github.com/puppetlabs/pdk/pull/277) ([rodjek](https://github.com/rodjek))
30
+ - \(PDK-430\) Do not cache template-url answer if using the default template [\#265](https://github.com/puppetlabs/pdk/pull/265) ([rodjek](https://github.com/rodjek))
31
+
6
32
  ## [v1.0.1](https://github.com/puppetlabs/pdk/tree/v1.0.1) (2017-08-17)
7
33
 
8
34
  [Full Changelog](https://github.com/puppetlabs/pdk/compare/v1.0.0...v1.0.1)
data/README.md CHANGED
@@ -56,6 +56,17 @@ pdk new class class_name
56
56
 
57
57
  PDK creates the new class manifest and a test file (as `class_name_spec.rb`) in your module's `/spec/classes` directory.
58
58
 
59
+ ### Generate a defined type
60
+
61
+ To generate a defined type in your module, use the `pdk new defined_type` command, specifying the name of your new defined type.
62
+
63
+ 1. From the command line, in your module's directory, run:
64
+ ```
65
+ pdk new defined_type defined_type_name
66
+ ```
67
+
68
+ PDK creates the new defined\_type manifest and a test file (as `defined_type_name_spec.rb`) in your module's `/spec/defines` directory.
69
+
59
70
 
60
71
  ### Validating a module
61
72
 
@@ -53,7 +53,7 @@ module PDK
53
53
  # @raise (see #save_to_disk)
54
54
  def update!(new_answers = {})
55
55
  unless new_answers.is_a?(Hash)
56
- raise PDK::CLI::FatalError, _('Answer file can only be updated with a Hash')
56
+ raise PDK::CLI::FatalError, _('Answer file can be updated only with a Hash')
57
57
  end
58
58
 
59
59
  answers.merge!(new_answers)
@@ -2,6 +2,7 @@ require 'cri'
2
2
 
3
3
  require 'pdk/cli/errors'
4
4
  require 'pdk/cli/util'
5
+ require 'pdk/cli/util/command_redirector'
5
6
  require 'pdk/cli/util/option_normalizer'
6
7
  require 'pdk/cli/util/option_validator'
7
8
  require 'pdk/cli/exec_group'
@@ -14,6 +15,10 @@ require 'pdk/util/version'
14
15
  module PDK::CLI
15
16
  def self.run(args)
16
17
  @base_cmd.run(args)
18
+ rescue PDK::CLI::ExitWithError => e
19
+ PDK.logger.error(e.message)
20
+
21
+ exit e.exit_code
17
22
  rescue PDK::CLI::FatalError => e
18
23
  PDK.logger.fatal(e.message) if e.message
19
24
 
@@ -33,7 +38,11 @@ module PDK::CLI
33
38
  end
34
39
 
35
40
  def self.template_url_option(dsl)
36
- dsl.option nil, 'template-url', _('Specifies the URL to the template to use when creating new modules, and other parts.'), argument: :required, default: PDK::Generate::Module.default_template_url
41
+ dsl.option nil, 'template-url', _('Specifies the URL to the template to use when creating new modules or classes.'), argument: :required, default: PDK::Generate::Module.default_template_url
42
+ end
43
+
44
+ def self.skip_interview_option(dsl)
45
+ dsl.option nil, 'skip-interview', _('When specified, skips interactive querying of metadata.')
37
46
  end
38
47
 
39
48
  @base_cmd = Cri::Command.define do
@@ -43,21 +52,21 @@ module PDK::CLI
43
52
  description _('The shortest path to better modules.')
44
53
  default_subcommand 'help'
45
54
 
46
- flag nil, :version, _('show version of pdk') do |_, _|
55
+ flag nil, :version, _('Show version of pdk.') do |_, _|
47
56
  puts PDK::Util::Version.version_string
48
57
  exit 0
49
58
  end
50
59
 
51
- flag :h, :help, _('show help for this command') do |_, c|
60
+ flag :h, :help, _('Show help for this command.') do |_, c|
52
61
  puts c.help
53
62
  exit 0
54
63
  end
55
64
 
56
65
  format_desc = _(
57
66
  "Specify desired output format. Valid formats are '%{available_formats}'. " \
58
- 'You may also specify a file to which the formatted output will be directed, ' \
67
+ 'You may also specify a file to which the formatted output is sent, ' \
59
68
  "for example: '--format=junit:report.xml'. This option may be specified " \
60
- 'multiple times as long as each option specifies a distinct target file.',
69
+ 'multiple times if each option specifies a distinct target file.',
61
70
  ) % { available_formats: PDK::Report.formats.join("', '") }
62
71
 
63
72
  option :f, :format, format_desc, argument: :required, multiple: true do |values|
@@ -68,7 +77,7 @@ module PDK::CLI
68
77
  PDK.logger.enable_debug_output
69
78
  end
70
79
 
71
- option nil, 'answer-file', _('Path to an answer file'), argument: :required, hidden: true do |value|
80
+ option nil, 'answer-file', _('Path to an answer file.'), argument: :required, hidden: true do |value|
72
81
  PDK.answer_file = value
73
82
  end
74
83
  end
@@ -77,6 +86,7 @@ module PDK::CLI
77
86
  require 'pdk/cli/new'
78
87
  require 'pdk/cli/test'
79
88
  require 'pdk/cli/validate'
89
+ require 'pdk/cli/module'
80
90
 
81
91
  @base_cmd.add_command Cri::Command.new_basic_help
82
92
  end
@@ -3,9 +3,11 @@ module PDK::CLI
3
3
  @bundle_cmd = @base_cmd.define_command do
4
4
  name 'bundle'
5
5
  usage _('bundle -- [bundler_options]')
6
- summary _('escape hatch to bundler')
7
- description _('[experimental] For advanced users, this allows to run arbitrary commands in the bundler environment that the pdk manages. ' \
8
- 'Careless use of this command can lead to errors later which can\'t be recovered by the pdk itself.')
6
+ summary _('(Experimental) Command pass-through to bundler')
7
+ description _('[experimental] For advanced users, pdk bundle runs arbitrary commands in the bundler environment that pdk manages.' \
8
+ 'Careless use of this command can lead to errors that pdk can\'t help recover from.')
9
+
10
+ be_hidden
9
11
 
10
12
  run do |_opts, args, _cmd|
11
13
  PDK::CLI::Util.ensure_in_module!
@@ -3,7 +3,16 @@ module PDK
3
3
  class FatalError < StandardError
4
4
  attr_reader :exit_code
5
5
 
6
- def initialize(msg = _('An unexpected error has occurred, try running the command again with --debug'), exit_code = 1)
6
+ def initialize(msg = _('An unexpected error has occurred. Try running the command again with --debug'), exit_code = 1)
7
+ @exit_code = exit_code
8
+ super(msg)
9
+ end
10
+ end
11
+
12
+ class ExitWithError < StandardError
13
+ attr_reader :exit_code
14
+
15
+ def initialize(msg, exit_code = 1)
7
16
  @exit_code = exit_code
8
17
  super(msg)
9
18
  end
@@ -53,15 +53,15 @@ module PDK
53
53
 
54
54
  def self.try_vendored_bin(vendored_bin_path, fallback)
55
55
  unless PDK::Util.package_install?
56
- PDK.logger.debug(_("PDK package installation not found, trying '%{fallback}' from the system PATH instead") % { fallback: fallback })
56
+ PDK.logger.debug(_("PDK package installation not found. Trying '%{fallback}' from the system PATH instead.") % { fallback: fallback })
57
57
  return fallback
58
58
  end
59
59
 
60
60
  if File.exist?(File.join(PDK::Util.pdk_package_basedir, vendored_bin_path))
61
- PDK.logger.debug(_("Using '%{vendored_bin_path}' from PDK package") % { vendored_bin_path: vendored_bin_path })
61
+ PDK.logger.debug(_("Using '%{vendored_bin_path}' from PDK package.") % { vendored_bin_path: vendored_bin_path })
62
62
  File.join(PDK::Util.pdk_package_basedir, vendored_bin_path)
63
63
  else
64
- PDK.logger.debug(_("Could not find '%{vendored_bin_path}' in PDK package, trying '%{fallback}' from the system PATH instead") % { fallback: fallback, vendored_bin_path: vendored_bin_path })
64
+ PDK.logger.debug(_("Could not find '%{vendored_bin_path}' in PDK package. Trying '%{fallback}' from the system PATH instead.") % { fallback: fallback, vendored_bin_path: vendored_bin_path })
65
65
  fallback
66
66
  end
67
67
  end
@@ -99,7 +99,7 @@ module PDK
99
99
 
100
100
  def context=(new_context)
101
101
  unless [:system, :module].include?(new_context)
102
- raise ArgumentError, _("Expected execution context to be :system or :module but got '%{context}'") % { context: new_context }
102
+ raise ArgumentError, _("Expected execution context to be :system or :module but got '%{context}'.") % { context: new_context }
103
103
  end
104
104
 
105
105
  @context = new_context
@@ -154,6 +154,7 @@ module PDK
154
154
  File.join(@process.environment['GEM_HOME'], 'bin'),
155
155
  File.join(@process.environment['GEM_PATH'], 'bin'),
156
156
  package_binpath,
157
+ PDK::Util.package_install? ? PDK::CLI::Exec.git_bindir : nil,
157
158
  ENV['PATH'],
158
159
  ].compact.join(File::PATH_SEPARATOR)
159
160
 
@@ -217,6 +218,10 @@ module PDK
217
218
  def run_process!
218
219
  command_string = argv.join(' ')
219
220
  PDK.logger.debug(_("Executing '%{command}'") % { command: command_string })
221
+ if context == :module
222
+ PDK.logger.debug(_("Command environment: GEM_HOME is '%{gem_home}' and GEM_PATH is '%{gem_path}'") % { gem_home: @process.environment['GEM_HOME'],
223
+ gem_path: @process.environment['GEM_PATH'] })
224
+ end
220
225
  start_time = Time.now
221
226
  begin
222
227
  @process.start
@@ -0,0 +1,14 @@
1
+ module PDK::CLI
2
+ @module_cmd = @base_cmd.define_command do
3
+ name 'module'
4
+ usage _('module [options]')
5
+ summary _('Perform administrative tasks on your module.')
6
+ description _('Perform tasks on the module project.')
7
+ default_subcommand 'help'
8
+ be_hidden
9
+ end
10
+
11
+ @module_cmd.add_command Cri::Command.new_basic_help
12
+ end
13
+
14
+ require 'pdk/cli/module/generate'
@@ -0,0 +1,40 @@
1
+ require 'tty-prompt'
2
+
3
+ module PDK::CLI
4
+ @module_generate_cmd = @module_cmd.define_command do
5
+ name 'generate'
6
+ usage _('generate [options] <module_name>')
7
+ summary _('This command is now \'pdk new module\'.')
8
+ be_hidden
9
+
10
+ PDK::CLI.template_url_option(self)
11
+ PDK::CLI.skip_interview_option(self)
12
+
13
+ run do |opts, args, _cmd|
14
+ require 'pdk/generators/module'
15
+
16
+ module_name = args[0]
17
+
18
+ if module_name.nil? || module_name.empty?
19
+ puts command.help
20
+ exit 1
21
+ end
22
+
23
+ PDK.logger.info(_('New modules are created using the ‘pdk new module’ command.'))
24
+ prompt = TTY::Prompt.new(help_color: :cyan)
25
+ redirect = PDK::CLI::Util::CommandRedirector.new(prompt)
26
+ redirect.target_command('pdk new module')
27
+ answer = redirect.run
28
+
29
+ if answer
30
+ opts[:name] = module_name
31
+ opts[:target_dir] = module_name
32
+
33
+ PDK.logger.info(_('Creating new module: %{modname}') % { modname: module_name })
34
+ PDK::Generate::Module.invoke(opts)
35
+ else
36
+ exit 1
37
+ end
38
+ end
39
+ end
40
+ end
@@ -4,7 +4,7 @@ module PDK::CLI
4
4
  name 'new'
5
5
  usage _('new <type> [options]')
6
6
  summary _('create a new module, etc.')
7
- description _('Creates a new instance of <type> using the options relevant to that type of thing')
7
+ description _('Creates a new instance of <type> using relevant options.')
8
8
  default_subcommand 'help'
9
9
  end
10
10
 
@@ -12,4 +12,5 @@ module PDK::CLI
12
12
  end
13
13
 
14
14
  require 'pdk/cli/new/class'
15
+ require 'pdk/cli/new/defined_type'
15
16
  require 'pdk/cli/new/module'
@@ -20,7 +20,7 @@ module PDK::CLI
20
20
  end
21
21
 
22
22
  unless Util::OptionValidator.valid_class_name?(class_name)
23
- raise PDK::CLI::FatalError, _("'%{name}' is not a valid class name") % { name: class_name }
23
+ raise PDK::CLI::ExitWithError, _("'%{name}' is not a valid class name") % { name: class_name }
24
24
  end
25
25
 
26
26
  PDK::Generate::PuppetClass.new(module_dir, class_name, opts).run
@@ -0,0 +1,27 @@
1
+ module PDK::CLI
2
+ @new_define_cmd = @new_cmd.define_command do
3
+ name 'defined_type'
4
+ usage _('defined_type [options] <name>')
5
+ summary _('Create a new defined type named <name> using given options')
6
+
7
+ PDK::CLI.template_url_option(self)
8
+
9
+ run do |opts, args, _cmd|
10
+ PDK::CLI::Util.ensure_in_module!
11
+
12
+ defined_type_name = args[0]
13
+ module_dir = Dir.pwd
14
+
15
+ if defined_type_name.nil? || defined_type_name.empty?
16
+ puts command.help
17
+ exit 1
18
+ end
19
+
20
+ unless Util::OptionValidator.valid_defined_type_name?(defined_type_name)
21
+ raise PDK::CLI::ExitWithError, _("'%{name}' is not a valid defined type name") % { name: defined_type_name }
22
+ end
23
+
24
+ PDK::Generate::DefinedType.new(module_dir, defined_type_name, opts).run
25
+ end
26
+ end
27
+ end
@@ -1,4 +1,3 @@
1
-
2
1
  module PDK::CLI
3
2
  @new_module_cmd = @new_cmd.define_command do
4
3
  name 'module'
@@ -6,12 +5,11 @@ module PDK::CLI
6
5
  summary _('Create a new module named <module_name> using given options')
7
6
 
8
7
  PDK::CLI.template_url_option(self)
8
+ PDK::CLI.skip_interview_option(self)
9
9
 
10
10
  option nil, 'license', _('Specifies the license this module is written under. ' \
11
11
  "This should be a identifier from https://spdx.org/licenses/. Common values are 'Apache-2.0', 'MIT', or 'proprietary'."), argument: :required
12
12
 
13
- flag nil, 'skip-interview', _('When specified, skips interactive querying of metadata.')
14
-
15
13
  run do |opts, args, _cmd|
16
14
  require 'pdk/generators/module'
17
15
 
@@ -23,14 +21,6 @@ module PDK::CLI
23
21
  exit 1
24
22
  end
25
23
 
26
- unless Util::OptionValidator.valid_module_name?(module_name)
27
- error_msg = _(
28
- "'%{module_name}' is not a valid module name.\n" \
29
- 'Module names must begin with a lowercase letter and can only include lowercase letters, digits, and underscores.',
30
- ) % { module_name: module_name }
31
- raise PDK::CLI::FatalError, error_msg
32
- end
33
-
34
24
  opts[:name] = module_name
35
25
  opts[:target_dir] = target_dir.nil? ? module_name : target_dir
36
26
 
@@ -3,11 +3,11 @@ module PDK
3
3
  module Util
4
4
  # Ensures the calling code is being run from inside a module directory.
5
5
  #
6
- # @raise [PDK::CLI::FatalError] if the current directory or parents do
6
+ # @raise [PDK::CLI::ExitWithError] if the current directory or parents do
7
7
  # not contain a `metadata.json` file.
8
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?
9
+ message = _('This command must be run from inside a valid module (no metadata.json found).')
10
+ raise PDK::CLI::ExitWithError, message if PDK::Util.module_root.nil?
11
11
  end
12
12
  module_function :ensure_in_module!
13
13
 
@@ -0,0 +1,26 @@
1
+ require 'tty-prompt'
2
+
3
+ module PDK
4
+ module CLI
5
+ module Util
6
+ class CommandRedirector < TTY::Prompt::AnswersCollector
7
+ attr_accessor :command
8
+
9
+ def pastel
10
+ @pastel ||= Pastel.new
11
+ end
12
+
13
+ def target_command(cmd)
14
+ @command = cmd
15
+ end
16
+
17
+ def run
18
+ @prompt.puts _('Did you mean \'%{command}\'?') % { command: pastel.bold(@command) }
19
+ @prompt.yes?('-->')
20
+ rescue TTY::Prompt::Reader::InputInterrupt
21
+ nil
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -29,15 +29,26 @@ module PDK
29
29
  @name = question_name
30
30
  @prompt.print pastel.bold(_('[Q %{current_number}/%{questions_total}]') % { current_number: i, questions_total: num_questions }) + ' '
31
31
  @prompt.puts pastel.bold(question[:question])
32
- @prompt.puts question[:help]
33
- ask(_('-->')) do |q|
34
- q.required(question.fetch(:required, false))
32
+ @prompt.puts question[:help] if question.key?(:help)
33
+ if question.key?(:choices)
34
+ multi_select(_('-->'), per_page: question[:choices].count) do |q|
35
+ q.enum ')'
36
+ q.default(*question[:default]) if question.key?(:default)
35
37
 
36
- if question.key?(:validate_pattern)
37
- q.validate(question[:validate_pattern], question[:validate_message])
38
+ question[:choices].each do |text, metadata|
39
+ q.choice text, metadata
40
+ end
38
41
  end
42
+ else
43
+ ask(_('-->')) do |q|
44
+ q.required(question.fetch(:required, false))
39
45
 
40
- q.default(question[:default]) if question.key?(:default)
46
+ if question.key?(:validate_pattern)
47
+ q.validate(question[:validate_pattern], question[:validate_message])
48
+ end
49
+
50
+ q.default(question[:default]) if question.key?(:default)
51
+ end
41
52
  end
42
53
  i += 1
43
54
  @prompt.puts ''