pdk 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1336 -1329
  3. data/LICENSE +201 -201
  4. data/README.md +163 -163
  5. data/exe/pdk +10 -10
  6. data/lib/pdk/analytics/client/google_analytics.rb +143 -143
  7. data/lib/pdk/analytics/client/noop.rb +25 -25
  8. data/lib/pdk/analytics/util.rb +19 -19
  9. data/lib/pdk/analytics.rb +30 -30
  10. data/lib/pdk/answer_file.rb +12 -12
  11. data/lib/pdk/bolt.rb +19 -19
  12. data/lib/pdk/cli/build.rb +82 -82
  13. data/lib/pdk/cli/bundle.rb +48 -48
  14. data/lib/pdk/cli/config/get.rb +26 -26
  15. data/lib/pdk/cli/config.rb +22 -22
  16. data/lib/pdk/cli/console.rb +148 -148
  17. data/lib/pdk/cli/convert.rb +52 -52
  18. data/lib/pdk/cli/env.rb +52 -52
  19. data/lib/pdk/cli/errors.rb +25 -25
  20. data/lib/pdk/cli/exec/command.rb +293 -293
  21. data/lib/pdk/cli/exec/interactive_command.rb +114 -114
  22. data/lib/pdk/cli/exec.rb +84 -84
  23. data/lib/pdk/cli/exec_group.rb +104 -104
  24. data/lib/pdk/cli/get/config.rb +24 -24
  25. data/lib/pdk/cli/get.rb +20 -20
  26. data/lib/pdk/cli/module/build.rb +12 -12
  27. data/lib/pdk/cli/module/generate.rb +47 -47
  28. data/lib/pdk/cli/module.rb +14 -14
  29. data/lib/pdk/cli/new/class.rb +32 -32
  30. data/lib/pdk/cli/new/defined_type.rb +32 -32
  31. data/lib/pdk/cli/new/fact.rb +29 -29
  32. data/lib/pdk/cli/new/function.rb +29 -29
  33. data/lib/pdk/cli/new/module.rb +53 -53
  34. data/lib/pdk/cli/new/provider.rb +29 -29
  35. data/lib/pdk/cli/new/task.rb +34 -34
  36. data/lib/pdk/cli/new/test.rb +52 -52
  37. data/lib/pdk/cli/new/transport.rb +27 -27
  38. data/lib/pdk/cli/new.rb +21 -21
  39. data/lib/pdk/cli/release/prep.rb +39 -39
  40. data/lib/pdk/cli/release/publish.rb +50 -50
  41. data/lib/pdk/cli/release.rb +194 -194
  42. data/lib/pdk/cli/remove/config.rb +80 -80
  43. data/lib/pdk/cli/remove.rb +20 -20
  44. data/lib/pdk/cli/set/config.rb +119 -119
  45. data/lib/pdk/cli/set.rb +20 -20
  46. data/lib/pdk/cli/test/unit.rb +90 -90
  47. data/lib/pdk/cli/test.rb +11 -11
  48. data/lib/pdk/cli/update.rb +64 -64
  49. data/lib/pdk/cli/util/command_redirector.rb +27 -27
  50. data/lib/pdk/cli/util/interview.rb +72 -72
  51. data/lib/pdk/cli/util/option_normalizer.rb +55 -55
  52. data/lib/pdk/cli/util/option_validator.rb +68 -68
  53. data/lib/pdk/cli/util/spinner.rb +13 -13
  54. data/lib/pdk/cli/util/update_manager_printer.rb +82 -82
  55. data/lib/pdk/cli/util.rb +305 -305
  56. data/lib/pdk/cli/validate.rb +116 -116
  57. data/lib/pdk/cli.rb +175 -175
  58. data/lib/pdk/config/analytics_schema.json +26 -26
  59. data/lib/pdk/config/errors.rb +5 -5
  60. data/lib/pdk/config/ini_file.rb +183 -183
  61. data/lib/pdk/config/ini_file_setting.rb +39 -39
  62. data/lib/pdk/config/json.rb +34 -34
  63. data/lib/pdk/config/json_schema_namespace.rb +142 -142
  64. data/lib/pdk/config/json_schema_setting.rb +53 -53
  65. data/lib/pdk/config/json_with_schema.rb +49 -49
  66. data/lib/pdk/config/namespace.rb +354 -354
  67. data/lib/pdk/config/setting.rb +135 -135
  68. data/lib/pdk/config/validator.rb +31 -31
  69. data/lib/pdk/config/yaml.rb +46 -46
  70. data/lib/pdk/config/yaml_with_schema.rb +59 -59
  71. data/lib/pdk/config.rb +390 -390
  72. data/lib/pdk/context/control_repo.rb +60 -60
  73. data/lib/pdk/context/module.rb +28 -28
  74. data/lib/pdk/context/none.rb +22 -22
  75. data/lib/pdk/context.rb +99 -99
  76. data/lib/pdk/control_repo.rb +90 -90
  77. data/lib/pdk/generate/defined_type.rb +43 -43
  78. data/lib/pdk/generate/fact.rb +25 -25
  79. data/lib/pdk/generate/function.rb +48 -48
  80. data/lib/pdk/generate/module.rb +352 -352
  81. data/lib/pdk/generate/provider.rb +28 -28
  82. data/lib/pdk/generate/puppet_class.rb +43 -43
  83. data/lib/pdk/generate/puppet_object.rb +232 -232
  84. data/lib/pdk/generate/task.rb +68 -68
  85. data/lib/pdk/generate/transport.rb +33 -33
  86. data/lib/pdk/generate.rb +24 -24
  87. data/lib/pdk/i18n.rb +4 -4
  88. data/lib/pdk/logger.rb +45 -45
  89. data/lib/pdk/module/build.rb +322 -322
  90. data/lib/pdk/module/convert.rb +296 -296
  91. data/lib/pdk/module/metadata.rb +202 -202
  92. data/lib/pdk/module/release.rb +260 -260
  93. data/lib/pdk/module/update.rb +131 -131
  94. data/lib/pdk/module/update_manager.rb +227 -227
  95. data/lib/pdk/module.rb +30 -30
  96. data/lib/pdk/report/event.rb +370 -370
  97. data/lib/pdk/report.rb +121 -121
  98. data/lib/pdk/template/fetcher/git.rb +85 -85
  99. data/lib/pdk/template/fetcher/local.rb +28 -28
  100. data/lib/pdk/template/fetcher.rb +98 -98
  101. data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +116 -116
  102. data/lib/pdk/template/renderer/v1/renderer.rb +132 -132
  103. data/lib/pdk/template/renderer/v1/template_file.rb +102 -102
  104. data/lib/pdk/template/renderer/v1.rb +25 -25
  105. data/lib/pdk/template/renderer.rb +96 -96
  106. data/lib/pdk/template/template_dir.rb +67 -67
  107. data/lib/pdk/template.rb +59 -59
  108. data/lib/pdk/tests/unit.rb +252 -252
  109. data/lib/pdk/util/bundler.rb +259 -259
  110. data/lib/pdk/util/changelog_generator.rb +137 -137
  111. data/lib/pdk/util/env.rb +47 -47
  112. data/lib/pdk/util/filesystem.rb +138 -138
  113. data/lib/pdk/util/git.rb +179 -179
  114. data/lib/pdk/util/json_finder.rb +85 -85
  115. data/lib/pdk/util/puppet_strings.rb +125 -125
  116. data/lib/pdk/util/puppet_version.rb +266 -266
  117. data/lib/pdk/util/ruby_version.rb +179 -179
  118. data/lib/pdk/util/template_uri.rb +295 -295
  119. data/lib/pdk/util/vendored_file.rb +93 -93
  120. data/lib/pdk/util/version.rb +43 -43
  121. data/lib/pdk/util/windows/api_types.rb +82 -82
  122. data/lib/pdk/util/windows/file.rb +36 -36
  123. data/lib/pdk/util/windows/process.rb +79 -79
  124. data/lib/pdk/util/windows/string.rb +16 -16
  125. data/lib/pdk/util/windows.rb +15 -15
  126. data/lib/pdk/util.rb +278 -278
  127. data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -23
  128. data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -98
  129. data/lib/pdk/validate/external_command_validator.rb +208 -208
  130. data/lib/pdk/validate/internal_ruby_validator.rb +100 -100
  131. data/lib/pdk/validate/invokable_validator.rb +228 -228
  132. data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +86 -86
  133. data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +78 -78
  134. data/lib/pdk/validate/metadata/metadata_validator_group.rb +20 -20
  135. data/lib/pdk/validate/puppet/puppet_epp_validator.rb +133 -133
  136. data/lib/pdk/validate/puppet/puppet_lint_validator.rb +66 -66
  137. data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +137 -137
  138. data/lib/pdk/validate/puppet/puppet_validator_group.rb +21 -21
  139. data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +80 -80
  140. data/lib/pdk/validate/ruby/ruby_validator_group.rb +19 -19
  141. data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +88 -88
  142. data/lib/pdk/validate/tasks/tasks_name_validator.rb +50 -50
  143. data/lib/pdk/validate/tasks/tasks_validator_group.rb +20 -20
  144. data/lib/pdk/validate/validator.rb +118 -118
  145. data/lib/pdk/validate/validator_group.rb +104 -104
  146. data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +95 -95
  147. data/lib/pdk/validate/yaml/yaml_validator_group.rb +19 -19
  148. data/lib/pdk/validate.rb +94 -94
  149. data/lib/pdk/version.rb +4 -4
  150. data/lib/pdk.rb +76 -76
  151. data/locales/config.yaml +21 -21
  152. data/locales/pdk.pot +2111 -2094
  153. metadata +3 -3
data/lib/pdk/cli/util.rb CHANGED
@@ -1,305 +1,305 @@
1
- require 'pdk'
2
-
3
- module PDK
4
- module CLI
5
- module Util
6
- autoload :CommandRedirector, 'pdk/cli/util/command_redirector'
7
- autoload :OptionNormalizer, 'pdk/cli/util/option_normalizer'
8
- autoload :OptionValidator, 'pdk/cli/util/option_validator'
9
- autoload :Interview, 'pdk/cli/util/interview'
10
- autoload :Spinner, 'pdk/cli/util/spinner'
11
- autoload :UpdateManagerPrinter, 'pdk/cli/util/update_manager_printer'
12
-
13
- # Ensures the calling code is being run from inside a module directory.
14
- #
15
- # @param opts [Hash] options to change the behavior of the check logic.
16
- # @option opts [Boolean] :check_module_layout Set to true to check for
17
- # stardard module folder layout if the module does not contain
18
- # a metadata.json file.
19
- #
20
- # @raise [PDK::CLI::ExitWithError] if the current directory does not
21
- # contain a Puppet module.
22
- def ensure_in_module!(opts = {})
23
- return unless PDK::Util.module_root.nil?
24
- return if opts[:check_module_layout] && PDK::Util.in_module_root?
25
-
26
- message = opts.fetch(:message, _('This command must be run from inside a valid module (no metadata.json found).'))
27
- raise PDK::CLI::ExitWithError.new(message, opts)
28
- end
29
- module_function :ensure_in_module!
30
-
31
- def spinner_opts_for_platform
32
- windows_opts = {
33
- success_mark: '*',
34
- error_mark: 'X',
35
- }
36
-
37
- return windows_opts if Gem.win_platform?
38
- {}
39
- end
40
- module_function :spinner_opts_for_platform
41
-
42
- def prompt_for_yes(question_text, opts = {})
43
- require 'tty/prompt'
44
-
45
- prompt = opts[:prompt] || TTY::Prompt.new(help_color: :cyan)
46
- validator = proc { |value| [true, false].include?(value) || value =~ %r{\A(?:yes|y|no|n)\Z}i }
47
- response = nil
48
-
49
- begin
50
- response = prompt.yes?(question_text) do |q|
51
- q.default opts[:default] unless opts[:default].nil?
52
- q.validate(validator, _('Answer "Y" to continue or "n" to cancel.'))
53
- end
54
- rescue PDK::CLI::Util::Interview::READER::InputInterrupt
55
- PDK.logger.info opts[:cancel_message] if opts[:cancel_message]
56
- end
57
-
58
- response
59
- end
60
- module_function :prompt_for_yes
61
-
62
- # Uses environment variables to detect if the current process is running in common
63
- # Continuous Integration (CI) environments
64
- # @return [Boolean] Whether the PDK is in a CI based environment
65
- def ci_environment?
66
- [
67
- 'CI', # Generic
68
- 'CONTINUOUS_INTEGRATION', # Generic
69
- 'APPVEYOR_BUILD_FOLDER', # AppVeyor CI
70
- 'GITLAB_CI', # GitLab CI
71
- 'JENKINS_URL', # Jenkins
72
- 'BUILD_DEFINITIONNAME', # Azure Pipelines
73
- 'TEAMCITY_VERSION', # Team City
74
- 'BAMBOO_BUILDKEY', # Bamboo
75
- 'GOCD_SERVER_URL', # Go CD
76
- 'TRAVIS', # Travis CI
77
- 'GITHUB_WORKFLOW', # GitHub Actions
78
- ].any? { |name| PDK::Util::Env.key?(name) }
79
- end
80
- module_function :ci_environment?
81
-
82
- def interactive?
83
- require 'pdk/logger'
84
-
85
- return false if PDK.logger.debug?
86
- return !PDK::Util::Env['PDK_FRONTEND'].casecmp('noninteractive').zero? if PDK::Util::Env['PDK_FRONTEND']
87
- return false if ci_environment?
88
- return false unless $stderr.isatty
89
-
90
- true
91
- end
92
- module_function :interactive?
93
-
94
- def module_version_check
95
- module_pdk_ver = PDK::Util.module_pdk_version
96
-
97
- # This means the module does not have a pdk-version tag in the metadata.json
98
- # and will require a pdk convert.
99
- 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?
100
-
101
- # This checks that the version of pdk in the module's metadata is older
102
- # than 1.3.1, which means the module will need to run pdk convert to the
103
- # new templates.
104
- if Gem::Version.new(module_pdk_ver) < Gem::Version.new('1.3.1')
105
- PDK.logger.warn _('This module template is out of date. Run `pdk convert` to make it compatible with your version of PDK.')
106
- # This checks if the version of the installed PDK is older than the
107
- # version in the module's metadata, and advises the user to upgrade to
108
- # their install of PDK.
109
- elsif Gem::Version.new(PDK::VERSION) < Gem::Version.new(module_pdk_ver)
110
- PDK.logger.warn _('This module is compatible with a newer version of PDK. Upgrade your version of PDK to ensure compatibility.')
111
- # This checks if the version listed in the module's metadata is older
112
- # than the installed PDK, and advises the user to run pdk update.
113
- elsif Gem::Version.new(PDK::VERSION) > Gem::Version.new(module_pdk_ver)
114
- PDK.logger.warn _('This module is compatible with an older version of PDK. Run `pdk update` to update it to your version of PDK.')
115
- end
116
- end
117
- module_function :module_version_check
118
-
119
- def check_for_deprecated_puppet(version)
120
- return unless version.is_a?(Gem::Version)
121
-
122
- deprecated_below = Gem::Version.new('5.0.0')
123
- return unless version < deprecated_below
124
-
125
- deprecated_msg = _(
126
- 'Support for Puppet versions older than %{version} is ' \
127
- 'deprecated and will be removed in a future version of PDK.',
128
- ) % { version: deprecated_below.to_s }
129
- PDK.logger.warn(deprecated_msg)
130
- end
131
- module_function :check_for_deprecated_puppet
132
-
133
- # @param opts [Hash] - the pdk options to use, defaults to empty hash
134
- # @option opts [String] :'puppet-dev' Use the puppet development version, default to PDK_PUPPET_DEV env
135
- # @option opts [String] :'puppet-version' Puppet version to use, default to PDK_PUPPET_VERSION env
136
- # @option opts [String] :'pe-version' PE Puppet version to use, default to PDK_PE_VERSION env
137
- # @param logging_disabled [Boolean] - disable logging of PDK info
138
- # @param context [PDK::Context::AbstractContext] - The context the PDK is running in
139
- # @return [Hash] - return hash of { gemset: <>, ruby_version: 2.x.x }
140
- def puppet_from_opts_or_env(opts, logging_disabled = false, context = PDK.context)
141
- opts ||= {}
142
- use_puppet_dev = opts.fetch(:'puppet-dev', PDK::Util::Env['PDK_PUPPET_DEV'])
143
- desired_puppet_version = opts.fetch(:'puppet-version', PDK::Util::Env['PDK_PUPPET_VERSION'])
144
- desired_pe_version = opts.fetch(:'pe-version', PDK::Util::Env['PDK_PE_VERSION'])
145
-
146
- begin
147
- puppet_env =
148
- if use_puppet_dev
149
- PDK::Util::PuppetVersion.fetch_puppet_dev(run: :once)
150
- PDK::Util::PuppetVersion.puppet_dev_env
151
- elsif desired_puppet_version
152
- PDK::Util::PuppetVersion.find_gem_for(desired_puppet_version)
153
- elsif desired_pe_version
154
- PDK::Util::PuppetVersion.from_pe_version(desired_pe_version)
155
- elsif context.is_a?(PDK::Context::Module)
156
- PDK::Util::PuppetVersion.from_module_metadata || PDK::Util::PuppetVersion.latest_available
157
- else
158
- PDK::Util::PuppetVersion.latest_available
159
- end
160
- rescue ArgumentError => e
161
- raise PDK::CLI::ExitWithError, e.message
162
- end
163
-
164
- # Notify user of what Ruby version will be used.
165
- unless logging_disabled
166
- PDK.logger.info(_('Using Ruby %{version}') % {
167
- version: puppet_env[:ruby_version],
168
- })
169
- end
170
-
171
- check_for_deprecated_puppet(puppet_env[:gem_version])
172
-
173
- gemset = { puppet: puppet_env[:gem_version].to_s }
174
-
175
- # Notify user of what gems are being activated.
176
- unless logging_disabled
177
- gemset.each do |gem, version|
178
- next if version.nil?
179
-
180
- PDK.logger.info(_('Using %{gem} %{version}') % {
181
- gem: gem.to_s.capitalize,
182
- version: version,
183
- })
184
- end
185
- end
186
-
187
- {
188
- gemset: gemset,
189
- ruby_version: puppet_env[:ruby_version],
190
- }
191
- end
192
- module_function :puppet_from_opts_or_env
193
-
194
- def validate_puppet_version_opts(opts)
195
- puppet_ver_specs = []
196
- puppet_ver_specs << '--puppet-version option' if opts[:'puppet-version']
197
- puppet_ver_specs << 'PDK_PUPPET_VERSION environment variable' if PDK::Util::Env['PDK_PUPPET_VERSION'] && !PDK::Util::Env['PDK_PUPPET_VERSION'].empty?
198
-
199
- pe_ver_specs = []
200
- pe_ver_specs << '--pe-version option' if opts[:'pe-version']
201
- pe_ver_specs << 'PDK_PE_VERSION environment variable' if PDK::Util::Env['PDK_PE_VERSION'] && !PDK::Util::Env['PDK_PE_VERSION'].empty?
202
-
203
- puppet_dev_specs = []
204
- puppet_dev_specs << '--puppet-dev flag' if opts[:'puppet-dev']
205
- puppet_dev_specs << 'PDK_PUPPET_DEV environment variable' if PDK::Util::Env['PDK_PUPPET_DEV'] && !PDK::Util::Env['PDK_PUPPET_DEV'].empty?
206
-
207
- puppet_dev_specs.each do |pup_dev_spec|
208
- [puppet_ver_specs, pe_ver_specs].each do |offending|
209
- next if offending.empty?
210
-
211
- raise PDK::CLI::ExitWithError, _('You cannot specify a %{first} and %{second} at the same time.') % {
212
- first: pup_dev_spec,
213
- second: offending.first,
214
- }
215
- end
216
- end
217
-
218
- puppet_ver_specs.each do |pup_ver_spec|
219
- next if pe_ver_specs.empty?
220
-
221
- offending = [pup_ver_spec, pe_ver_specs[0]].sort
222
-
223
- raise PDK::CLI::ExitWithError, _('You cannot specify a %{first} and %{second} at the same time.') % {
224
- first: offending[0],
225
- second: offending[1],
226
- }
227
- end
228
-
229
- if puppet_dev_specs.size == 2
230
- warning_str = 'Puppet dev flag from command line: "--puppet-dev" '
231
- warning_str += 'overrides value from environment: "PDK_PUPPET_DEV=true". You should not specify both.'
232
-
233
- PDK.logger.warn(_(warning_str) % {
234
- pup_ver_opt: opts[:'puppet-dev'],
235
- pup_ver_env: PDK::Util::Env['PDK_PUPPET_DEV'],
236
- })
237
- elsif puppet_ver_specs.size == 2
238
- warning_str = 'Puppet version option from command line: "--puppet-version=%{pup_ver_opt}" '
239
- warning_str += 'overrides value from environment: "PDK_PUPPET_VERSION=%{pup_ver_env}". You should not specify both.'
240
-
241
- PDK.logger.warn(_(warning_str) % {
242
- pup_ver_opt: opts[:'puppet-version'],
243
- pup_ver_env: PDK::Util::Env['PDK_PUPPET_VERSION'],
244
- })
245
- elsif pe_ver_specs.size == 2
246
- warning_str = 'Puppet Enterprise version option from command line: "--pe-version=%{pe_ver_opt}" '
247
- warning_str += 'overrides value from environment: "PDK_PE_VERSION=%{pe_ver_env}". You should not specify both.'
248
-
249
- PDK.logger.warn(_(warning_str) % {
250
- pup_ver_opt: opts[:'pe-version'],
251
- pup_ver_env: PDK::Util::Env['PDK_PE_VERSION'],
252
- })
253
- end
254
- end
255
- module_function :validate_puppet_version_opts
256
-
257
- def validate_template_opts(opts)
258
- if opts[:'template-ref'] && opts[:'template-url'].nil?
259
- raise PDK::CLI::ExitWithError, _('--template-ref requires --template-url to also be specified.')
260
- end
261
-
262
- return unless opts[:'template-url'] && opts[:'template-url'].include?('#')
263
- raise PDK::CLI::ExitWithError, _('--template-url may not be used to specify paths containing #\'s.')
264
- end
265
- module_function :validate_template_opts
266
-
267
- def analytics_screen_view(screen_name, opts = {})
268
- require 'pdk/analytics'
269
-
270
- dimensions = {
271
- ruby_version: RUBY_VERSION,
272
- }
273
-
274
- cmd_opts = opts.dup.reject do |_, v|
275
- v.nil? || (v.respond_to?(:empty?) && v.empty?)
276
- end
277
-
278
- if (format_args = cmd_opts.delete(:format))
279
- formats = PDK::CLI::Util::OptionNormalizer.report_formats(format_args)
280
- dimensions[:output_format] = formats.map { |r| r[:method].to_s.gsub(%r{\Awrite_}, '') }.sort.uniq.join(',')
281
- else
282
- dimensions[:output_format] = 'default'
283
- end
284
-
285
- safe_opts = [:'puppet-version', :'pe-version']
286
- redacted_opts = cmd_opts.map do |k, v|
287
- value = if [true, false].include?(v) || safe_opts.include?(k)
288
- v
289
- else
290
- 'redacted'
291
- end
292
- "#{k}=#{value}"
293
- end
294
- dimensions[:cli_options] = redacted_opts.join(',') unless redacted_opts.empty?
295
-
296
- ignored_env_vars = %w[PDK_ANALYTICS_CONFIG PDK_DISABLE_ANALYTICS]
297
- env_vars = PDK::Util::Env.select { |k, _| k.start_with?('PDK_') && !ignored_env_vars.include?(k) }.map { |k, v| "#{k}=#{v}" }
298
- dimensions[:env_vars] = env_vars.join(',') unless env_vars.empty?
299
-
300
- PDK.analytics.screen_view(screen_name, dimensions)
301
- end
302
- module_function :analytics_screen_view
303
- end
304
- end
305
- end
1
+ require 'pdk'
2
+
3
+ module PDK
4
+ module CLI
5
+ module Util
6
+ autoload :CommandRedirector, 'pdk/cli/util/command_redirector'
7
+ autoload :OptionNormalizer, 'pdk/cli/util/option_normalizer'
8
+ autoload :OptionValidator, 'pdk/cli/util/option_validator'
9
+ autoload :Interview, 'pdk/cli/util/interview'
10
+ autoload :Spinner, 'pdk/cli/util/spinner'
11
+ autoload :UpdateManagerPrinter, 'pdk/cli/util/update_manager_printer'
12
+
13
+ # Ensures the calling code is being run from inside a module directory.
14
+ #
15
+ # @param opts [Hash] options to change the behavior of the check logic.
16
+ # @option opts [Boolean] :check_module_layout Set to true to check for
17
+ # stardard module folder layout if the module does not contain
18
+ # a metadata.json file.
19
+ #
20
+ # @raise [PDK::CLI::ExitWithError] if the current directory does not
21
+ # contain a Puppet module.
22
+ def ensure_in_module!(opts = {})
23
+ return unless PDK::Util.module_root.nil?
24
+ return if opts[:check_module_layout] && PDK::Util.in_module_root?
25
+
26
+ message = opts.fetch(:message, _('This command must be run from inside a valid module (no metadata.json found).'))
27
+ raise PDK::CLI::ExitWithError.new(message, opts)
28
+ end
29
+ module_function :ensure_in_module!
30
+
31
+ def spinner_opts_for_platform
32
+ windows_opts = {
33
+ success_mark: '*',
34
+ error_mark: 'X',
35
+ }
36
+
37
+ return windows_opts if Gem.win_platform?
38
+ {}
39
+ end
40
+ module_function :spinner_opts_for_platform
41
+
42
+ def prompt_for_yes(question_text, opts = {})
43
+ require 'tty/prompt'
44
+
45
+ prompt = opts[:prompt] || TTY::Prompt.new(help_color: :cyan)
46
+ validator = proc { |value| [true, false].include?(value) || value =~ %r{\A(?:yes|y|no|n)\Z}i }
47
+ response = nil
48
+
49
+ begin
50
+ response = prompt.yes?(question_text) do |q|
51
+ q.default opts[:default] unless opts[:default].nil?
52
+ q.validate(validator, _('Answer "Y" to continue or "n" to cancel.'))
53
+ end
54
+ rescue PDK::CLI::Util::Interview::READER::InputInterrupt
55
+ PDK.logger.info opts[:cancel_message] if opts[:cancel_message]
56
+ end
57
+
58
+ response
59
+ end
60
+ module_function :prompt_for_yes
61
+
62
+ # Uses environment variables to detect if the current process is running in common
63
+ # Continuous Integration (CI) environments
64
+ # @return [Boolean] Whether the PDK is in a CI based environment
65
+ def ci_environment?
66
+ [
67
+ 'CI', # Generic
68
+ 'CONTINUOUS_INTEGRATION', # Generic
69
+ 'APPVEYOR_BUILD_FOLDER', # AppVeyor CI
70
+ 'GITLAB_CI', # GitLab CI
71
+ 'JENKINS_URL', # Jenkins
72
+ 'BUILD_DEFINITIONNAME', # Azure Pipelines
73
+ 'TEAMCITY_VERSION', # Team City
74
+ 'BAMBOO_BUILDKEY', # Bamboo
75
+ 'GOCD_SERVER_URL', # Go CD
76
+ 'TRAVIS', # Travis CI
77
+ 'GITHUB_WORKFLOW', # GitHub Actions
78
+ ].any? { |name| PDK::Util::Env.key?(name) }
79
+ end
80
+ module_function :ci_environment?
81
+
82
+ def interactive?
83
+ require 'pdk/logger'
84
+
85
+ return false if PDK.logger.debug?
86
+ return !PDK::Util::Env['PDK_FRONTEND'].casecmp('noninteractive').zero? if PDK::Util::Env['PDK_FRONTEND']
87
+ return false if ci_environment?
88
+ return false unless $stderr.isatty
89
+
90
+ true
91
+ end
92
+ module_function :interactive?
93
+
94
+ def module_version_check
95
+ module_pdk_ver = PDK::Util.module_pdk_version
96
+
97
+ # This means the module does not have a pdk-version tag in the metadata.json
98
+ # and will require a pdk convert.
99
+ 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?
100
+
101
+ # This checks that the version of pdk in the module's metadata is older
102
+ # than 1.3.1, which means the module will need to run pdk convert to the
103
+ # new templates.
104
+ if Gem::Version.new(module_pdk_ver) < Gem::Version.new('1.3.1')
105
+ PDK.logger.warn _('This module template is out of date. Run `pdk convert` to make it compatible with your version of PDK.')
106
+ # This checks if the version of the installed PDK is older than the
107
+ # version in the module's metadata, and advises the user to upgrade to
108
+ # their install of PDK.
109
+ elsif Gem::Version.new(PDK::VERSION) < Gem::Version.new(module_pdk_ver)
110
+ PDK.logger.warn _('This module is compatible with a newer version of PDK. Upgrade your version of PDK to ensure compatibility.')
111
+ # This checks if the version listed in the module's metadata is older
112
+ # than the installed PDK, and advises the user to run pdk update.
113
+ elsif Gem::Version.new(PDK::VERSION) > Gem::Version.new(module_pdk_ver)
114
+ PDK.logger.warn _('This module is compatible with an older version of PDK. Run `pdk update` to update it to your version of PDK.')
115
+ end
116
+ end
117
+ module_function :module_version_check
118
+
119
+ def check_for_deprecated_puppet(version)
120
+ return unless version.is_a?(Gem::Version)
121
+
122
+ deprecated_below = Gem::Version.new('5.0.0')
123
+ return unless version < deprecated_below
124
+
125
+ deprecated_msg = _(
126
+ 'Support for Puppet versions older than %{version} is ' \
127
+ 'deprecated and will be removed in a future version of PDK.',
128
+ ) % { version: deprecated_below.to_s }
129
+ PDK.logger.warn(deprecated_msg)
130
+ end
131
+ module_function :check_for_deprecated_puppet
132
+
133
+ # @param opts [Hash] - the pdk options to use, defaults to empty hash
134
+ # @option opts [String] :'puppet-dev' Use the puppet development version, default to PDK_PUPPET_DEV env
135
+ # @option opts [String] :'puppet-version' Puppet version to use, default to PDK_PUPPET_VERSION env
136
+ # @option opts [String] :'pe-version' PE Puppet version to use, default to PDK_PE_VERSION env
137
+ # @param logging_disabled [Boolean] - disable logging of PDK info
138
+ # @param context [PDK::Context::AbstractContext] - The context the PDK is running in
139
+ # @return [Hash] - return hash of { gemset: <>, ruby_version: 2.x.x }
140
+ def puppet_from_opts_or_env(opts, logging_disabled = false, context = PDK.context)
141
+ opts ||= {}
142
+ use_puppet_dev = opts.fetch(:'puppet-dev', PDK::Util::Env['PDK_PUPPET_DEV'])
143
+ desired_puppet_version = opts.fetch(:'puppet-version', PDK::Util::Env['PDK_PUPPET_VERSION'])
144
+ desired_pe_version = opts.fetch(:'pe-version', PDK::Util::Env['PDK_PE_VERSION'])
145
+
146
+ begin
147
+ puppet_env =
148
+ if use_puppet_dev
149
+ PDK::Util::PuppetVersion.fetch_puppet_dev(run: :once)
150
+ PDK::Util::PuppetVersion.puppet_dev_env
151
+ elsif desired_puppet_version
152
+ PDK::Util::PuppetVersion.find_gem_for(desired_puppet_version)
153
+ elsif desired_pe_version
154
+ PDK::Util::PuppetVersion.from_pe_version(desired_pe_version)
155
+ elsif context.is_a?(PDK::Context::Module)
156
+ PDK::Util::PuppetVersion.from_module_metadata || PDK::Util::PuppetVersion.latest_available
157
+ else
158
+ PDK::Util::PuppetVersion.latest_available
159
+ end
160
+ rescue ArgumentError => e
161
+ raise PDK::CLI::ExitWithError, e.message
162
+ end
163
+
164
+ # Notify user of what Ruby version will be used.
165
+ unless logging_disabled
166
+ PDK.logger.info(_('Using Ruby %{version}') % {
167
+ version: puppet_env[:ruby_version],
168
+ })
169
+ end
170
+
171
+ check_for_deprecated_puppet(puppet_env[:gem_version])
172
+
173
+ gemset = { puppet: puppet_env[:gem_version].to_s }
174
+
175
+ # Notify user of what gems are being activated.
176
+ unless logging_disabled
177
+ gemset.each do |gem, version|
178
+ next if version.nil?
179
+
180
+ PDK.logger.info(_('Using %{gem} %{version}') % {
181
+ gem: gem.to_s.capitalize,
182
+ version: version,
183
+ })
184
+ end
185
+ end
186
+
187
+ {
188
+ gemset: gemset,
189
+ ruby_version: puppet_env[:ruby_version],
190
+ }
191
+ end
192
+ module_function :puppet_from_opts_or_env
193
+
194
+ def validate_puppet_version_opts(opts)
195
+ puppet_ver_specs = []
196
+ puppet_ver_specs << '--puppet-version option' if opts[:'puppet-version']
197
+ puppet_ver_specs << 'PDK_PUPPET_VERSION environment variable' if PDK::Util::Env['PDK_PUPPET_VERSION'] && !PDK::Util::Env['PDK_PUPPET_VERSION'].empty?
198
+
199
+ pe_ver_specs = []
200
+ pe_ver_specs << '--pe-version option' if opts[:'pe-version']
201
+ pe_ver_specs << 'PDK_PE_VERSION environment variable' if PDK::Util::Env['PDK_PE_VERSION'] && !PDK::Util::Env['PDK_PE_VERSION'].empty?
202
+
203
+ puppet_dev_specs = []
204
+ puppet_dev_specs << '--puppet-dev flag' if opts[:'puppet-dev']
205
+ puppet_dev_specs << 'PDK_PUPPET_DEV environment variable' if PDK::Util::Env['PDK_PUPPET_DEV'] && !PDK::Util::Env['PDK_PUPPET_DEV'].empty?
206
+
207
+ puppet_dev_specs.each do |pup_dev_spec|
208
+ [puppet_ver_specs, pe_ver_specs].each do |offending|
209
+ next if offending.empty?
210
+
211
+ raise PDK::CLI::ExitWithError, _('You cannot specify a %{first} and %{second} at the same time.') % {
212
+ first: pup_dev_spec,
213
+ second: offending.first,
214
+ }
215
+ end
216
+ end
217
+
218
+ puppet_ver_specs.each do |pup_ver_spec|
219
+ next if pe_ver_specs.empty?
220
+
221
+ offending = [pup_ver_spec, pe_ver_specs[0]].sort
222
+
223
+ raise PDK::CLI::ExitWithError, _('You cannot specify a %{first} and %{second} at the same time.') % {
224
+ first: offending[0],
225
+ second: offending[1],
226
+ }
227
+ end
228
+
229
+ if puppet_dev_specs.size == 2
230
+ warning_str = 'Puppet dev flag from command line: "--puppet-dev" '
231
+ warning_str += 'overrides value from environment: "PDK_PUPPET_DEV=true". You should not specify both.'
232
+
233
+ PDK.logger.warn(_(warning_str) % {
234
+ pup_ver_opt: opts[:'puppet-dev'],
235
+ pup_ver_env: PDK::Util::Env['PDK_PUPPET_DEV'],
236
+ })
237
+ elsif puppet_ver_specs.size == 2
238
+ warning_str = 'Puppet version option from command line: "--puppet-version=%{pup_ver_opt}" '
239
+ warning_str += 'overrides value from environment: "PDK_PUPPET_VERSION=%{pup_ver_env}". You should not specify both.'
240
+
241
+ PDK.logger.warn(_(warning_str) % {
242
+ pup_ver_opt: opts[:'puppet-version'],
243
+ pup_ver_env: PDK::Util::Env['PDK_PUPPET_VERSION'],
244
+ })
245
+ elsif pe_ver_specs.size == 2
246
+ warning_str = 'Puppet Enterprise version option from command line: "--pe-version=%{pe_ver_opt}" '
247
+ warning_str += 'overrides value from environment: "PDK_PE_VERSION=%{pe_ver_env}". You should not specify both.'
248
+
249
+ PDK.logger.warn(_(warning_str) % {
250
+ pup_ver_opt: opts[:'pe-version'],
251
+ pup_ver_env: PDK::Util::Env['PDK_PE_VERSION'],
252
+ })
253
+ end
254
+ end
255
+ module_function :validate_puppet_version_opts
256
+
257
+ def validate_template_opts(opts)
258
+ if opts[:'template-ref'] && opts[:'template-url'].nil?
259
+ raise PDK::CLI::ExitWithError, _('--template-ref requires --template-url to also be specified.')
260
+ end
261
+
262
+ return unless opts[:'template-url'] && opts[:'template-url'].include?('#')
263
+ raise PDK::CLI::ExitWithError, _('--template-url may not be used to specify paths containing #\'s.')
264
+ end
265
+ module_function :validate_template_opts
266
+
267
+ def analytics_screen_view(screen_name, opts = {})
268
+ require 'pdk/analytics'
269
+
270
+ dimensions = {
271
+ ruby_version: RUBY_VERSION,
272
+ }
273
+
274
+ cmd_opts = opts.dup.reject do |_, v|
275
+ v.nil? || (v.respond_to?(:empty?) && v.empty?)
276
+ end
277
+
278
+ if (format_args = cmd_opts.delete(:format))
279
+ formats = PDK::CLI::Util::OptionNormalizer.report_formats(format_args)
280
+ dimensions[:output_format] = formats.map { |r| r[:method].to_s.gsub(%r{\Awrite_}, '') }.sort.uniq.join(',')
281
+ else
282
+ dimensions[:output_format] = 'default'
283
+ end
284
+
285
+ safe_opts = [:'puppet-version', :'pe-version']
286
+ redacted_opts = cmd_opts.map do |k, v|
287
+ value = if [true, false].include?(v) || safe_opts.include?(k)
288
+ v
289
+ else
290
+ 'redacted'
291
+ end
292
+ "#{k}=#{value}"
293
+ end
294
+ dimensions[:cli_options] = redacted_opts.join(',') unless redacted_opts.empty?
295
+
296
+ ignored_env_vars = %w[PDK_ANALYTICS_CONFIG PDK_DISABLE_ANALYTICS]
297
+ env_vars = PDK::Util::Env.select { |k, _| k.start_with?('PDK_') && !ignored_env_vars.include?(k) }.map { |k, v| "#{k}=#{v}" }
298
+ dimensions[:env_vars] = env_vars.join(',') unless env_vars.empty?
299
+
300
+ PDK.analytics.screen_view(screen_name, dimensions)
301
+ end
302
+ module_function :analytics_screen_view
303
+ end
304
+ end
305
+ end