pdk 2.1.0 → 2.4.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.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1329 -1292
  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 -283
  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 -192
  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 -42
  70. data/lib/pdk/config/yaml_with_schema.rb +59 -59
  71. data/lib/pdk/config.rb +390 -384
  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 -254
  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 -124
  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 -84
  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 -277
  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 -220
  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 +2094 -2094
  153. metadata +19 -13
@@ -1,283 +1,293 @@
1
- require 'pdk'
2
-
3
- module PDK
4
- module CLI
5
- module Exec
6
- class Command
7
- attr_reader :argv
8
- attr_reader :context
9
- attr_accessor :timeout
10
- attr_accessor :environment
11
- attr_writer :exec_group
12
-
13
- # The spinner for this command.
14
- # This should only be used for testing
15
- #
16
- # @return [TTY::Spinner, nil]
17
- #
18
- # @api private
19
- attr_reader :spinner
20
-
21
- TEMPFILE_MODE = File::RDWR | File::BINARY | File::CREAT | File::TRUNC
22
-
23
- def initialize(*argv)
24
- require 'childprocess'
25
- require 'tempfile'
26
-
27
- @argv = argv
28
-
29
- @process = ChildProcess.build(*@argv)
30
- @process.leader = true
31
-
32
- @stdout = Tempfile.new('stdout', mode: TEMPFILE_MODE).tap { |io| io.sync = true }
33
- @stderr = Tempfile.new('stderr', mode: TEMPFILE_MODE).tap { |io| io.sync = true }
34
-
35
- @process.io.stdout = @stdout
36
- @process.io.stderr = @stderr
37
-
38
- # Default to running things in the system context.
39
- @context = :system
40
-
41
- # Extra environment vars to add to base set.
42
- @environment = {}
43
-
44
- # Register the ExecGroup when running in parallel
45
- @exec_group = nil
46
- end
47
-
48
- def context=(new_context)
49
- unless [:system, :module, :pwd].include?(new_context)
50
- raise ArgumentError, _("Expected execution context to be :system or :module but got '%{context}'.") % { context: new_context }
51
- end
52
-
53
- @context = new_context
54
- end
55
-
56
- def register_spinner(spinner, opts = {})
57
- require 'pdk/cli/util'
58
-
59
- return unless PDK::CLI::Util.interactive?
60
- @success_message = opts.delete(:success)
61
- @failure_message = opts.delete(:failure)
62
-
63
- @spinner = spinner
64
- end
65
-
66
- def add_spinner(message, opts = {})
67
- require 'pdk/cli/util'
68
-
69
- return unless PDK::CLI::Util.interactive?
70
- @success_message = opts.delete(:success)
71
- @failure_message = opts.delete(:failure)
72
-
73
- require 'pdk/cli/util/spinner'
74
-
75
- @spinner = TTY::Spinner.new("[:spinner] #{message}", opts.merge(PDK::CLI::Util.spinner_opts_for_platform))
76
- end
77
-
78
- def update_environment(additional_env)
79
- @environment.merge!(additional_env)
80
- end
81
-
82
- # @return [Hash[Symbol => Object]] The result from executing the command
83
- # :stdout => String : The result of STDOUT
84
- # :stderr => String : The result of STDERR
85
- # :exit_code => Integer : The exit code from the command
86
- # :duration => Float : Number seconds it took to execute
87
- def execute!
88
- # Start spinning if configured.
89
- @spinner.auto_spin if @spinner
90
-
91
- # Set env for child process
92
- resolved_env_for_command.each { |k, v| @process.environment[k] = v }
93
-
94
- if [:module, :pwd].include?(context)
95
- require 'pdk/util'
96
- mod_root = PDK::Util.module_root
97
-
98
- unless mod_root
99
- @spinner.error if @spinner
100
-
101
- raise PDK::CLI::FatalError, _('Current working directory is not part of a module. (No metadata.json was found.)')
102
- end
103
-
104
- if Dir.pwd == mod_root || context == :pwd
105
- run_process_in_clean_env!
106
- else
107
- Dir.chdir(mod_root) do
108
- run_process_in_clean_env!
109
- end
110
- end
111
- else
112
- run_process!
113
- end
114
-
115
- # Stop spinning when done (if configured).
116
- stop_spinner
117
-
118
- @stdout.rewind
119
- @stderr.rewind
120
-
121
- process_data = {
122
- stdout: @stdout.read,
123
- stderr: @stderr.read,
124
- exit_code: @process.exit_code,
125
- duration: @duration,
126
- }
127
-
128
- PDK.logger.debug _('STDOUT: %{output}') % {
129
- output: process_data[:stdout].empty? ? 'N/A' : "\n#{process_data[:stdout]}",
130
- }
131
- PDK.logger.debug _('STDERR: %{output}') % {
132
- output: process_data[:stderr].empty? ? 'N/A' : "\n#{process_data[:stderr]}",
133
- }
134
-
135
- process_data
136
- ensure
137
- @stdout.close
138
- @stderr.close
139
- end
140
-
141
- protected
142
-
143
- def warn_on_legacy_env_vars!
144
- if PDK::Util::Env['PUPPET_GEM_VERSION']
145
- PDK.logger.warn_once _(
146
- 'PUPPET_GEM_VERSION is not supported by PDK. ' \
147
- 'Use the --puppet-version option on your PDK command ' \
148
- 'or set the PDK_PUPPET_VERSION environment variable instead',
149
- )
150
- end
151
-
152
- %w[FACTER HIERA].each do |gem|
153
- if PDK::Util::Env["#{gem}_GEM_VERSION"]
154
- PDK.logger.warn_once _('%{varname} is not supported by PDK.') % { varname: "#{gem}_GEM_VERSION" }
155
- end
156
- end
157
- end
158
-
159
- def resolved_env_for_command
160
- warn_on_legacy_env_vars!
161
-
162
- resolved_env = {}
163
-
164
- resolved_env['TERM'] = PDK::Util::Env['TERM']
165
- resolved_env['PUPPET_GEM_VERSION'] = nil
166
- resolved_env['FACTER_GEM_VERSION'] = nil
167
- resolved_env['HIERA_GEM_VERSION'] = nil
168
-
169
- resolved_env.merge!(@environment.dup)
170
-
171
- resolved_env['BUNDLE_IGNORE_CONFIG'] = '1'
172
-
173
- if [:module, :pwd].include?(context)
174
- require 'pdk/util'
175
- require 'pdk/util/git'
176
- require 'pdk/util/ruby_version'
177
-
178
- resolved_env['GEM_HOME'] = PDK::Util::RubyVersion.gem_home
179
- gem_path = PDK::Util::RubyVersion.gem_path
180
- resolved_env['GEM_PATH'] = gem_path.empty? ? resolved_env['GEM_HOME'] : gem_path
181
-
182
- # Make sure invocation of Ruby prefers our private installation.
183
- package_binpath = PDK::Util.package_install? ? File.join(PDK::Util.pdk_package_basedir, 'bin') : nil
184
-
185
- resolved_env['PATH'] = [
186
- PDK::Util::RubyVersion.bin_path,
187
- File.join(resolved_env['GEM_HOME'], 'bin'),
188
- PDK::Util::RubyVersion.gem_paths_raw.map { |gem_path_raw| File.join(gem_path_raw, 'bin') },
189
- package_binpath,
190
- PDK::Util.package_install? ? PDK::Util::Git.git_paths : nil,
191
- PDK::Util::Env['PATH'],
192
- ].compact.flatten.join(File::PATH_SEPARATOR)
193
- end
194
-
195
- resolved_env
196
- end
197
-
198
- def stop_spinner
199
- return unless @spinner
200
-
201
- # If it is a single spinner, we need to send it a success/error message
202
- if @process.exit_code.zero?
203
- @spinner.success(@success_message || '')
204
- else
205
- @spinner.error(@failure_message || '')
206
- end
207
- end
208
-
209
- def run_process_in_clean_env!
210
- require 'bundler'
211
-
212
- # Bundler 2.1.0 has deprecated the use of `Bundler.with_clean_env` in favour of
213
- # `Bundler.with_unbundled_env`. So prefer to use the newer method if it exists
214
- # otherwise revert back to the old method.
215
- if ::Bundler.respond_to?(:with_unbundled_env)
216
- run_process_with_unbundled_env!
217
- else
218
- run_process_with_clean_env!
219
- end
220
- end
221
-
222
- def run_process!
223
- command_string = argv.join(' ')
224
-
225
- PDK.logger.debug(_("Executing '%{command}'") % { command: command_string })
226
-
227
- if context == :module
228
- PDK.logger.debug(_('Command environment:'))
229
- @process.environment.each do |var, val|
230
- PDK.logger.debug(" #{var}: #{val}")
231
- end
232
- end
233
-
234
- start_time = Time.now
235
-
236
- begin
237
- @process.start
238
- rescue ChildProcess::LaunchError => e
239
- raise PDK::CLI::FatalError, _("Failed to execute '%{command}': %{message}") % { command: command_string, message: e.message }
240
- end
241
-
242
- if timeout
243
- begin
244
- @process.poll_for_exit(timeout)
245
- rescue ChildProcess::TimeoutError
246
- @process.stop # tries increasingly harsher methods to kill the process.
247
- end
248
- else
249
- # Wait indfinitely if no timeout set.
250
- @process.wait
251
- end
252
-
253
- @duration = Time.now - start_time
254
-
255
- PDK.logger.debug(_("Execution of '%{command}' complete (duration: %{duration_in_seconds}s; exit code: %{exit_code})") %
256
- { command: command_string, duration_in_seconds: @duration, exit_code: @process.exit_code })
257
- end
258
-
259
- private
260
-
261
- #:nocov:
262
- # These are just bundler helper methods and are tested via the public run_process_in_clean_env! method
263
- def run_process_with_unbundled_env!
264
- # Bundler 2.1.0 or greater
265
- ::Bundler.with_unbundled_env do
266
- run_process!
267
- end
268
- end
269
- #:nocov:
270
-
271
- #:nocov:
272
- # These are just bundler helper methods and are tested via the public run_process_in_clean_env! method
273
- def run_process_with_clean_env!
274
- # Bundler 2.0.2 or less
275
- ::Bundler.with_clean_env do
276
- run_process!
277
- end
278
- end
279
- #:nocov:
280
- end
281
- end
282
- end
283
- end
1
+ require 'pdk'
2
+
3
+ module PDK
4
+ module CLI
5
+ module Exec
6
+ class Command
7
+ attr_reader :argv
8
+ attr_reader :context
9
+ attr_accessor :timeout
10
+ attr_accessor :environment
11
+ attr_writer :exec_group
12
+
13
+ # The spinner for this command.
14
+ # This should only be used for testing
15
+ #
16
+ # @return [TTY::Spinner, nil]
17
+ #
18
+ # @api private
19
+ attr_reader :spinner
20
+
21
+ TEMPFILE_MODE = File::RDWR | File::BINARY | File::CREAT | File::TRUNC
22
+
23
+ def initialize(*argv)
24
+ require 'childprocess'
25
+ require 'tempfile'
26
+
27
+ @argv = argv
28
+
29
+ @process = ChildProcess.build(*@argv)
30
+ # https://github.com/puppetlabs/pdk/issues/1083:
31
+ # When @process.leader is set, childprocess will set the CREATE_BREAKAWAY_FROM_JOB
32
+ # and JOB_OBJECT_LIMIT_BREAKAWAY_OK flags in the Win32 API calls. This will cause
33
+ # issues on systems > Windows 7 / Server 2008, if the JOB_OBJECT_LIMIT_BREAKAWAY_OK
34
+ # flag is set and the Task Scheduler is trying to kick off a job, it can sometimes
35
+ # result in ACCESS_DENIED being returned by the Win32 API, depending on the permission
36
+ # levels / user account this user.
37
+ # The resolution for pdk/issues/1083 is to ensure @process.leader is not set.
38
+ # This will potentially cause issues on older Windows systems, in which case we may
39
+ # need to revisit and conditionally set this param depending on what OS we're on
40
+ # @process.leader = true
41
+
42
+ @stdout = Tempfile.new('stdout', mode: TEMPFILE_MODE).tap { |io| io.sync = true }
43
+ @stderr = Tempfile.new('stderr', mode: TEMPFILE_MODE).tap { |io| io.sync = true }
44
+
45
+ @process.io.stdout = @stdout
46
+ @process.io.stderr = @stderr
47
+
48
+ # Default to running things in the system context.
49
+ @context = :system
50
+
51
+ # Extra environment vars to add to base set.
52
+ @environment = {}
53
+
54
+ # Register the ExecGroup when running in parallel
55
+ @exec_group = nil
56
+ end
57
+
58
+ def context=(new_context)
59
+ unless [:system, :module, :pwd].include?(new_context)
60
+ raise ArgumentError, _("Expected execution context to be :system or :module but got '%{context}'.") % { context: new_context }
61
+ end
62
+
63
+ @context = new_context
64
+ end
65
+
66
+ def register_spinner(spinner, opts = {})
67
+ require 'pdk/cli/util'
68
+
69
+ return unless PDK::CLI::Util.interactive?
70
+ @success_message = opts.delete(:success)
71
+ @failure_message = opts.delete(:failure)
72
+
73
+ @spinner = spinner
74
+ end
75
+
76
+ def add_spinner(message, opts = {})
77
+ require 'pdk/cli/util'
78
+
79
+ return unless PDK::CLI::Util.interactive?
80
+ @success_message = opts.delete(:success)
81
+ @failure_message = opts.delete(:failure)
82
+
83
+ require 'pdk/cli/util/spinner'
84
+
85
+ @spinner = TTY::Spinner.new("[:spinner] #{message}", opts.merge(PDK::CLI::Util.spinner_opts_for_platform))
86
+ end
87
+
88
+ def update_environment(additional_env)
89
+ @environment.merge!(additional_env)
90
+ end
91
+
92
+ # @return [Hash[Symbol => Object]] The result from executing the command
93
+ # :stdout => String : The result of STDOUT
94
+ # :stderr => String : The result of STDERR
95
+ # :exit_code => Integer : The exit code from the command
96
+ # :duration => Float : Number seconds it took to execute
97
+ def execute!
98
+ # Start spinning if configured.
99
+ @spinner.auto_spin if @spinner
100
+
101
+ # Set env for child process
102
+ resolved_env_for_command.each { |k, v| @process.environment[k] = v }
103
+
104
+ if [:module, :pwd].include?(context)
105
+ require 'pdk/util'
106
+ mod_root = PDK::Util.module_root
107
+
108
+ unless mod_root
109
+ @spinner.error if @spinner
110
+
111
+ raise PDK::CLI::FatalError, _('Current working directory is not part of a module. (No metadata.json was found.)')
112
+ end
113
+
114
+ if Dir.pwd == mod_root || context == :pwd
115
+ run_process_in_clean_env!
116
+ else
117
+ Dir.chdir(mod_root) do
118
+ run_process_in_clean_env!
119
+ end
120
+ end
121
+ else
122
+ run_process!
123
+ end
124
+
125
+ # Stop spinning when done (if configured).
126
+ stop_spinner
127
+
128
+ @stdout.rewind
129
+ @stderr.rewind
130
+
131
+ process_data = {
132
+ stdout: @stdout.read,
133
+ stderr: @stderr.read,
134
+ exit_code: @process.exit_code,
135
+ duration: @duration,
136
+ }
137
+
138
+ PDK.logger.debug _('STDOUT: %{output}') % {
139
+ output: process_data[:stdout].empty? ? 'N/A' : "\n#{process_data[:stdout]}",
140
+ }
141
+ PDK.logger.debug _('STDERR: %{output}') % {
142
+ output: process_data[:stderr].empty? ? 'N/A' : "\n#{process_data[:stderr]}",
143
+ }
144
+
145
+ process_data
146
+ ensure
147
+ @stdout.close
148
+ @stderr.close
149
+ end
150
+
151
+ protected
152
+
153
+ def warn_on_legacy_env_vars!
154
+ if PDK::Util::Env['PUPPET_GEM_VERSION']
155
+ PDK.logger.warn_once _(
156
+ 'PUPPET_GEM_VERSION is not supported by PDK. ' \
157
+ 'Use the --puppet-version option on your PDK command ' \
158
+ 'or set the PDK_PUPPET_VERSION environment variable instead',
159
+ )
160
+ end
161
+
162
+ %w[FACTER HIERA].each do |gem|
163
+ if PDK::Util::Env["#{gem}_GEM_VERSION"]
164
+ PDK.logger.warn_once _('%{varname} is not supported by PDK.') % { varname: "#{gem}_GEM_VERSION" }
165
+ end
166
+ end
167
+ end
168
+
169
+ def resolved_env_for_command
170
+ warn_on_legacy_env_vars!
171
+
172
+ resolved_env = {}
173
+
174
+ resolved_env['TERM'] = PDK::Util::Env['TERM']
175
+ resolved_env['PUPPET_GEM_VERSION'] = nil
176
+ resolved_env['FACTER_GEM_VERSION'] = nil
177
+ resolved_env['HIERA_GEM_VERSION'] = nil
178
+
179
+ resolved_env.merge!(@environment.dup)
180
+
181
+ resolved_env['BUNDLE_IGNORE_CONFIG'] = '1'
182
+
183
+ if [:module, :pwd].include?(context)
184
+ require 'pdk/util'
185
+ require 'pdk/util/git'
186
+ require 'pdk/util/ruby_version'
187
+
188
+ resolved_env['GEM_HOME'] = PDK::Util::RubyVersion.gem_home
189
+ gem_path = PDK::Util::RubyVersion.gem_path
190
+ resolved_env['GEM_PATH'] = gem_path.empty? ? resolved_env['GEM_HOME'] : gem_path
191
+
192
+ # Make sure invocation of Ruby prefers our private installation.
193
+ package_binpath = PDK::Util.package_install? ? File.join(PDK::Util.pdk_package_basedir, 'bin') : nil
194
+
195
+ resolved_env['PATH'] = [
196
+ PDK::Util::RubyVersion.bin_path,
197
+ File.join(resolved_env['GEM_HOME'], 'bin'),
198
+ PDK::Util::RubyVersion.gem_paths_raw.map { |gem_path_raw| File.join(gem_path_raw, 'bin') },
199
+ package_binpath,
200
+ PDK::Util.package_install? ? PDK::Util::Git.git_paths : nil,
201
+ PDK::Util::Env['PATH'],
202
+ ].compact.flatten.join(File::PATH_SEPARATOR)
203
+ end
204
+
205
+ resolved_env
206
+ end
207
+
208
+ def stop_spinner
209
+ return unless @spinner
210
+
211
+ # If it is a single spinner, we need to send it a success/error message
212
+ if @process.exit_code.zero?
213
+ @spinner.success(@success_message || '')
214
+ else
215
+ @spinner.error(@failure_message || '')
216
+ end
217
+ end
218
+
219
+ def run_process_in_clean_env!
220
+ require 'bundler'
221
+
222
+ # Bundler 2.1.0 has deprecated the use of `Bundler.with_clean_env` in favour of
223
+ # `Bundler.with_unbundled_env`. So prefer to use the newer method if it exists
224
+ # otherwise revert back to the old method.
225
+ if ::Bundler.respond_to?(:with_unbundled_env)
226
+ run_process_with_unbundled_env!
227
+ else
228
+ run_process_with_clean_env!
229
+ end
230
+ end
231
+
232
+ def run_process!
233
+ command_string = argv.join(' ')
234
+
235
+ PDK.logger.debug(_("Executing '%{command}'") % { command: command_string })
236
+
237
+ if context == :module
238
+ PDK.logger.debug(_('Command environment:'))
239
+ @process.environment.each do |var, val|
240
+ PDK.logger.debug(" #{var}: #{val}")
241
+ end
242
+ end
243
+
244
+ start_time = Time.now
245
+
246
+ begin
247
+ @process.start
248
+ rescue ChildProcess::LaunchError => e
249
+ raise PDK::CLI::FatalError, _("Failed to execute '%{command}': %{message}") % { command: command_string, message: e.message }
250
+ end
251
+
252
+ if timeout
253
+ begin
254
+ @process.poll_for_exit(timeout)
255
+ rescue ChildProcess::TimeoutError
256
+ @process.stop # tries increasingly harsher methods to kill the process.
257
+ end
258
+ else
259
+ # Wait indfinitely if no timeout set.
260
+ @process.wait
261
+ end
262
+
263
+ @duration = Time.now - start_time
264
+
265
+ PDK.logger.debug(_("Execution of '%{command}' complete (duration: %{duration_in_seconds}s; exit code: %{exit_code})") %
266
+ { command: command_string, duration_in_seconds: @duration, exit_code: @process.exit_code })
267
+ end
268
+
269
+ private
270
+
271
+ #:nocov:
272
+ # These are just bundler helper methods and are tested via the public run_process_in_clean_env! method
273
+ def run_process_with_unbundled_env!
274
+ # Bundler 2.1.0 or greater
275
+ ::Bundler.with_unbundled_env do
276
+ run_process!
277
+ end
278
+ end
279
+ #:nocov:
280
+
281
+ #:nocov:
282
+ # These are just bundler helper methods and are tested via the public run_process_in_clean_env! method
283
+ def run_process_with_clean_env!
284
+ # Bundler 2.0.2 or less
285
+ ::Bundler.with_clean_env do
286
+ run_process!
287
+ end
288
+ end
289
+ #:nocov:
290
+ end
291
+ end
292
+ end
293
+ end