diff options
author | Claire McQuin <mcquin@users.noreply.github.com> | 2014-08-08 08:27:54 -0700 |
---|---|---|
committer | Claire McQuin <mcquin@users.noreply.github.com> | 2014-08-08 08:27:54 -0700 |
commit | 01f85655f30eea95ea52a37b3b55515b2de75a0f (patch) | |
tree | 6dcd987d970cf6521ba64bbc6ced950cd6966163 | |
parent | b5e27147f0a5f0ccf44ff4968be2bdfb0c2ce35d (diff) | |
parent | ef704af76fa6d2512782824c7c3ba52a9deac3ab (diff) | |
download | mixlib-shellout-01f85655f30eea95ea52a37b3b55515b2de75a0f.tar.gz |
Merge pull request #53 from maxlinc/stderr_livestream
Support separate live stream for stderr
-rw-r--r-- | lib/mixlib/shellout.rb | 31 | ||||
-rw-r--r-- | lib/mixlib/shellout/unix.rb | 4 | ||||
-rw-r--r-- | lib/mixlib/shellout/windows.rb | 2 | ||||
-rw-r--r-- | spec/mixlib/shellout_spec.rb | 96 |
4 files changed, 119 insertions, 14 deletions
diff --git a/lib/mixlib/shellout.rb b/lib/mixlib/shellout.rb index e446448..6261c21 100644 --- a/lib/mixlib/shellout.rb +++ b/lib/mixlib/shellout.rb @@ -53,10 +53,13 @@ module Mixlib # to determine if the command was successful. Normally set via options to new attr_accessor :valid_exit_codes - # When live_stream is set, stdout and stderr of the subprocess will be - # copied to it as the subprocess is running. For example, if live_stream is - # set to STDOUT, the command's output will be echoed to STDOUT. - attr_accessor :live_stream + # When live_stdout is set, the stdout of the subprocess will be copied to it + # as the subprocess is running. + attr_accessor :live_stdout + + # When live_stderr is set, the stderr of the subprocess will be copied to it + # as the subprocess is running. + attr_accessor :live_stderr # ShellOut will push data from :input down the stdin of the subprocss. # Normally set via options passed to new. @@ -147,7 +150,7 @@ module Mixlib # cmd.run_command # etc. def initialize(*command_args) @stdout, @stderr = '', '' - @live_stream = nil + @live_stdout = @live_stderr = nil @input = nil @log_level = :debug @log_tag = nil @@ -163,6 +166,18 @@ module Mixlib @command = command_args.size == 1 ? command_args.first : command_args end + # Returns the stream that both is being used by both live_stdout and live_stderr, or nil + def live_stream + live_stdout == live_stderr ? live_stdout : nil + end + + # A shortcut for setting both live_stdout and live_stderr, so that both the + # stdout and stderr from the subprocess will be copied to the same stream as + # the subprocess is running. + def live_stream=(stream) + @live_stdout = @live_stderr = stream + end + # Set the umask that the subprocess will have. If given as a string, it # will be converted to an integer by String#oct. def umask=(new_umask) @@ -286,7 +301,11 @@ module Mixlib when 'returns' self.valid_exit_codes = Array(setting) when 'live_stream' - self.live_stream = setting + self.live_stdout = self.live_stderr = setting + when 'live_stdout' + self.live_stdout = setting + when 'live_stderr' + self.live_stderr = setting when 'input' self.input = setting when 'logger' diff --git a/lib/mixlib/shellout/unix.rb b/lib/mixlib/shellout/unix.rb index 46c2c73..be2e66a 100644 --- a/lib/mixlib/shellout/unix.rb +++ b/lib/mixlib/shellout/unix.rb @@ -278,7 +278,7 @@ module Mixlib def read_stdout_to_buffer while chunk = child_stdout.read_nonblock(READ_SIZE) @stdout << chunk - @live_stream << chunk if @live_stream + @live_stdout << chunk if @live_stdout end rescue Errno::EAGAIN rescue EOFError @@ -288,7 +288,7 @@ module Mixlib def read_stderr_to_buffer while chunk = child_stderr.read_nonblock(READ_SIZE) @stderr << chunk - @live_stream << chunk if @live_stream + @live_stderr << chunk if @live_stderr end rescue Errno::EAGAIN rescue EOFError diff --git a/lib/mixlib/shellout/windows.rb b/lib/mixlib/shellout/windows.rb index 832584a..2ae0256 100644 --- a/lib/mixlib/shellout/windows.rb +++ b/lib/mixlib/shellout/windows.rb @@ -167,7 +167,7 @@ module Mixlib begin next_chunk = stderr_read.readpartial(READ_SIZE) @stderr << next_chunk - @live_stream << next_chunk if @live_stream + @live_stderr << next_chunk if @live_stderr rescue EOFError stderr_read.close open_streams.delete(stderr_read) diff --git a/spec/mixlib/shellout_spec.rb b/spec/mixlib/shellout_spec.rb index 5dcb6a7..ff493c2 100644 --- a/spec/mixlib/shellout_spec.rb +++ b/spec/mixlib/shellout_spec.rb @@ -187,8 +187,68 @@ describe Mixlib::ShellOut do let(:value) { stream } let(:stream) { StringIO.new } - it "should set the live stream" do - should eql(value) + before(:each) do + shell_cmd.live_stream = stream + end + + it "live stream should return the stream used for live stdout and live stderr" do + shell_cmd.live_stream.should eql(stream) + end + + it "should set the live stdout stream" do + shell_cmd.live_stderr.should eql(stream) + end + + it "should set the live stderr stream" do + shell_cmd.live_stderr.should eql(stream) + end + end + + context 'when setting the live stdout and live stderr streams separately' do + let(:accessor) { :live_stream } + let(:stream) { StringIO.new } + let(:value) { stream } + let(:stdout_stream) { StringIO.new } + let(:stderr_stream) { StringIO.new } + + before(:each) do + shell_cmd.live_stdout = stdout_stream + shell_cmd.live_stderr = stderr_stream + end + + it "live_stream should return nil" do + shell_cmd.live_stream.should be_nil + end + + it "should set the live stdout" do + shell_cmd.live_stdout.should eql(stdout_stream) + end + + it "should set the live stderr" do + shell_cmd.live_stderr.should eql(stderr_stream) + end + end + + context 'when setting a live stream and then overriding the live stderr' do + let(:accessor) { :live_stream } + let(:value) { stream } + let(:stream) { StringIO.new } + + before(:each) do + shell_cmd.live_stdout = stream + shell_cmd.live_stderr = nil + end + + it "should return nil" do + should be_nil + end + + it "should set the live stdout" do + shell_cmd.live_stdout.should eql(stream) + end + + it "should set the live stderr" do + shell_cmd.live_stderr.should eql(nil) end end @@ -457,9 +517,35 @@ describe Mixlib::ShellOut do stream.string.should include("hello#{LINE_ENDING}") end - it "should copy the child's stderr to the live stream" do - shell_cmd.run_command - stream.string.should include("world#{LINE_ENDING}") + context "with default live stderr" do + it "should copy the child's stderr to the live stream" do + shell_cmd.run_command + stream.string.should include("world#{LINE_ENDING}") + end + end + + context "without live stderr" do + it "should not copy the child's stderr to the live stream" do + shell_cmd.live_stderr = nil + shell_cmd.run_command + stream.string.should_not include("world#{LINE_ENDING}") + end + end + + context "with a separate live stderr" do + let(:stderr_stream) { StringIO.new } + + it "should not copy the child's stderr to the live stream" do + shell_cmd.live_stderr = stderr_stream + shell_cmd.run_command + stream.string.should_not include("world#{LINE_ENDING}") + end + + it "should copy the child's stderr to the live stderr stream" do + shell_cmd.live_stderr = stderr_stream + shell_cmd.run_command + stderr_stream.string.should include("world#{LINE_ENDING}") + end end end |