Skip to content

Commit

Permalink
Add support for config.command_output
Browse files Browse the repository at this point in the history
Normally airbrussh hides all stderr and stdout data returned by SSH commands.
With this commit, users of airbrussh can selectively enable displaying of
stderr and/or stdout data.
  • Loading branch information
mattbrictson committed Mar 28, 2015
1 parent af3b8a5 commit 42a16ff
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

* Your contribution here.
* New `config.banner` option allows startup message to be disabled or changed (suggestion from [@justindowning](https://github.com/justindowning))
* New `config.command_output` option gives full control of whether airbrussh shows or hides the stderr and stdout data received from remote commands; see the usage section of the README for further explanation (suggestion from [@carlesso](https://github.com/carlesso))

## 0.2.1 (2015-03-02)

Expand Down
38 changes: 35 additions & 3 deletions README.md
Expand Up @@ -53,39 +53,70 @@ Airbrussh automatically replaces the default Capistrano log formatter, so there
```ruby
Airbrussh.configure do |config|
# Capistrano's default, un-airbrusshed output is saved to a file to
# facilitate debugging. To disable this entirely:
# facilitate debugging.
#
# To disable this entirely:
# config.log_file = nil
#
# Default:
config.log_file = "log/capistrano.log"

# Airbrussh patches Rake so it can access the name of the currently executing
# task. Set this to false if monkey patching is causing issues.
#
# Default:
config.monkey_patch_rake = true

# Ansi colors will be used in the output automatically based on whether the
# output is a TTY, or if the SSHKIT_COLOR environment variable is set.
#
# To disable color always:
# config.color = false
#
# Default:
config.color = :auto

# Output is automatically truncated to the width of the terminal window, if
# possible. If the width of the terminal can't be determined, no truncation
# is performed. To truncate to a fixed width:
# is performed.
#
# To truncate to a fixed width:
# config.truncate = 80
#
# Or to disable truncation entirely:
# config.truncate = false
#
# Default:
config.truncate = :auto

# If a log_file is configured, airbrussh will output a message at startup
# displaying the log_file location. To always disable this message:
# displaying the log_file location.
#
# To always disable this message:
# config.banner = false
#
# To display an alternative message:
# config.banner = "Hello, world!"
#
# Default:
config.banner = :auto

# You can control whether airbrussh shows the output of SSH commands. For
# brevity, the output is hidden by default.
#
# Display stdout of SSH commands. Stderr is not displayed.
# config.command_output = :stdout
#
# Display stderr of SSH commands. Stdout is not displayed.
# config.command_output = :stderr
#
# Display all SSH command output.
# config.command_output = [:stdout, :stderr]
# or
# config.command_output = true
#
# Default (all output suppressed):
config.command_output = false
end
```

Expand All @@ -107,6 +138,7 @@ Airbrussh.configure do |config|
config.color = :auto
config.truncate = :auto
config.banner = :auto
config.command_output = false
end
```

Expand Down
18 changes: 17 additions & 1 deletion lib/airbrussh/configuration.rb
@@ -1,13 +1,29 @@
module Airbrussh
class Configuration
attr_accessor :log_file, :monkey_patch_rake, :color, :truncate, :banner
attr_accessor :log_file, :monkey_patch_rake, :color, :truncate, :banner,
:command_output

def initialize
self.log_file = nil
self.monkey_patch_rake = false
self.color = :auto
self.truncate = :auto
self.banner = :auto
self.command_output = false
end

def command_output_stdout?
command_output_include?(:stdout)
end

def command_output_stderr?
command_output_include?(:stderr)
end

private

def command_output_include?(sym)
command_output == true || Array(command_output).include?(sym)
end
end
end
41 changes: 36 additions & 5 deletions lib/airbrussh/formatter.rb
Expand Up @@ -33,7 +33,7 @@ def initialize(io)

@tasks = {}

@log_file = Airbrussh.configuration.log_file
@log_file = config.log_file
@log_file_formatter = create_log_file_formatter

@console = Airbrussh::Console.new(original_output)
Expand All @@ -53,13 +53,13 @@ def print_line(string)
end

def write_banner
return unless Airbrussh.configuration.banner
if Airbrussh.configuration.banner == :auto
return unless config.banner
if config.banner == :auto
return if @log_file.nil?
print_line "Using airbrussh format."
print_line "Verbose output is being written to #{blue(@log_file)}."
else
print_line Airbrussh.configuration.banner
print_line config.banner
end
end

Expand All @@ -77,7 +77,9 @@ def write_log_file_delimiter
end

def write(obj)
@log_file_formatter << obj
# SSHKit's :pretty formatter mutates the stdout and stderr data in the
# command obj. So we need to dup it to ensure our copy is unscathed.
@log_file_formatter << obj.dup

case obj
when SSHKit::Command then write_command(obj)
Expand Down Expand Up @@ -119,12 +121,37 @@ def write_command(command)
print_line " #{number} #{description}"
end

write_command_output(command, number)

if command.finished?
status = format_command_completion_status(command, number)
print_line " #{status}"
end
end

# Prints the data from the stdout and stderr streams of the given command,
# but only if enabled (see Airbrussh::Configuration#command_output).
def write_command_output(command, number)
# Use a bit of meta-programming here, since stderr and stdout logic
# are identical except for different method names.
%w(stderr stdout).each do |stream|

next unless config.public_send("command_output_#{stream}?")
output = command.public_send(stream)
next if output.empty?

output.lines.each do |line|
print_line " #{number} #{line.chomp}"
end

# The stderr/stdout data provided by the command object is the current
# "chunk" as received over the wire. Since there may be more chunks
# appended and we don't want to print duplicates, clear the current
# data.
command.public_send("#{stream}=", "")
end
end

def print_task_if_changed
status = current_task_status

Expand Down Expand Up @@ -202,5 +229,9 @@ def clock
string.to_s.colorize(color.to_sym)
end
end

def config
Airbrussh.configuration
end
end
end
48 changes: 48 additions & 0 deletions test/test_configuration.rb
@@ -0,0 +1,48 @@
require "minitest_helper"

class TestConfiguration < Minitest::Test
def setup
# Reset any configuration changes done by the tests
Airbrussh.reset
end

def test_default_command_output
refute(config.command_output)
end

def test_effects_of_command_output_true
config.command_output = true
assert(config.command_output_stdout?)
assert(config.command_output_stderr?)
end

def test_effects_of_command_output_false
config.command_output = false
refute(config.command_output_stdout?)
refute(config.command_output_stderr?)
end

def test_effects_of_command_output_stdout
config.command_output = :stdout
assert(config.command_output_stdout?)
refute(config.command_output_stderr?)
end

def test_effects_of_command_output_stderr
config.command_output = :stderr
refute(config.command_output_stdout?)
assert(config.command_output_stderr?)
end

def test_effects_of_command_output_stdout_stderr
config.command_output = [:stdout, :stderr]
assert(config.command_output_stdout?)
assert(config.command_output_stderr?)
end

private

def config
Airbrussh.configuration
end
end

0 comments on commit 42a16ff

Please sign in to comment.