r10k 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|