r10k 1.2.0 → 1.2.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.
- checksums.yaml +8 -8
- data/CHANGELOG +19 -0
- data/README.markdown +9 -5
- data/lib/r10k/cli.rb +1 -0
- data/lib/r10k/cli/deploy.rb +13 -0
- data/lib/r10k/cli/help.rb +7 -0
- data/lib/r10k/cli/puppetfile.rb +1 -1
- data/lib/r10k/util/platform.rb +19 -0
- data/lib/r10k/util/subprocess.rb +47 -43
- data/lib/r10k/util/subprocess/io.rb +0 -5
- data/lib/r10k/util/subprocess/posix.rb +4 -0
- data/lib/r10k/util/subprocess/posix/io.rb +7 -0
- data/lib/r10k/util/subprocess/posix/runner.rb +113 -0
- data/lib/r10k/util/subprocess/runner.rb +23 -61
- data/lib/r10k/util/subprocess/windows.rb +4 -0
- data/lib/r10k/util/subprocess/windows/io.rb +6 -0
- data/lib/r10k/util/subprocess/windows/runner.rb +32 -0
- data/lib/r10k/version.rb +1 -1
- data/r10k.gemspec +1 -1
- data/spec/unit/util/subprocess_spec.rb +65 -0
- metadata +14 -4
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NzM2NDQyNzM1Y2I0Zjc5ZmUzNmEyZDA0MTJiMzZjM2E2MWNhNWJhMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NmRkYWZiZDYxNGEyNTZiZDgzZDQwMjEzYjQ0MjA2MjgxNjE0MjRlMw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YWE2ZTg3ZDI1YzA4YTlkNTFlNjQ2MDIzZDU1YWNjZGExMjY3NTY5NGRhN2Fm
|
10
|
+
MTNhNDA4NzY1YTNkODM4ZjQ4NTI4ZmRiOTEwNDIwZWYwOWNiN2VhZWE3M2My
|
11
|
+
NDE4MGY0M2ZiZjcyOGI2Y2UyNWU5ZWRjNjlhZGJkZDc4ZjZlMGY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NzM5YmU2ODRlNzg2NGEzMzQ3NjBmODIzYzE4MmUzM2NkYmRmYmExOTBhMWNk
|
14
|
+
NGNhMjI5Njc3MGEyNWVjYjg3NTNmMjJkOTY0ZTAzMDM3NzQ5YzhlYjlhZDI0
|
15
|
+
Yzg5MDQ0MDNlNmI5NjlhNGQwZTRiMGRhM2ZkNDI3MWM4Zjk2OGQ=
|
data/CHANGELOG
CHANGED
@@ -1,6 +1,25 @@
|
|
1
1
|
CHANGELOG
|
2
2
|
=========
|
3
3
|
|
4
|
+
1.2.1
|
5
|
+
-----
|
6
|
+
|
7
|
+
2014/04/21
|
8
|
+
|
9
|
+
### User Notes
|
10
|
+
|
11
|
+
(GH-93) r10k deploy subcommands now respect the --help flag.
|
12
|
+
|
13
|
+
(GH-100) The addition of a faster command execution library was POSIX centric,
|
14
|
+
but there were a number of users that were running r10k on Windows, which brike
|
15
|
+
their environments. Support for Windows has been re-added and Windows is now a
|
16
|
+
supported platform for using the r10k puppetfile commands. Please note that
|
17
|
+
r10k now requires Ruby 1.9.3 on Windows to function.
|
18
|
+
|
19
|
+
### Thanks
|
20
|
+
|
21
|
+
Thanks to Sam Kottler and Daniel Dreier for their their work on this release.
|
22
|
+
|
4
23
|
1.2.0
|
5
24
|
-----
|
6
25
|
|
data/README.markdown
CHANGED
@@ -18,15 +18,19 @@ implementation of Puppet [dynamic environments][workflow].
|
|
18
18
|
Installation
|
19
19
|
------------
|
20
20
|
|
21
|
-
r10k
|
22
|
-
|
21
|
+
r10k supports the following Ruby versions:
|
22
|
+
|
23
|
+
- 1.8.7 (POSIX minimum version)
|
24
|
+
- 1.9.3 (Windows minimum version)
|
25
|
+
- 2.0.0
|
26
|
+
- 2.1.0
|
23
27
|
|
24
28
|
### Rubygems
|
25
29
|
|
26
30
|
For general use, you should install r10k from Ruby gems:
|
27
31
|
|
28
32
|
gem install r10k
|
29
|
-
r10k
|
33
|
+
r10k help
|
30
34
|
|
31
35
|
### Bundler
|
32
36
|
|
@@ -36,14 +40,14 @@ a git repository using Bundler for dependencies:
|
|
36
40
|
git clone git://github.com/adrienthebo/r10k
|
37
41
|
cd r10k
|
38
42
|
bundle install
|
39
|
-
bundle exec r10k
|
43
|
+
bundle exec r10k help
|
40
44
|
|
41
45
|
### Puppet Enterprise
|
42
46
|
|
43
47
|
Puppet Enterprise uses its own Ruby, so you need to use the correct version of gem when installing r10k.
|
44
48
|
|
45
49
|
/opt/puppet/bin/gem install r10k
|
46
|
-
r10k
|
50
|
+
r10k help
|
47
51
|
|
48
52
|
Common Commands
|
49
53
|
---------------
|
data/lib/r10k/cli.rb
CHANGED
data/lib/r10k/cli/deploy.rb
CHANGED
@@ -51,6 +51,10 @@ scheduled. On subsequent deployments, Puppetfile deployment will default to off.
|
|
51
51
|
DESCRIPTION
|
52
52
|
|
53
53
|
flag :p, :puppetfile, 'Deploy modules from a puppetfile'
|
54
|
+
flag :h, :help, 'Show help for this command' do |value, cmd|
|
55
|
+
puts cmd.help
|
56
|
+
exit 0
|
57
|
+
end
|
54
58
|
|
55
59
|
run do |opts, args, cmd|
|
56
60
|
deploy = R10K::Deployment.load_config(opts[:config])
|
@@ -86,6 +90,11 @@ It will load the Puppetfile configurations out of all environments, and will
|
|
86
90
|
try to deploy the given module names in all environments.
|
87
91
|
DESCRIPTION
|
88
92
|
|
93
|
+
flag :h, :help, 'Show help for this command' do |value, cmd|
|
94
|
+
puts cmd.help
|
95
|
+
exit 0
|
96
|
+
end
|
97
|
+
|
89
98
|
run do |opts, args, cmd|
|
90
99
|
deploy = R10K::Deployment.load_config(opts[:config])
|
91
100
|
|
@@ -111,6 +120,10 @@ try to deploy the given module names in all environments.
|
|
111
120
|
summary 'Display environments and modules in the deployment'
|
112
121
|
|
113
122
|
flag :p, :puppetfile, 'Display Puppetfile modules'
|
123
|
+
flag :h, :help, 'Show help for this command' do |value, cmd|
|
124
|
+
puts cmd.help
|
125
|
+
exit 0
|
126
|
+
end
|
114
127
|
|
115
128
|
run do |opts, args, cmd|
|
116
129
|
deploy = R10K::Deployment.load_config(opts[:config])
|
data/lib/r10k/cli/puppetfile.rb
CHANGED
@@ -59,7 +59,7 @@ Puppetfile (http://bombasticmonkey.com/librarian-puppet/).
|
|
59
59
|
puppetfile_root = Dir.getwd
|
60
60
|
puppetfile_path = ENV['PUPPETFILE_DIR']
|
61
61
|
puppetfile = ENV['PUPPETFILE']
|
62
|
-
|
62
|
+
|
63
63
|
puppetfile = R10K::Puppetfile.new(puppetfile_root, puppetfile_path, puppetfile)
|
64
64
|
begin
|
65
65
|
puppetfile.load
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
module R10K
|
4
|
+
module Util
|
5
|
+
module Platform
|
6
|
+
def self.platform
|
7
|
+
if self.windows?
|
8
|
+
:windows
|
9
|
+
else
|
10
|
+
:posix
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.windows?
|
15
|
+
RbConfig::CONFIG['host_os'] =~ /mswin|win32|dos|mingw|cygwin/i
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/r10k/util/subprocess.rb
CHANGED
@@ -1,54 +1,81 @@
|
|
1
1
|
require 'r10k/logging'
|
2
2
|
require 'r10k/errors'
|
3
|
+
require 'r10k/util/platform'
|
3
4
|
|
4
5
|
module R10K
|
5
6
|
module Util
|
6
7
|
|
7
|
-
# The subprocess namespace implements
|
8
|
-
#
|
8
|
+
# The subprocess namespace implements an interface similar to childprocess.
|
9
|
+
# The interface has been simplified to make it easier to use and does not
|
10
|
+
# depend on native code.
|
9
11
|
#
|
10
|
-
#
|
11
|
-
# 2. there are no dependencies on C extensions (ffi)
|
12
|
-
# 3. it only support unixy systems.
|
12
|
+
# @api private
|
13
13
|
class Subprocess
|
14
14
|
|
15
15
|
require 'r10k/util/subprocess/runner'
|
16
16
|
require 'r10k/util/subprocess/io'
|
17
17
|
require 'r10k/util/subprocess/result'
|
18
18
|
|
19
|
+
require 'r10k/util/subprocess/posix'
|
20
|
+
require 'r10k/util/subprocess/windows'
|
21
|
+
|
22
|
+
# @return [Class < R10K::Util::Subprocess::Runner]
|
23
|
+
def self.runner
|
24
|
+
if R10K::Util::Platform.windows?
|
25
|
+
R10K::Util::Subprocess::Windows::Runner
|
26
|
+
else
|
27
|
+
R10K::Util::Subprocess::POSIX::Runner
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
19
31
|
include R10K::Logging
|
20
32
|
|
33
|
+
# @!attribute [r] argv
|
34
|
+
# @return [Array<String>] The command to be executed
|
35
|
+
attr_reader :argv
|
36
|
+
|
37
|
+
# @!attribute [rw] raise_on_fail
|
38
|
+
# Determine whether #execute raises an error when the command exits
|
39
|
+
# with a non-zero exit status.
|
40
|
+
# @return [true, false]
|
21
41
|
attr_accessor :raise_on_fail
|
42
|
+
|
43
|
+
# @!attribute [rw] cwd
|
44
|
+
# @return [String] The directory to be used as the cwd when executing
|
45
|
+
# the command.
|
22
46
|
attr_accessor :cwd
|
23
47
|
|
48
|
+
# @!attribute [w] logger
|
49
|
+
# Allow calling processes to take ownership of execution logs by passing
|
50
|
+
# their own logger to the command being executed.
|
24
51
|
attr_writer :logger
|
25
52
|
|
53
|
+
# Prepare the subprocess invocation.
|
54
|
+
#
|
55
|
+
# @param argv [Array<String>] The argument vector to execute
|
26
56
|
def initialize(argv)
|
27
57
|
@argv = argv
|
28
58
|
|
29
59
|
@raise_on_fail = false
|
30
60
|
end
|
31
61
|
|
62
|
+
# Execute the given command and return the result of evaluation.
|
63
|
+
#
|
64
|
+
# @api public
|
65
|
+
# @raise [R10K::Util::Subprocess::SubprocessError] if raise_on_fail is
|
66
|
+
# true and the command exited with a non-zero status.
|
67
|
+
# @return [R10K::Util::Subprocess::Result]
|
32
68
|
def execute
|
33
|
-
subprocess =
|
34
|
-
subprocess.cwd = @cwd
|
35
|
-
|
36
|
-
stdout_r, stdout_w = attach_pipe(subprocess.io, :stdout, :reader)
|
37
|
-
stderr_r, stderr_w = attach_pipe(subprocess.io, :stderr, :reader)
|
69
|
+
subprocess = self.class.runner.new(@argv)
|
70
|
+
subprocess.cwd = @cwd if @cwd
|
38
71
|
|
39
72
|
logmsg = "Execute: #{@argv.join(' ')}"
|
40
73
|
logmsg << "(cwd: #{@cwd})" if @cwd
|
41
74
|
logger.debug1 logmsg
|
42
75
|
|
43
|
-
subprocess.
|
44
|
-
stdout_w.close
|
45
|
-
stderr_w.close
|
46
|
-
subprocess.wait
|
76
|
+
subprocess.run
|
47
77
|
|
48
|
-
|
49
|
-
stderr = stderr_r.read
|
50
|
-
|
51
|
-
result = Result.new(@argv, stdout, stderr, subprocess.exit_code)
|
78
|
+
result = subprocess.result
|
52
79
|
|
53
80
|
logger.debug2 "[#{result.cmd}] STDOUT: #{result.stdout.chomp}" unless result.stdout.empty?
|
54
81
|
logger.debug2 "[#{result.cmd}] STDERR: #{result.stderr.chomp}" unless result.stderr.empty?
|
@@ -60,33 +87,10 @@ module R10K
|
|
60
87
|
result
|
61
88
|
end
|
62
89
|
|
63
|
-
private
|
64
|
-
|
65
|
-
# Attach a pipe to the given process, and return the requested end of the
|
66
|
-
# pipe.
|
67
|
-
#
|
68
|
-
# @param subproc [Runner]
|
69
|
-
# @param name [Symbol] The name of the setter method on the subproc
|
70
|
-
# @param type [Symbol] One of (:reader, :writer) denoting the type to return
|
71
|
-
#
|
72
|
-
# @return [Array<IO>] The reader and writer endpoints of the pipe
|
73
|
-
def attach_pipe(subproc, name, type)
|
74
|
-
rd, wr = ::IO.pipe
|
75
|
-
|
76
|
-
case type
|
77
|
-
when :reader
|
78
|
-
other = wr
|
79
|
-
when :writer
|
80
|
-
other = rd
|
81
|
-
end
|
82
|
-
|
83
|
-
subproc.send("#{name}=", other)
|
84
|
-
|
85
|
-
[rd, wr]
|
86
|
-
end
|
87
|
-
|
88
90
|
class SubprocessError < R10KError
|
89
91
|
|
92
|
+
# !@attribute [r] result
|
93
|
+
# @return [R10K::Util::Subprocess::Result]
|
90
94
|
attr_reader :result
|
91
95
|
|
92
96
|
def initialize(mesg = nil, options = {})
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'fcntl'
|
2
|
+
|
3
|
+
# Implement a POSIX command runner by using fork/exec.
|
4
|
+
#
|
5
|
+
# This implementation is optimized to run commands in the background, and has
|
6
|
+
# a few noteworthy implementation details.
|
7
|
+
#
|
8
|
+
# First off, when the child process is forked, it calls setsid() to detach from
|
9
|
+
# the controlling TTY. This has two main ramifications: sending signals will
|
10
|
+
# never be send to the forked process, and the forked process does not have
|
11
|
+
# access to stdin.
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
class R10K::Util::Subprocess::POSIX::Runner < R10K::Util::Subprocess::Runner
|
15
|
+
|
16
|
+
def initialize(argv)
|
17
|
+
@argv = argv
|
18
|
+
@io = R10K::Util::Subprocess::POSIX::IO.new
|
19
|
+
|
20
|
+
attach_pipes
|
21
|
+
end
|
22
|
+
|
23
|
+
def start
|
24
|
+
exec_r, exec_w = status_pipe()
|
25
|
+
|
26
|
+
|
27
|
+
@pid = fork do
|
28
|
+
exec_r.close
|
29
|
+
execute_child(exec_w)
|
30
|
+
end
|
31
|
+
|
32
|
+
exec_w.close
|
33
|
+
execute_parent(exec_r)
|
34
|
+
end
|
35
|
+
|
36
|
+
def wait
|
37
|
+
if @pid
|
38
|
+
_, @status = Process.waitpid2(@pid)
|
39
|
+
end
|
40
|
+
|
41
|
+
stdout = @stdout_r.read
|
42
|
+
stderr = @stderr_r.read
|
43
|
+
|
44
|
+
@result = R10K::Util::Subprocess::Result.new(@argv, stdout, stderr, @status.exitstatus)
|
45
|
+
end
|
46
|
+
|
47
|
+
def run
|
48
|
+
start
|
49
|
+
wait
|
50
|
+
@result
|
51
|
+
end
|
52
|
+
|
53
|
+
def crashed?
|
54
|
+
exit_code != 0
|
55
|
+
end
|
56
|
+
|
57
|
+
def exit_code
|
58
|
+
@status.exitstatus
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def execute_child(exec_w)
|
64
|
+
if @cwd
|
65
|
+
Dir.chdir @cwd
|
66
|
+
end
|
67
|
+
|
68
|
+
# Create a new session for the forked child. This prevents children from
|
69
|
+
# ever being the foreground process on a TTY, which is almost always what
|
70
|
+
# we want in r10k.
|
71
|
+
Process.setsid
|
72
|
+
|
73
|
+
# Reopen file descriptors
|
74
|
+
STDOUT.reopen(io.stdout)
|
75
|
+
STDERR.reopen(io.stderr)
|
76
|
+
|
77
|
+
executable = @argv.shift
|
78
|
+
exec([executable, executable], *@argv)
|
79
|
+
rescue SystemCallError => e
|
80
|
+
exec_w.write(e.message)
|
81
|
+
end
|
82
|
+
|
83
|
+
def execute_parent(exec_r)
|
84
|
+
@stdout_w.close
|
85
|
+
@stderr_w.close
|
86
|
+
|
87
|
+
if not exec_r.eof?
|
88
|
+
msg = exec_r.read || "exec() failed"
|
89
|
+
raise "Could not execute #{@argv.join(' ')}: #{msg}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Create a pipe so that the parent can verify that the child process
|
94
|
+
# successfully executed. The pipe will be closed on a successful exec(),
|
95
|
+
# and will contain an error message on failure.
|
96
|
+
#
|
97
|
+
# @return [IO, IO] The reader and writer for this pipe
|
98
|
+
def status_pipe
|
99
|
+
r_pipe, w_pipe = ::IO.pipe
|
100
|
+
|
101
|
+
w_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
102
|
+
|
103
|
+
[r_pipe, w_pipe]
|
104
|
+
end
|
105
|
+
|
106
|
+
def attach_pipes
|
107
|
+
@stdout_r, @stdout_w = ::IO.pipe
|
108
|
+
@stderr_r, @stderr_w = ::IO.pipe
|
109
|
+
|
110
|
+
@io.stdout = @stdout_w
|
111
|
+
@io.stderr = @stderr_w
|
112
|
+
end
|
113
|
+
end
|
@@ -1,88 +1,50 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Define an abstract interface for external command runners.
|
2
|
+
#
|
3
3
|
# @api private
|
4
4
|
class R10K::Util::Subprocess::Runner
|
5
5
|
|
6
|
+
# @!attribute [rw] cwd
|
7
|
+
# @return [String] The directory to be used as the cwd when executing
|
8
|
+
# the command.
|
6
9
|
attr_accessor :cwd
|
7
10
|
|
8
11
|
attr_reader :io
|
9
12
|
|
10
13
|
attr_reader :pid
|
11
14
|
|
15
|
+
# @!attribute [r] status
|
16
|
+
# @return [Process::Status]
|
12
17
|
attr_reader :status
|
13
18
|
|
19
|
+
# @!attribute [r] result
|
20
|
+
# @return [R10K::Util::Subprocess::Result]
|
21
|
+
attr_reader :result
|
22
|
+
|
14
23
|
def initialize(argv)
|
15
|
-
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
16
26
|
|
17
|
-
|
27
|
+
def run
|
28
|
+
raise NotImplementedError
|
18
29
|
end
|
19
30
|
|
31
|
+
# Start the process asynchronously and return. Not all runners will implement this.
|
20
32
|
def start
|
21
|
-
|
22
|
-
|
23
|
-
@pid = fork do
|
24
|
-
exec_r.close
|
25
|
-
execute_child(exec_w)
|
26
|
-
end
|
27
|
-
|
28
|
-
exec_w.close
|
29
|
-
execute_parent(exec_r)
|
33
|
+
raise NotImplementedError
|
30
34
|
end
|
31
35
|
|
36
|
+
# Wait for the process to exit. Not all runners will implement this.
|
32
37
|
def wait
|
33
|
-
|
34
|
-
_, @status = Process.waitpid2(@pid)
|
35
|
-
end
|
38
|
+
raise NotImplementedError
|
36
39
|
end
|
37
40
|
|
41
|
+
# Did the given process exit with a non-zero exit code?
|
38
42
|
def crashed?
|
39
|
-
|
43
|
+
raise NotImplementedError
|
40
44
|
end
|
41
45
|
|
46
|
+
# @return [Integer] The exit status of the given process.
|
42
47
|
def exit_code
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def execute_child(exec_w)
|
49
|
-
if @cwd
|
50
|
-
Dir.chdir @cwd
|
51
|
-
end
|
52
|
-
|
53
|
-
# Create a new session for the forked child. This prevents children from
|
54
|
-
# ever being the foreground process on a TTY, which is almost always what
|
55
|
-
# we want in r10k.
|
56
|
-
Process.setsid
|
57
|
-
|
58
|
-
# Reopen file descriptors
|
59
|
-
STDOUT.reopen(io.stdout)
|
60
|
-
STDERR.reopen(io.stderr)
|
61
|
-
|
62
|
-
executable = @argv.shift
|
63
|
-
exec([executable, executable], *@argv)
|
64
|
-
rescue SystemCallError => e
|
65
|
-
exec_w.write(e.message)
|
66
|
-
end
|
67
|
-
|
68
|
-
def execute_parent(exec_r)
|
69
|
-
|
70
|
-
if not exec_r.eof?
|
71
|
-
msg = exec_r.read || "exec() failed"
|
72
|
-
raise "Could not execute #{@argv.join(' ')}: #{msg}"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# Create a pipe so that the parent can verify that the child process
|
77
|
-
# successfully executed. The pipe will be closed on a successful exec(),
|
78
|
-
# and will contain an error message on failure.
|
79
|
-
#
|
80
|
-
# @return [IO, IO] The reader and writer for this pipe
|
81
|
-
def status_pipe
|
82
|
-
r_pipe, w_pipe = ::IO.pipe
|
83
|
-
|
84
|
-
w_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
85
|
-
|
86
|
-
[r_pipe, w_pipe]
|
48
|
+
raise NotImplementedError
|
87
49
|
end
|
88
50
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
# Run processes on Windows.
|
4
|
+
#
|
5
|
+
# This implementation relies on Open3.capture3 to run commands and capture
|
6
|
+
# results. In contrast to the POSIX runner this cannot be used in an
|
7
|
+
# asynchronous manner as-is; implementing that will probably mean launching a
|
8
|
+
# thread and invoking #capture3 in that thread.
|
9
|
+
class R10K::Util::Subprocess::Windows::Runner < R10K::Util::Subprocess::Runner
|
10
|
+
|
11
|
+
def initialize(argv)
|
12
|
+
@argv = argv
|
13
|
+
@io = R10K::Util::Subprocess::Windows::IO.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
cmd = @argv.join(' ')
|
18
|
+
|
19
|
+
stdout, stderr, status = Open3.capture3(cmd)
|
20
|
+
|
21
|
+
@status = status
|
22
|
+
@result = R10K::Util::Subprocess::Result.new(@argv, stdout, stderr, status.exitstatus)
|
23
|
+
end
|
24
|
+
|
25
|
+
def exit_code
|
26
|
+
@status.exitstatus
|
27
|
+
end
|
28
|
+
|
29
|
+
def crashed?
|
30
|
+
exit_code != 0
|
31
|
+
end
|
32
|
+
end
|
data/lib/r10k/version.rb
CHANGED
data/r10k.gemspec
CHANGED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'r10k/util/subprocess'
|
3
|
+
|
4
|
+
describe R10K::Util::Subprocess do
|
5
|
+
|
6
|
+
describe "selecting the runner implementation" do
|
7
|
+
it "uses the windows implementation on Windows platforms" do
|
8
|
+
expect(R10K::Util::Platform).to receive(:windows?).and_return true
|
9
|
+
expect(described_class.runner).to eq R10K::Util::Subprocess::Windows::Runner
|
10
|
+
end
|
11
|
+
it "uses the posix implementation when not on windows" do
|
12
|
+
expect(R10K::Util::Platform).to receive(:windows?).and_return true
|
13
|
+
expect(described_class.runner).to eq R10K::Util::Subprocess::Windows::Runner
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "running commands" do
|
18
|
+
subject { described_class.new(['/bin/echo', 'hello', 'world']) }
|
19
|
+
|
20
|
+
let(:runner) do
|
21
|
+
double('R10K::Util::Subprocess::Runner').tap do |i|
|
22
|
+
allow(i).to receive(:run)
|
23
|
+
allow(i).to receive(:result).and_return(result)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:result) { double('R10K::Util::Subprocess::Result').as_null_object }
|
28
|
+
|
29
|
+
before do
|
30
|
+
allow(described_class).to receive(:runner).and_return(double(:new => runner))
|
31
|
+
end
|
32
|
+
|
33
|
+
it "copies the cwd to the runner if a cwd is given" do
|
34
|
+
expect(runner).to receive(:cwd=).with('/tmp')
|
35
|
+
subject.cwd = '/tmp'
|
36
|
+
subject.execute
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns the result from the execution" do
|
40
|
+
expect(subject.execute).to eq result
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "when the command returned with a non-zero exit status" do
|
44
|
+
before do
|
45
|
+
allow(runner).to receive(:crashed?).and_return true
|
46
|
+
end
|
47
|
+
|
48
|
+
it "raises an exception if raise_on_fail is true" do
|
49
|
+
subject.raise_on_fail = true
|
50
|
+
|
51
|
+
allow(result).to receive(:exit_code).and_return(255)
|
52
|
+
allow(result).to receive(:stderr).and_return('Command not found')
|
53
|
+
|
54
|
+
expect {
|
55
|
+
subject.execute
|
56
|
+
}.to raise_error(R10K::Util::Subprocess::SubprocessError, /Command .* exited with 255: Command not found/)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "doesn't raise an exception if raise_on_fail is false" do
|
60
|
+
subject.raise_on_fail = false
|
61
|
+
expect { subject.execute }.to_not raise_error
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: r10k
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrien Thebo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colored
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.
|
33
|
+
version: 2.5.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.
|
40
|
+
version: 2.5.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: systemu
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -207,6 +207,7 @@ files:
|
|
207
207
|
- lib/r10k/cli/environment/list.rb
|
208
208
|
- lib/r10k/cli/environment/stale.rb
|
209
209
|
- lib/r10k/cli/ext/logging.rb
|
210
|
+
- lib/r10k/cli/help.rb
|
210
211
|
- lib/r10k/cli/module.rb
|
211
212
|
- lib/r10k/cli/module/deploy.rb
|
212
213
|
- lib/r10k/cli/module/list.rb
|
@@ -253,11 +254,18 @@ files:
|
|
253
254
|
- lib/r10k/task/module.rb
|
254
255
|
- lib/r10k/task/puppetfile.rb
|
255
256
|
- lib/r10k/task_runner.rb
|
257
|
+
- lib/r10k/util/platform.rb
|
256
258
|
- lib/r10k/util/purgeable.rb
|
257
259
|
- lib/r10k/util/subprocess.rb
|
258
260
|
- lib/r10k/util/subprocess/io.rb
|
261
|
+
- lib/r10k/util/subprocess/posix.rb
|
262
|
+
- lib/r10k/util/subprocess/posix/io.rb
|
263
|
+
- lib/r10k/util/subprocess/posix/runner.rb
|
259
264
|
- lib/r10k/util/subprocess/result.rb
|
260
265
|
- lib/r10k/util/subprocess/runner.rb
|
266
|
+
- lib/r10k/util/subprocess/windows.rb
|
267
|
+
- lib/r10k/util/subprocess/windows/io.rb
|
268
|
+
- lib/r10k/util/subprocess/windows/runner.rb
|
261
269
|
- lib/r10k/version.rb
|
262
270
|
- r10k.gemspec
|
263
271
|
- r10k.yaml.example
|
@@ -299,6 +307,7 @@ files:
|
|
299
307
|
- spec/unit/module_spec.rb
|
300
308
|
- spec/unit/registry_spec.rb
|
301
309
|
- spec/unit/settings/container_spec.rb
|
310
|
+
- spec/unit/util/subprocess_spec.rb
|
302
311
|
homepage: http://github.com/adrienthebo/r10k
|
303
312
|
licenses:
|
304
313
|
- Apache 2.0
|
@@ -375,6 +384,7 @@ test_files:
|
|
375
384
|
- spec/unit/git/tag_spec.rb
|
376
385
|
- spec/unit/deployment/environment_spec.rb
|
377
386
|
- spec/unit/deployment/source_spec.rb
|
387
|
+
- spec/unit/util/subprocess_spec.rb
|
378
388
|
- spec/unit/settings/container_spec.rb
|
379
389
|
- spec/unit/module/forge_spec.rb
|
380
390
|
- spec/unit/module/svn_spec.rb
|