Skip to content

Commit

Permalink
Merge pull request #246 from dylanahsmith/eof
Browse files Browse the repository at this point in the history
Close input streams when sending commands that don't read input.
  • Loading branch information
carsomyr committed Aug 1, 2012
2 parents ffaf041 + 784c98a commit 62a6cb7
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 6 deletions.
1 change: 1 addition & 0 deletions lib/capistrano/command.rb
Expand Up @@ -221,6 +221,7 @@ def open_channels

ch.exec(command_line)
ch.send_data(options[:data]) if options[:data]
ch.eof! if options[:eof]
else
# just log it, don't actually raise an exception, since the
# process method will see that the status is not zero and will
Expand Down
4 changes: 2 additions & 2 deletions lib/capistrano/configuration/actions/inspect.rb
Expand Up @@ -20,7 +20,7 @@ module Inspect
# stream "tail -f #{shared_path}/log/fastcgi.crash.log"
# end
def stream(command, options={})
invoke_command(command, options) do |ch, stream, out|
invoke_command(command, options.merge(:eof => true)) do |ch, stream, out|
puts out if stream == :out
warn "[err :: #{ch[:server]}] #{out}" if stream == :err
end
Expand All @@ -31,7 +31,7 @@ def stream(command, options={})
# string. The command is invoked via #invoke_command.
def capture(command, options={})
output = ""
invoke_command(command, options.merge(:once => true)) do |ch, stream, data|
invoke_command(command, options.merge(:once => true, :eof => true)) do |ch, stream, data|
case stream
when :out then output << data
when :err then warn "[err :: #{ch[:server]}] #{data}"
Expand Down
5 changes: 5 additions & 0 deletions lib/capistrano/configuration/actions/invocation.rb
Expand Up @@ -138,11 +138,16 @@ def invoke_command(cmd, options={}, &block)
# and the values should be their corresponding values. The default is
# empty, but may be modified by changing the +default_environment+
# Capistrano variable.
# * :eof - if true, the standard input stream will be closed after sending
# any data specified in the :data option. If false, the input stream is
# left open. The default is to close the input stream only if no block is
# passed.
#
# Note that if you set these keys in the +default_run_options+ Capistrano
# variable, they will apply for all invocations of #run, #invoke_command,
# and #parallel.
def run(cmd, options={}, &block)
options = options.merge(:eof => !block_given?) if options[:eof].nil?
block ||= self.class.default_io_proc
tree = Command::Tree.new(self) { |t| t.else(cmd, &block) }
run_tree(tree, options)
Expand Down
8 changes: 8 additions & 0 deletions test/command_test.rb
Expand Up @@ -254,6 +254,14 @@ def test_process_with_unknown_placeholder_should_not_replace_placeholder
Capistrano::Command.new("echo $CAPISTRANO:OTHER$", [session])
end

def test_input_stream_closed_when_eof_option_is_true
channel = nil
session = setup_for_extracting_channel_action { |ch| channel = ch }
channel.expects(:eof!)
Capistrano::Command.new("cat", [session], :data => "here we go", :eof => true)
assert_equal({ :data => 'here we go', :eof => true }, channel[:options])
end

private

def mock_session(channel=nil)
Expand Down
4 changes: 2 additions & 2 deletions test/configuration/actions/inspect_test.rb
Expand Up @@ -12,7 +12,7 @@ def setup
end

def test_stream_should_pass_options_through_to_run
@config.expects(:invoke_command).with("tail -f foo.log", :once => true)
@config.expects(:invoke_command).with("tail -f foo.log", :once => true, :eof => true)
@config.stream("tail -f foo.log", :once => true)
end

Expand All @@ -33,7 +33,7 @@ def test_stream_should_emit_stderr_via_warn
end

def test_capture_should_pass_options_merged_with_once_to_run
@config.expects(:invoke_command).with("hostname", :foo => "bar", :once => true)
@config.expects(:invoke_command).with("hostname", :foo => "bar", :once => true, :eof => true)
@config.capture("hostname", :foo => "bar")
end

Expand Down
2 changes: 1 addition & 1 deletion test/configuration/actions/invocation_test.rb
Expand Up @@ -45,7 +45,7 @@ def teardown
end

def test_run_options_should_be_passed_to_execute_on_servers
@config.expects(:execute_on_servers).with(:foo => "bar")
@config.expects(:execute_on_servers).with(:foo => "bar", :eof => true)
@config.run "ls", :foo => "bar"
end

Expand Down
2 changes: 1 addition & 1 deletion test/configuration_test.rb
Expand Up @@ -16,7 +16,7 @@ def test_connections_execution_loading_namespaces_roles_and_variables_modules_sh
process_args = Proc.new do |tree, session, opts|
tree.fallback.command == "echo 'hello world'" &&
session == [:session] &&
opts == { :logger => @config.logger }
opts == { :logger => @config.logger, :eof => true }
end

Capistrano::Command.expects(:process).with(&process_args)
Expand Down

0 comments on commit 62a6cb7

Please sign in to comment.