pdk-akerl 1.8.0.1

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 (81) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +826 -0
  3. data/LICENSE +201 -0
  4. data/README.md +133 -0
  5. data/exe/pdk +10 -0
  6. data/lib/pdk.rb +10 -0
  7. data/lib/pdk/answer_file.rb +121 -0
  8. data/lib/pdk/cli.rb +113 -0
  9. data/lib/pdk/cli/build.rb +76 -0
  10. data/lib/pdk/cli/bundle.rb +42 -0
  11. data/lib/pdk/cli/convert.rb +41 -0
  12. data/lib/pdk/cli/errors.rb +23 -0
  13. data/lib/pdk/cli/exec.rb +246 -0
  14. data/lib/pdk/cli/exec_group.rb +67 -0
  15. data/lib/pdk/cli/module.rb +14 -0
  16. data/lib/pdk/cli/module/build.rb +14 -0
  17. data/lib/pdk/cli/module/generate.rb +45 -0
  18. data/lib/pdk/cli/new.rb +17 -0
  19. data/lib/pdk/cli/new/class.rb +32 -0
  20. data/lib/pdk/cli/new/defined_type.rb +30 -0
  21. data/lib/pdk/cli/new/module.rb +41 -0
  22. data/lib/pdk/cli/new/provider.rb +27 -0
  23. data/lib/pdk/cli/new/task.rb +31 -0
  24. data/lib/pdk/cli/test.rb +12 -0
  25. data/lib/pdk/cli/test/unit.rb +88 -0
  26. data/lib/pdk/cli/update.rb +32 -0
  27. data/lib/pdk/cli/util.rb +193 -0
  28. data/lib/pdk/cli/util/command_redirector.rb +26 -0
  29. data/lib/pdk/cli/util/interview.rb +63 -0
  30. data/lib/pdk/cli/util/option_normalizer.rb +53 -0
  31. data/lib/pdk/cli/util/option_validator.rb +56 -0
  32. data/lib/pdk/cli/validate.rb +124 -0
  33. data/lib/pdk/generate.rb +11 -0
  34. data/lib/pdk/generate/defined_type.rb +49 -0
  35. data/lib/pdk/generate/module.rb +318 -0
  36. data/lib/pdk/generate/provider.rb +82 -0
  37. data/lib/pdk/generate/puppet_class.rb +48 -0
  38. data/lib/pdk/generate/puppet_object.rb +288 -0
  39. data/lib/pdk/generate/task.rb +86 -0
  40. data/lib/pdk/i18n.rb +4 -0
  41. data/lib/pdk/logger.rb +28 -0
  42. data/lib/pdk/module.rb +21 -0
  43. data/lib/pdk/module/build.rb +214 -0
  44. data/lib/pdk/module/convert.rb +209 -0
  45. data/lib/pdk/module/metadata.rb +193 -0
  46. data/lib/pdk/module/templatedir.rb +313 -0
  47. data/lib/pdk/module/update.rb +111 -0
  48. data/lib/pdk/module/update_manager.rb +210 -0
  49. data/lib/pdk/report.rb +112 -0
  50. data/lib/pdk/report/event.rb +357 -0
  51. data/lib/pdk/template_file.rb +89 -0
  52. data/lib/pdk/tests/unit.rb +213 -0
  53. data/lib/pdk/util.rb +271 -0
  54. data/lib/pdk/util/bundler.rb +253 -0
  55. data/lib/pdk/util/filesystem.rb +12 -0
  56. data/lib/pdk/util/git.rb +74 -0
  57. data/lib/pdk/util/puppet_version.rb +242 -0
  58. data/lib/pdk/util/ruby_version.rb +147 -0
  59. data/lib/pdk/util/vendored_file.rb +88 -0
  60. data/lib/pdk/util/version.rb +42 -0
  61. data/lib/pdk/util/windows.rb +13 -0
  62. data/lib/pdk/util/windows/api_types.rb +57 -0
  63. data/lib/pdk/util/windows/file.rb +36 -0
  64. data/lib/pdk/util/windows/string.rb +16 -0
  65. data/lib/pdk/validate.rb +14 -0
  66. data/lib/pdk/validate/base_validator.rb +209 -0
  67. data/lib/pdk/validate/metadata/metadata_json_lint.rb +86 -0
  68. data/lib/pdk/validate/metadata/metadata_syntax.rb +109 -0
  69. data/lib/pdk/validate/metadata_validator.rb +30 -0
  70. data/lib/pdk/validate/puppet/puppet_lint.rb +67 -0
  71. data/lib/pdk/validate/puppet/puppet_syntax.rb +112 -0
  72. data/lib/pdk/validate/puppet_validator.rb +30 -0
  73. data/lib/pdk/validate/ruby/rubocop.rb +77 -0
  74. data/lib/pdk/validate/ruby_validator.rb +29 -0
  75. data/lib/pdk/validate/tasks/metadata_lint.rb +126 -0
  76. data/lib/pdk/validate/tasks/name.rb +88 -0
  77. data/lib/pdk/validate/tasks_validator.rb +33 -0
  78. data/lib/pdk/version.rb +4 -0
  79. data/locales/config.yaml +21 -0
  80. data/locales/pdk.pot +1283 -0
  81. metadata +304 -0
@@ -0,0 +1,193 @@
1
+ module PDK
2
+ module CLI
3
+ module Util
4
+ # Ensures the calling code is being run from inside a module directory.
5
+ #
6
+ # @param opts [Hash] options to change the behavior of the check logic.
7
+ # @option opts [Boolean] :check_module_layout Set to true to check for
8
+ # stardard module folder layout if the module does not contain
9
+ # a metadata.json file.
10
+ #
11
+ # @raise [PDK::CLI::ExitWithError] if the current directory does not
12
+ # contain a Puppet module.
13
+ def ensure_in_module!(opts = {})
14
+ return unless PDK::Util.module_root.nil?
15
+ return if opts[:check_module_layout] && PDK::Util.in_module_root?
16
+
17
+ message = opts.fetch(:message, _('This command must be run from inside a valid module (no metadata.json found).'))
18
+ raise PDK::CLI::ExitWithError.new(message, opts)
19
+ end
20
+ module_function :ensure_in_module!
21
+
22
+ def spinner_opts_for_platform
23
+ windows_opts = {
24
+ success_mark: '*',
25
+ error_mark: 'X',
26
+ }
27
+
28
+ return windows_opts if Gem.win_platform?
29
+ {}
30
+ end
31
+ module_function :spinner_opts_for_platform
32
+
33
+ def prompt_for_yes(question_text, opts = {})
34
+ prompt = opts[:prompt] || TTY::Prompt.new(help_color: :cyan)
35
+ validator = proc { |value| [true, false].include?(value) || value =~ %r{\A(?:yes|y|no|n)\Z}i }
36
+ response = nil
37
+
38
+ begin
39
+ response = prompt.yes?(question_text) do |q|
40
+ q.default opts[:default] unless opts[:default].nil?
41
+ q.validate(validator, _('Answer "Y" to continue or "n" to cancel.'))
42
+ end
43
+ rescue TTY::Prompt::Reader::InputInterrupt
44
+ PDK.logger.info opts[:cancel_message] if opts[:cancel_message]
45
+ end
46
+
47
+ response
48
+ end
49
+ module_function :prompt_for_yes
50
+
51
+ def interactive?
52
+ return false if PDK.logger.debug?
53
+ return !ENV['PDK_FRONTEND'].casecmp('noninteractive').zero? if ENV['PDK_FRONTEND']
54
+ return false unless $stderr.isatty
55
+
56
+ true
57
+ end
58
+ module_function :interactive?
59
+
60
+ def module_version_check
61
+ module_pdk_ver = PDK::Util.module_pdk_version
62
+
63
+ # This means the module does not have a pdk-version tag in the metadata.json
64
+ # and will require a pdk convert.
65
+ raise PDK::CLI::ExitWithError, _('This module is not PDK compatible. Run `pdk convert` to make it compatible with your version of PDK.') if module_pdk_ver.nil?
66
+
67
+ # This checks that the version of pdk in the module's metadata is older
68
+ # than 1.3.1, which means the module will need to run pdk convert to the
69
+ # new templates.
70
+ if Gem::Version.new(module_pdk_ver) < Gem::Version.new('1.3.1')
71
+ PDK.logger.warn _('This module template is out of date. Run `pdk convert` to make it compatible with your version of PDK.')
72
+ # This checks if the version of the installed PDK is older than the
73
+ # version in the module's metadata, and advises the user to upgrade to
74
+ # their install of PDK.
75
+ elsif Gem::Version.new(PDK::VERSION) < Gem::Version.new(module_pdk_ver)
76
+ PDK.logger.warn _('This module is compatible with a newer version of PDK. Upgrade your version of PDK to ensure compatibility.')
77
+ # This checks if the version listed in the module's metadata is older
78
+ # than the installed PDK, and advises the user to run pdk update.
79
+ elsif Gem::Version.new(PDK::VERSION) > Gem::Version.new(module_pdk_ver)
80
+ PDK.logger.warn _('This module is compatible with an older version of PDK. Run `pdk update` to update it to your version of PDK.')
81
+ end
82
+ end
83
+ module_function :module_version_check
84
+
85
+ def puppet_from_opts_or_env(opts)
86
+ use_puppet_dev = (opts || {})[:'puppet-dev'] || ENV['PDK_PUPPET_DEV']
87
+ desired_puppet_version = (opts || {})[:'puppet-version'] || ENV['PDK_PUPPET_VERSION']
88
+ desired_pe_version = (opts || {})[:'pe-version'] || ENV['PDK_PE_VERSION']
89
+
90
+ begin
91
+ puppet_env =
92
+ if use_puppet_dev
93
+ PDK::Util::PuppetVersion.puppet_dev_env
94
+ elsif desired_puppet_version
95
+ PDK::Util::PuppetVersion.find_gem_for(desired_puppet_version)
96
+ elsif desired_pe_version
97
+ PDK::Util::PuppetVersion.from_pe_version(desired_pe_version)
98
+ else
99
+ PDK::Util::PuppetVersion.from_module_metadata || PDK::Util::PuppetVersion.latest_available
100
+ end
101
+ rescue ArgumentError => e
102
+ raise PDK::CLI::ExitWithError, e.message
103
+ end
104
+
105
+ # Notify user of what Ruby version will be used.
106
+ PDK.logger.info(_('Using Ruby %{version}') % {
107
+ version: puppet_env[:ruby_version],
108
+ })
109
+
110
+ gemset = { puppet: puppet_env[:gem_version].to_s }
111
+
112
+ # Notify user of what gems are being activated.
113
+ gemset.each do |gem, version|
114
+ next if version.nil?
115
+
116
+ PDK.logger.info(_('Using %{gem} %{version}') % {
117
+ gem: gem.to_s.capitalize,
118
+ version: version,
119
+ })
120
+ end
121
+
122
+ {
123
+ gemset: gemset,
124
+ ruby_version: puppet_env[:ruby_version],
125
+ }
126
+ end
127
+ module_function :puppet_from_opts_or_env
128
+
129
+ def validate_puppet_version_opts(opts)
130
+ puppet_ver_specs = []
131
+ puppet_ver_specs << '--puppet-version option' if opts[:'puppet-version']
132
+ puppet_ver_specs << 'PDK_PUPPET_VERSION environment variable' if ENV['PDK_PUPPET_VERSION'] && !ENV['PDK_PUPPET_VERSION'].empty?
133
+
134
+ pe_ver_specs = []
135
+ pe_ver_specs << '--pe-version option' if opts[:'pe-version']
136
+ pe_ver_specs << 'PDK_PE_VERSION environment variable' if ENV['PDK_PE_VERSION'] && !ENV['PDK_PE_VERSION'].empty?
137
+
138
+ puppet_dev_specs = []
139
+ puppet_dev_specs << '--puppet-dev flag' if opts[:'puppet-dev']
140
+ puppet_dev_specs << 'PDK_PUPPET_DEV environment variable' if ENV['PDK_PUPPET_DEV'] && !ENV['PDK_PUPPET_DEV'].empty?
141
+
142
+ puppet_dev_specs.each do |pup_dev_spec|
143
+ [puppet_ver_specs, pe_ver_specs].each do |offending|
144
+ next if offending.empty?
145
+
146
+ raise PDK::CLI::ExitWithError, _('You cannot specify a %{first} and %{second} at the same time') % {
147
+ first: pup_dev_spec,
148
+ second: offending.first,
149
+ }
150
+ end
151
+ end
152
+
153
+ puppet_ver_specs.each do |pup_ver_spec|
154
+ next if pe_ver_specs.empty?
155
+
156
+ offending = [pup_ver_spec, pe_ver_specs[0]].sort
157
+
158
+ raise PDK::CLI::ExitWithError, _('You cannot specify a %{first} and %{second} at the same time.') % {
159
+ first: offending[0],
160
+ second: offending[1],
161
+ }
162
+ end
163
+
164
+ if puppet_dev_specs.size == 2
165
+ warning_str = 'Puppet dev flag from command line: "--puppet-dev" '
166
+ warning_str += 'overrides value from environment: "PDK_PUPPET_DEV=true". You should not specify both.'
167
+
168
+ PDK.logger.warn(_(warning_str) % {
169
+ pup_ver_opt: opts[:'puppet-dev'],
170
+ pup_ver_env: ENV['PDK_PUPPET_DEV'],
171
+ })
172
+ elsif puppet_ver_specs.size == 2
173
+ warning_str = 'Puppet version option from command line: "--puppet-version=%{pup_ver_opt}" '
174
+ warning_str += 'overrides value from environment: "PDK_PUPPET_VERSION=%{pup_ver_env}". You should not specify both.'
175
+
176
+ PDK.logger.warn(_(warning_str) % {
177
+ pup_ver_opt: opts[:'puppet-version'],
178
+ pup_ver_env: ENV['PDK_PUPPET_VERSION'],
179
+ })
180
+ elsif pe_ver_specs.size == 2
181
+ warning_str = 'Puppet Enterprise version option from command line: "--pe-version=%{pe_ver_opt}" '
182
+ warning_str += 'overrides value from environment: "PDK_PE_VERSION=%{pe_ver_env}". You should not specify both.'
183
+
184
+ PDK.logger.warn(_(warning_str) % {
185
+ pup_ver_opt: opts[:'pe-version'],
186
+ pup_ver_env: ENV['PDK_PE_VERSION'],
187
+ })
188
+ end
189
+ end
190
+ module_function :validate_puppet_version_opts
191
+ end
192
+ end
193
+ end
@@ -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
@@ -0,0 +1,63 @@
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
+ @prompt.print pastel.bold(_('[Q %{current_number}/%{questions_total}]') % { current_number: i, questions_total: num_questions }) + ' '
31
+ @prompt.puts pastel.bold(question[:question])
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)
37
+
38
+ question[:choices].each do |text, metadata|
39
+ q.choice text, metadata
40
+ end
41
+ end
42
+ else
43
+ ask(_('-->')) do |q|
44
+ q.required(question.fetch(:required, false))
45
+
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
52
+ end
53
+ i += 1
54
+ @prompt.puts ''
55
+ end
56
+ @answers
57
+ rescue TTY::Prompt::Reader::InputInterrupt
58
+ nil
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,53 @@
1
+ module PDK
2
+ module CLI
3
+ module Util
4
+ class OptionNormalizer
5
+ def self.comma_separated_list_to_array(list, _options = {})
6
+ raise _('Error: expected comma separated list') unless OptionValidator.comma_separated_list?(list)
7
+ list.split(',').compact
8
+ end
9
+
10
+ # Parse one or more format:target pairs into report format
11
+ # specifications.
12
+ #
13
+ # Each specification is a Hash with two values:
14
+ # :method => The name of the method to call on the PDK::Report object
15
+ # to render the report.
16
+ # :target => The target to write the report to. This can be either an
17
+ # IO object that implements #write, or a String filename
18
+ # that will be opened for writing.
19
+ #
20
+ # If the target given is "stdout" or "stderr", this will convert those
21
+ # strings into the appropriate IO object.
22
+ #
23
+ # @return [Array<Hash{Symbol=>Object}>] An array of one or more report
24
+ # format specifications
25
+ def self.report_formats(formats)
26
+ formats.map do |f|
27
+ format, target = f.split(':', 2)
28
+
29
+ begin
30
+ OptionValidator.enum(format, PDK::Report.formats)
31
+ rescue ArgumentError
32
+ raise PDK::CLI::ExitWithError, _("'%{name}' is not a valid report format (%{valid})") % {
33
+ name: format,
34
+ valid: PDK::Report.formats.join(', '),
35
+ }
36
+ end
37
+
38
+ case target
39
+ when 'stdout'
40
+ target = $stdout
41
+ when 'stderr'
42
+ target = $stderr
43
+ when nil
44
+ target = PDK::Report.default_target
45
+ end
46
+
47
+ { method: "write_#{format}".to_sym, target: target }
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,56 @@
1
+ module PDK
2
+ module CLI
3
+ module Util
4
+ class OptionValidator
5
+ def self.comma_separated_list?(list, _options = {})
6
+ (list =~ %r{^[\w\-]+(?:,[\w\-]+)+$}) ? true : false
7
+ end
8
+
9
+ def self.enum(val, valid_entries, _options = {})
10
+ vals = val.is_a?(Array) ? val : [val]
11
+ invalid_entries = vals.reject { |e| valid_entries.include?(e) }
12
+
13
+ unless invalid_entries.empty?
14
+ raise ArgumentError, _('Error: the following values are invalid: %{invalid_entries}') % { invalid_entries: invalid_entries }
15
+ end
16
+
17
+ val
18
+ end
19
+
20
+ # Validate the module name against the regular expression in the
21
+ # documentation: https://docs.puppet.com/puppet/4.10/modules_fundamentals.html#allowed-module-names
22
+ def self.valid_module_name?(string)
23
+ !(string =~ %r{\A[a-z][a-z0-9_]*\Z}).nil?
24
+ end
25
+ singleton_class.send(:alias_method, :valid_task_name?, :valid_module_name?)
26
+
27
+ # https://puppet.com/docs/puppet/5.3/custom_types.html#creating-a-type only says the name has to be a ruby symbol.
28
+ # Let's assume that only strings similar to module names can actually be resolved by the puppet language.
29
+ singleton_class.send(:alias_method, :valid_provider_name?, :valid_module_name?)
30
+
31
+ # Validate a Puppet namespace against the regular expression in the
32
+ # documentation: https://docs.puppet.com/puppet/4.10/lang_reserved.html#classes-and-defined-resource-types
33
+ def self.valid_namespace?(string)
34
+ return false if (string || '').split('::').last == 'init'
35
+
36
+ !(string =~ %r{\A([a-z][a-z0-9_]*)(::[a-z][a-z0-9_]*)*\Z}).nil?
37
+ end
38
+
39
+ singleton_class.send(:alias_method, :valid_class_name?, :valid_namespace?)
40
+ singleton_class.send(:alias_method, :valid_defined_type_name?, :valid_namespace?)
41
+
42
+ # Validate that a class/defined type parameter matches the regular
43
+ # expression in the documentation: https://docs.puppet.com/puppet/4.10/lang_reserved.html#parameters
44
+ # The parameter should also not be a reserved word or overload
45
+ # a metaparameter.
46
+ def self.valid_param_name?(string)
47
+ reserved_words = %w[trusted facts server_facts title name].freeze
48
+ metaparams = %w[alias audit before loglevel noop notify require schedule stage subscribe tag].freeze
49
+ return false if reserved_words.include?(string) || metaparams.include?(string)
50
+
51
+ !(string =~ %r{\A[a-z][a-zA-Z0-9_]*\Z}).nil?
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,124 @@
1
+ require 'pdk/util/bundler'
2
+
3
+ module PDK::CLI
4
+ @validate_cmd = @base_cmd.define_command do
5
+ name 'validate'
6
+ usage _('validate [validators] [options] [targets]')
7
+ summary _('Run static analysis tests.')
8
+ description _(
9
+ "Run metadata, Puppet, Ruby, or Tasks validation.\n\n" \
10
+ '[validators] is an optional comma-separated list of validators to use. ' \
11
+ 'If not specified, all validators are used. ' \
12
+ "Note that when using PowerShell, the list of validators must be enclosed in single quotes.\n\n" \
13
+ '[targets] is an optional space-separated list of files or directories to be validated. ' \
14
+ 'If not specified, validators are run against all applicable files in the module.',
15
+ )
16
+
17
+ PDK::CLI.puppet_version_options(self)
18
+ PDK::CLI.puppet_dev_option(self)
19
+ flag nil, :list, _('List all available validators.')
20
+ flag :a, 'auto-correct', _('Automatically correct problems where possible.')
21
+ flag nil, :parallel, _('Run validations in parallel.')
22
+
23
+ run do |opts, args, _cmd|
24
+ if args == ['help']
25
+ PDK::CLI.run(['validate', '--help'])
26
+ exit 0
27
+ end
28
+
29
+ validator_names = PDK::Validate.validators.map { |v| v.name }
30
+ validators = PDK::Validate.validators
31
+ targets = []
32
+
33
+ if opts[:list]
34
+ PDK.logger.info(_('Available validators: %{validator_names}') % { validator_names: validator_names.join(', ') })
35
+ exit 0
36
+ end
37
+
38
+ PDK::CLI::Util.validate_puppet_version_opts(opts)
39
+
40
+ PDK::CLI::Util.ensure_in_module!(
41
+ message: _('Code validation can only be run from inside a valid module directory'),
42
+ log_level: :info,
43
+ )
44
+
45
+ PDK::CLI::Util.module_version_check
46
+
47
+ if args[0]
48
+ # This may be a single validator, a list of validators, or a target.
49
+ if Util::OptionValidator.comma_separated_list?(args[0])
50
+ # This is a comma separated list. Treat each item as a validator.
51
+
52
+ vals = Util::OptionNormalizer.comma_separated_list_to_array(args[0])
53
+ validators = PDK::Validate.validators.select { |v| vals.include?(v.name) }
54
+
55
+ invalid = vals.reject { |v| validator_names.include?(v) }
56
+ invalid.each do |v|
57
+ PDK.logger.warn(_("Unknown validator '%{v}'. Available validators: %{validators}.") % { v: v, validators: validator_names.join(', ') })
58
+ end
59
+ else
60
+ # This is a single item. Check if it's a known validator, or otherwise treat it as a target.
61
+ val = PDK::Validate.validators.find { |v| args[0] == v.name }
62
+ if val
63
+ validators = [val]
64
+ else
65
+ targets = [args[0]]
66
+ # We now know that no validators were passed, so let the user know we're using all of them by default.
67
+ PDK.logger.info(_('Running all available validators...'))
68
+ end
69
+ end
70
+ else
71
+ PDK.logger.info(_('Running all available validators...'))
72
+ end
73
+
74
+ # Subsequent arguments are targets.
75
+ targets.concat(args[1..-1]) if args.length > 1
76
+
77
+ report = PDK::Report.new
78
+ report_formats = if opts[:format]
79
+ PDK::CLI::Util::OptionNormalizer.report_formats(opts[:format])
80
+ else
81
+ [{
82
+ method: PDK::Report.default_format,
83
+ target: PDK::Report.default_target,
84
+ }]
85
+ end
86
+
87
+ options = targets.empty? ? {} : { targets: targets }
88
+ options[:auto_correct] = true if opts.key?(:'auto-correct')
89
+
90
+ # Ensure that the bundled gems are up to date and correct Ruby is activated before running any validations.
91
+ puppet_env = PDK::CLI::Util.puppet_from_opts_or_env(opts)
92
+ PDK::Util::PuppetVersion.fetch_puppet_dev if opts.key?(:'puppet-dev')
93
+ PDK::Util::RubyVersion.use(puppet_env[:ruby_version])
94
+
95
+ options.merge!(puppet_env[:gemset])
96
+
97
+ PDK::Util::Bundler.ensure_bundle!(puppet_env[:gemset])
98
+
99
+ exit_code = 0
100
+ if opts[:parallel]
101
+ exec_group = PDK::CLI::ExecGroup.new(_('Validating module using %{num_of_threads} threads' % { num_of_threads: validators.count }), opts)
102
+
103
+ validators.each do |validator|
104
+ exec_group.register do
105
+ validator.invoke(report, options.merge(exec_group: exec_group))
106
+ end
107
+ end
108
+
109
+ exit_code = exec_group.exit_code
110
+ else
111
+ validators.each do |validator|
112
+ validator_exit_code = validator.invoke(report, options.dup)
113
+ exit_code = validator_exit_code if validator_exit_code != 0
114
+ end
115
+ end
116
+
117
+ report_formats.each do |format|
118
+ report.send(format[:method], format[:target])
119
+ end
120
+
121
+ exit exit_code
122
+ end
123
+ end
124
+ end