pdk 1.9.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +744 -711
- data/README.md +23 -21
- data/lib/pdk/answer_file.rb +3 -112
- data/lib/pdk/bolt.rb +20 -0
- data/lib/pdk/cli/build.rb +51 -54
- data/lib/pdk/cli/bundle.rb +33 -29
- data/lib/pdk/cli/console.rb +148 -0
- data/lib/pdk/cli/convert.rb +46 -37
- data/lib/pdk/cli/env.rb +51 -0
- data/lib/pdk/cli/errors.rb +4 -3
- data/lib/pdk/cli/exec/command.rb +285 -0
- data/lib/pdk/cli/exec/interactive_command.rb +109 -0
- data/lib/pdk/cli/exec.rb +32 -201
- data/lib/pdk/cli/exec_group.rb +79 -43
- data/lib/pdk/cli/get/config.rb +26 -0
- data/lib/pdk/cli/get.rb +22 -0
- data/lib/pdk/cli/new/class.rb +20 -22
- data/lib/pdk/cli/new/defined_type.rb +21 -21
- data/lib/pdk/cli/new/fact.rb +27 -0
- data/lib/pdk/cli/new/function.rb +27 -0
- data/lib/pdk/cli/new/module.rb +40 -29
- data/lib/pdk/cli/new/provider.rb +18 -18
- data/lib/pdk/cli/new/task.rb +23 -22
- data/lib/pdk/cli/new/test.rb +52 -0
- data/lib/pdk/cli/new/transport.rb +27 -0
- data/lib/pdk/cli/new.rb +15 -9
- data/lib/pdk/cli/release/prep.rb +39 -0
- data/lib/pdk/cli/release/publish.rb +46 -0
- data/lib/pdk/cli/release.rb +185 -0
- data/lib/pdk/cli/remove/config.rb +83 -0
- data/lib/pdk/cli/remove.rb +22 -0
- data/lib/pdk/cli/set/config.rb +121 -0
- data/lib/pdk/cli/set.rb +22 -0
- data/lib/pdk/cli/test/unit.rb +71 -69
- data/lib/pdk/cli/test.rb +9 -8
- data/lib/pdk/cli/update.rb +38 -21
- data/lib/pdk/cli/util/command_redirector.rb +13 -3
- data/lib/pdk/cli/util/interview.rb +25 -9
- data/lib/pdk/cli/util/option_normalizer.rb +6 -6
- data/lib/pdk/cli/util/option_validator.rb +19 -9
- data/lib/pdk/cli/util/spinner.rb +13 -0
- data/lib/pdk/cli/util/update_manager_printer.rb +82 -0
- data/lib/pdk/cli/util.rb +105 -48
- data/lib/pdk/cli/validate.rb +96 -111
- data/lib/pdk/cli.rb +134 -87
- data/lib/pdk/config/errors.rb +5 -0
- data/lib/pdk/config/ini_file.rb +184 -0
- data/lib/pdk/config/ini_file_setting.rb +35 -0
- data/lib/pdk/config/json.rb +35 -0
- data/lib/pdk/config/json_schema_namespace.rb +137 -0
- data/lib/pdk/config/json_schema_setting.rb +51 -0
- data/lib/pdk/config/json_with_schema.rb +47 -0
- data/lib/pdk/config/namespace.rb +362 -0
- data/lib/pdk/config/setting.rb +134 -0
- data/lib/pdk/config/task_schema.json +116 -0
- data/lib/pdk/config/validator.rb +31 -0
- data/lib/pdk/config/yaml.rb +41 -0
- data/lib/pdk/config/yaml_with_schema.rb +51 -0
- data/lib/pdk/config.rb +304 -0
- data/lib/pdk/context/control_repo.rb +61 -0
- data/lib/pdk/context/module.rb +28 -0
- data/lib/pdk/context/none.rb +22 -0
- data/lib/pdk/context.rb +98 -0
- data/lib/pdk/control_repo.rb +89 -0
- data/lib/pdk/generate/defined_type.rb +27 -33
- data/lib/pdk/generate/fact.rb +26 -0
- data/lib/pdk/generate/function.rb +49 -0
- data/lib/pdk/generate/module.rb +160 -153
- data/lib/pdk/generate/provider.rb +16 -69
- data/lib/pdk/generate/puppet_class.rb +27 -32
- data/lib/pdk/generate/puppet_object.rb +100 -159
- data/lib/pdk/generate/task.rb +34 -51
- data/lib/pdk/generate/transport.rb +34 -0
- data/lib/pdk/generate.rb +21 -8
- data/lib/pdk/logger.rb +24 -6
- data/lib/pdk/module/build.rb +125 -37
- data/lib/pdk/module/convert.rb +146 -65
- data/lib/pdk/module/metadata.rb +72 -71
- data/lib/pdk/module/release.rb +255 -0
- data/lib/pdk/module/update.rb +48 -37
- data/lib/pdk/module/update_manager.rb +75 -39
- data/lib/pdk/module.rb +10 -2
- data/lib/pdk/monkey_patches.rb +268 -0
- data/lib/pdk/report/event.rb +36 -48
- data/lib/pdk/report.rb +35 -22
- data/lib/pdk/template/fetcher/git.rb +84 -0
- data/lib/pdk/template/fetcher/local.rb +29 -0
- data/lib/pdk/template/fetcher.rb +100 -0
- data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +108 -0
- data/lib/pdk/template/renderer/v1/renderer.rb +131 -0
- data/lib/pdk/template/renderer/v1/template_file.rb +100 -0
- data/lib/pdk/template/renderer/v1.rb +25 -0
- data/lib/pdk/template/renderer.rb +97 -0
- data/lib/pdk/template/template_dir.rb +67 -0
- data/lib/pdk/template.rb +52 -0
- data/lib/pdk/tests/unit.rb +101 -51
- data/lib/pdk/util/bundler.rb +44 -42
- data/lib/pdk/util/changelog_generator.rb +138 -0
- data/lib/pdk/util/env.rb +48 -0
- data/lib/pdk/util/filesystem.rb +139 -2
- data/lib/pdk/util/git.rb +108 -8
- data/lib/pdk/util/json_finder.rb +86 -0
- data/lib/pdk/util/puppet_strings.rb +125 -0
- data/lib/pdk/util/puppet_version.rb +71 -87
- data/lib/pdk/util/ruby_version.rb +49 -25
- data/lib/pdk/util/template_uri.rb +283 -0
- data/lib/pdk/util/vendored_file.rb +34 -42
- data/lib/pdk/util/version.rb +11 -10
- data/lib/pdk/util/windows/api_types.rb +74 -44
- data/lib/pdk/util/windows/file.rb +31 -27
- data/lib/pdk/util/windows/process.rb +74 -0
- data/lib/pdk/util/windows/string.rb +19 -12
- data/lib/pdk/util/windows.rb +2 -0
- data/lib/pdk/util.rb +111 -124
- data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -0
- data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -0
- data/lib/pdk/validate/external_command_validator.rb +213 -0
- data/lib/pdk/validate/internal_ruby_validator.rb +101 -0
- data/lib/pdk/validate/invokable_validator.rb +238 -0
- data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +84 -0
- data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +76 -0
- data/lib/pdk/validate/metadata/metadata_validator_group.rb +20 -0
- data/lib/pdk/validate/puppet/puppet_epp_validator.rb +131 -0
- data/lib/pdk/validate/puppet/puppet_lint_validator.rb +66 -0
- data/lib/pdk/validate/puppet/puppet_plan_syntax_validator.rb +38 -0
- data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +135 -0
- data/lib/pdk/validate/puppet/puppet_validator_group.rb +22 -0
- data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +79 -0
- data/lib/pdk/validate/ruby/ruby_validator_group.rb +19 -0
- data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +83 -0
- data/lib/pdk/validate/tasks/tasks_name_validator.rb +45 -0
- data/lib/pdk/validate/tasks/tasks_validator_group.rb +20 -0
- data/lib/pdk/validate/validator.rb +120 -0
- data/lib/pdk/validate/validator_group.rb +107 -0
- data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +86 -0
- data/lib/pdk/validate/yaml/yaml_validator_group.rb +19 -0
- data/lib/pdk/validate.rb +86 -12
- data/lib/pdk/version.rb +2 -2
- data/lib/pdk.rb +60 -10
- metadata +138 -100
- data/lib/pdk/cli/module/build.rb +0 -14
- data/lib/pdk/cli/module/generate.rb +0 -45
- data/lib/pdk/cli/module.rb +0 -14
- data/lib/pdk/i18n.rb +0 -4
- data/lib/pdk/module/templatedir.rb +0 -321
- data/lib/pdk/template_file.rb +0 -95
- data/lib/pdk/validate/base_validator.rb +0 -215
- data/lib/pdk/validate/metadata/metadata_json_lint.rb +0 -86
- data/lib/pdk/validate/metadata/metadata_syntax.rb +0 -109
- data/lib/pdk/validate/metadata_validator.rb +0 -30
- data/lib/pdk/validate/puppet/puppet_lint.rb +0 -67
- data/lib/pdk/validate/puppet/puppet_syntax.rb +0 -112
- data/lib/pdk/validate/puppet_validator.rb +0 -30
- data/lib/pdk/validate/ruby/rubocop.rb +0 -77
- data/lib/pdk/validate/ruby_validator.rb +0 -29
- data/lib/pdk/validate/tasks/metadata_lint.rb +0 -126
- data/lib/pdk/validate/tasks/name.rb +0 -88
- data/lib/pdk/validate/tasks_validator.rb +0 -33
- data/lib/pdk/validate/yaml/syntax.rb +0 -109
- data/lib/pdk/validate/yaml_validator.rb +0 -31
- data/locales/config.yaml +0 -21
- data/locales/pdk.pot +0 -1291
data/lib/pdk/cli/env.rb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module PDK
|
|
2
|
+
module CLI
|
|
3
|
+
@env_cmd = @base_cmd.define_command do
|
|
4
|
+
name 'env'
|
|
5
|
+
usage 'env'
|
|
6
|
+
summary '(Experimental) Output environment variables for specific Puppet context'
|
|
7
|
+
description <<~EOF
|
|
8
|
+
[experimental] Aids in setting a CLI context for a specified version of Puppet by outputting export commands for necessary environment variables.
|
|
9
|
+
EOF
|
|
10
|
+
|
|
11
|
+
PDK::CLI.puppet_version_options(self)
|
|
12
|
+
PDK::CLI.puppet_dev_option(self)
|
|
13
|
+
|
|
14
|
+
run do |opts, _args, _cmd|
|
|
15
|
+
require 'pdk/util'
|
|
16
|
+
require 'pdk/util/ruby_version'
|
|
17
|
+
|
|
18
|
+
PDK::CLI::Util.validate_puppet_version_opts(opts)
|
|
19
|
+
|
|
20
|
+
# Ensure that the correct Ruby is activated before running command.
|
|
21
|
+
puppet_env = PDK::CLI::Util.puppet_from_opts_or_env(opts)
|
|
22
|
+
PDK::Util::RubyVersion.use(puppet_env[:ruby_version])
|
|
23
|
+
|
|
24
|
+
resolved_env = {
|
|
25
|
+
'PDK_RESOLVED_PUPPET_VERSION' => puppet_env[:gemset][:puppet],
|
|
26
|
+
'PDK_RESOLVED_RUBY_VERSION' => puppet_env[:ruby_version]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
resolved_env['GEM_HOME'] = PDK::Util::RubyVersion.gem_home
|
|
30
|
+
gem_path = PDK::Util::RubyVersion.gem_path
|
|
31
|
+
resolved_env['GEM_PATH'] = gem_path.empty? ? resolved_env['GEM_HOME'] : gem_path
|
|
32
|
+
|
|
33
|
+
# Make sure invocation of Ruby prefers our private installation.
|
|
34
|
+
package_binpath = PDK::Util.package_install? ? File.join(PDK::Util.pdk_package_basedir, 'bin') : nil
|
|
35
|
+
|
|
36
|
+
resolved_env['PATH'] = [
|
|
37
|
+
PDK::Util::RubyVersion.bin_path,
|
|
38
|
+
File.join(resolved_env['GEM_HOME'], 'bin'),
|
|
39
|
+
PDK::Util::RubyVersion.gem_paths_raw.map { |gem_path_raw| File.join(gem_path_raw, 'bin') },
|
|
40
|
+
package_binpath,
|
|
41
|
+
PDK::Util::Env['PATH']
|
|
42
|
+
].compact.flatten.join(File::PATH_SEPARATOR)
|
|
43
|
+
|
|
44
|
+
resolved_env.each do |var, val|
|
|
45
|
+
puts "export #{var}=\"#{val}\""
|
|
46
|
+
end
|
|
47
|
+
exit 0
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/pdk/cli/errors.rb
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
+
require 'pdk'
|
|
2
|
+
|
|
1
3
|
module PDK
|
|
2
4
|
module CLI
|
|
3
5
|
class FatalError < StandardError
|
|
4
6
|
attr_reader :exit_code
|
|
5
7
|
|
|
6
|
-
def initialize(msg =
|
|
8
|
+
def initialize(msg = 'An unexpected error has occurred. Try running the command again with --debug', opts = {})
|
|
7
9
|
@exit_code = opts.fetch(:exit_code, 1)
|
|
8
10
|
super(msg)
|
|
9
11
|
end
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
class ExitWithError < StandardError
|
|
13
|
-
attr_reader :exit_code
|
|
14
|
-
attr_reader :log_level
|
|
15
|
+
attr_reader :exit_code, :log_level
|
|
15
16
|
|
|
16
17
|
def initialize(msg, opts = {})
|
|
17
18
|
@exit_code = opts.fetch(:exit_code, 1)
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
require 'pdk'
|
|
2
|
+
|
|
3
|
+
module PDK
|
|
4
|
+
module CLI
|
|
5
|
+
module Exec
|
|
6
|
+
class Command
|
|
7
|
+
attr_reader :argv, :context
|
|
8
|
+
attr_accessor :timeout, :environment
|
|
9
|
+
attr_writer :exec_group
|
|
10
|
+
|
|
11
|
+
# The spinner for this command.
|
|
12
|
+
# This should only be used for testing
|
|
13
|
+
#
|
|
14
|
+
# @return [TTY::Spinner, nil]
|
|
15
|
+
#
|
|
16
|
+
# @api private
|
|
17
|
+
attr_reader :spinner
|
|
18
|
+
|
|
19
|
+
TEMPFILE_MODE = File::RDWR | File::BINARY | File::CREAT | File::TRUNC
|
|
20
|
+
|
|
21
|
+
def initialize(*argv)
|
|
22
|
+
require 'childprocess'
|
|
23
|
+
|
|
24
|
+
require 'pdk/monkey_patches'
|
|
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
|
+
raise ArgumentError, format("Expected execution context to be :system or :module but got '%{context}'.", context: new_context) unless [:system, :module, :pwd].include?(new_context)
|
|
60
|
+
|
|
61
|
+
@context = new_context
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def register_spinner(spinner, opts = {})
|
|
65
|
+
require 'pdk/cli/util'
|
|
66
|
+
|
|
67
|
+
return unless PDK::CLI::Util.interactive?
|
|
68
|
+
|
|
69
|
+
@success_message = opts.delete(:success)
|
|
70
|
+
@failure_message = opts.delete(:failure)
|
|
71
|
+
|
|
72
|
+
@spinner = spinner
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def add_spinner(message, opts = {})
|
|
76
|
+
require 'pdk/cli/util'
|
|
77
|
+
|
|
78
|
+
return unless PDK::CLI::Util.interactive?
|
|
79
|
+
|
|
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
|
|
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
|
|
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 format('STDOUT: %{output}', output: process_data[:stdout].empty? ? 'N/A' : "\n#{process_data[:stdout]}")
|
|
139
|
+
PDK.logger.debug format('STDERR: %{output}', output: process_data[:stderr].empty? ? 'N/A' : "\n#{process_data[:stderr]}")
|
|
140
|
+
|
|
141
|
+
process_data
|
|
142
|
+
ensure
|
|
143
|
+
@stdout.close
|
|
144
|
+
@stderr.close
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
protected
|
|
148
|
+
|
|
149
|
+
def warn_on_legacy_env_vars!
|
|
150
|
+
if PDK::Util::Env['PUPPET_GEM_VERSION']
|
|
151
|
+
PDK.logger.warn_once 'PUPPET_GEM_VERSION is not supported by PDK. ' \
|
|
152
|
+
'Use the --puppet-version option on your PDK command ' \
|
|
153
|
+
'or set the PDK_PUPPET_VERSION environment variable instead'
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
['FACTER', 'HIERA'].each do |gem|
|
|
157
|
+
PDK.logger.warn_once format('%{varname} is not supported by PDK.', varname: "#{gem}_GEM_VERSION") if PDK::Util::Env["#{gem}_GEM_VERSION"]
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def resolved_env_for_command
|
|
162
|
+
warn_on_legacy_env_vars!
|
|
163
|
+
|
|
164
|
+
resolved_env = {}
|
|
165
|
+
|
|
166
|
+
resolved_env['TERM'] = PDK::Util::Env['TERM']
|
|
167
|
+
resolved_env['PUPPET_GEM_VERSION'] = nil
|
|
168
|
+
resolved_env['FACTER_GEM_VERSION'] = nil
|
|
169
|
+
resolved_env['HIERA_GEM_VERSION'] = nil
|
|
170
|
+
|
|
171
|
+
resolved_env.merge!(@environment.dup)
|
|
172
|
+
|
|
173
|
+
resolved_env['BUNDLE_IGNORE_CONFIG'] = '1'
|
|
174
|
+
|
|
175
|
+
if [:module, :pwd].include?(context)
|
|
176
|
+
require 'pdk/util'
|
|
177
|
+
require 'pdk/util/git'
|
|
178
|
+
require 'pdk/util/ruby_version'
|
|
179
|
+
|
|
180
|
+
resolved_env['GEM_HOME'] = PDK::Util::RubyVersion.gem_home
|
|
181
|
+
gem_path = PDK::Util::RubyVersion.gem_path
|
|
182
|
+
resolved_env['GEM_PATH'] = gem_path.empty? ? resolved_env['GEM_HOME'] : gem_path
|
|
183
|
+
|
|
184
|
+
# Make sure invocation of Ruby prefers our private installation.
|
|
185
|
+
package_binpath = PDK::Util.package_install? ? File.join(PDK::Util.pdk_package_basedir, 'bin') : nil
|
|
186
|
+
|
|
187
|
+
resolved_env['PATH'] = [
|
|
188
|
+
PDK::Util::RubyVersion.bin_path,
|
|
189
|
+
File.join(resolved_env['GEM_HOME'], 'bin'),
|
|
190
|
+
PDK::Util::RubyVersion.gem_paths_raw.map { |gem_path_raw| File.join(gem_path_raw, 'bin') },
|
|
191
|
+
package_binpath,
|
|
192
|
+
PDK::Util.package_install? ? PDK::Util::Git.git_paths : nil,
|
|
193
|
+
PDK::Util::Env['PATH']
|
|
194
|
+
].compact.flatten.join(File::PATH_SEPARATOR)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
resolved_env
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def stop_spinner
|
|
201
|
+
return unless @spinner
|
|
202
|
+
|
|
203
|
+
# If it is a single spinner, we need to send it a success/error message
|
|
204
|
+
if @process.exit_code.zero?
|
|
205
|
+
@spinner.success(@success_message || '')
|
|
206
|
+
else
|
|
207
|
+
@spinner.error(@failure_message || '')
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def run_process_in_clean_env!
|
|
212
|
+
require 'bundler'
|
|
213
|
+
|
|
214
|
+
# Bundler 2.1.0 has deprecated the use of `Bundler.with_clean_env` in favour of
|
|
215
|
+
# `Bundler.with_unbundled_env`. So prefer to use the newer method if it exists
|
|
216
|
+
# otherwise revert back to the old method.
|
|
217
|
+
if ::Bundler.respond_to?(:with_unbundled_env)
|
|
218
|
+
run_process_with_unbundled_env!
|
|
219
|
+
else
|
|
220
|
+
run_process_with_clean_env!
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def run_process!
|
|
225
|
+
command_string = argv.join(' ')
|
|
226
|
+
|
|
227
|
+
PDK.logger.debug(format("Executing '%{command}'", command: command_string))
|
|
228
|
+
|
|
229
|
+
if context == :module
|
|
230
|
+
PDK.logger.debug('Command environment:')
|
|
231
|
+
@process.environment.each do |var, val|
|
|
232
|
+
PDK.logger.debug(" #{var}: #{val}")
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
start_time = Time.now
|
|
237
|
+
|
|
238
|
+
begin
|
|
239
|
+
@process.start
|
|
240
|
+
rescue ChildProcess::LaunchError => e
|
|
241
|
+
raise PDK::CLI::FatalError, format("Failed to execute '%{command}': %{message}", command: command_string, message: e.message)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
if timeout
|
|
245
|
+
begin
|
|
246
|
+
@process.poll_for_exit(timeout)
|
|
247
|
+
rescue ChildProcess::TimeoutError
|
|
248
|
+
@process.stop # tries increasingly harsher methods to kill the process.
|
|
249
|
+
end
|
|
250
|
+
else
|
|
251
|
+
# Wait indfinitely if no timeout set.
|
|
252
|
+
@process.wait
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
@duration = Time.now - start_time
|
|
256
|
+
|
|
257
|
+
PDK.logger.debug(format("Execution of '%{command}' complete (duration: %{duration_in_seconds}s; exit code: %{exit_code})", command: command_string, duration_in_seconds: @duration,
|
|
258
|
+
exit_code: @process.exit_code))
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
private
|
|
262
|
+
|
|
263
|
+
# :nocov:
|
|
264
|
+
# These are just bundler helper methods and are tested via the public run_process_in_clean_env! method
|
|
265
|
+
def run_process_with_unbundled_env!
|
|
266
|
+
# Bundler 2.1.0 or greater
|
|
267
|
+
::Bundler.with_unbundled_env do
|
|
268
|
+
run_process!
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
# :nocov:
|
|
272
|
+
|
|
273
|
+
# :nocov:
|
|
274
|
+
# These are just bundler helper methods and are tested via the public run_process_in_clean_env! method
|
|
275
|
+
def run_process_with_clean_env!
|
|
276
|
+
# Bundler 2.0.2 or less
|
|
277
|
+
::Bundler.with_clean_env do
|
|
278
|
+
run_process!
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
# :nocov:
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
require 'pdk'
|
|
2
|
+
|
|
3
|
+
module PDK
|
|
4
|
+
module CLI
|
|
5
|
+
module Exec
|
|
6
|
+
class InteractiveCommand < Command
|
|
7
|
+
# rubocop :disable Lint/MissingSuper
|
|
8
|
+
def initialize(*argv)
|
|
9
|
+
@argv = argv
|
|
10
|
+
|
|
11
|
+
# Default to running things in the system context.
|
|
12
|
+
@context = :system
|
|
13
|
+
|
|
14
|
+
# Extra environment vars to add to base set.
|
|
15
|
+
@environment = {}
|
|
16
|
+
end
|
|
17
|
+
# rubocop :enable Lint/MissingSuper
|
|
18
|
+
|
|
19
|
+
def register_spinner(_spinner, _opts = {})
|
|
20
|
+
raise 'This method is not implemented for PDK::CLI::Exec::InteractiveCommand'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def add_spinner(_message, _opts = {})
|
|
24
|
+
raise 'This method is not implemented for PDK::CLI::Exec::InteractiveCommand'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def timeout
|
|
28
|
+
raise 'This method is not implemented for PDK::CLI::Exec::InteractiveCommand'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def timeout=(_val)
|
|
32
|
+
raise 'This method is not implemented for PDK::CLI::Exec::InteractiveCommand'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def exec_group=(_val)
|
|
36
|
+
raise 'This method is not implemented for PDK::CLI::Exec::InteractiveCommand'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def execute!
|
|
40
|
+
require 'pdk/util'
|
|
41
|
+
|
|
42
|
+
@resolved_env = resolved_env_for_command
|
|
43
|
+
|
|
44
|
+
if [:module, :pwd].include?(context)
|
|
45
|
+
mod_root = PDK::Util.module_root
|
|
46
|
+
|
|
47
|
+
raise PDK::CLI::FatalError, 'Current working directory is not part of a module. (No metadata.json was found.)' unless mod_root
|
|
48
|
+
|
|
49
|
+
unless context == :pwd || Dir.pwd == mod_root
|
|
50
|
+
orig_workdir = Dir.pwd
|
|
51
|
+
Dir.chdir(mod_root)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
result = run_process_in_clean_env!
|
|
55
|
+
else
|
|
56
|
+
result = run_process!
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
{
|
|
60
|
+
interactive: true,
|
|
61
|
+
stdout: nil,
|
|
62
|
+
stderr: nil,
|
|
63
|
+
exit_code: result[:exit_code],
|
|
64
|
+
duration: result[:duration]
|
|
65
|
+
}
|
|
66
|
+
ensure
|
|
67
|
+
Dir.chdir(orig_workdir) if orig_workdir
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
protected
|
|
71
|
+
|
|
72
|
+
# TODO: debug logging
|
|
73
|
+
def run_process!
|
|
74
|
+
command_string = argv.join(' ')
|
|
75
|
+
PDK.logger.debug(format("Executing '%{command}' interactively", command: command_string))
|
|
76
|
+
|
|
77
|
+
if context == :module
|
|
78
|
+
PDK.logger.debug('Command environment:')
|
|
79
|
+
@resolved_env.each do |var, val|
|
|
80
|
+
PDK.logger.debug(" #{var}: #{val}")
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
start_time = Time.now
|
|
85
|
+
|
|
86
|
+
system(@resolved_env, *argv)
|
|
87
|
+
|
|
88
|
+
exit_code = child_status.exitstatus
|
|
89
|
+
duration = Time.now - start_time
|
|
90
|
+
|
|
91
|
+
PDK.logger.debug(format("Execution of '%{command}' complete (duration: \
|
|
92
|
+
%{duration_in_seconds}s; exit code: %{exit_code})", command: command_string, exit_code: exit_code, duration_in_seconds: duration))
|
|
93
|
+
|
|
94
|
+
{ exit_code: exit_code, duration: duration }
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def child_status
|
|
98
|
+
require 'English'
|
|
99
|
+
|
|
100
|
+
$CHILD_STATUS
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def stop_spinner
|
|
104
|
+
raise 'This method is not implemented for PDK::CLI::Exec::InteractiveCommand'
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|