sshkit 1.7.1 → 1.8.0
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 +4 -4
- data/.travis.yml +2 -2
- data/BREAKING_API_WISHLIST.md +14 -0
- data/CHANGELOG.md +74 -0
- data/CONTRIBUTING.md +43 -0
- data/EXAMPLES.md +265 -169
- data/Gemfile +7 -0
- data/README.md +274 -9
- data/RELEASING.md +16 -8
- data/Rakefile +8 -0
- data/lib/sshkit.rb +0 -9
- data/lib/sshkit/all.rb +6 -4
- data/lib/sshkit/backends/abstract.rb +42 -42
- data/lib/sshkit/backends/connection_pool.rb +57 -8
- data/lib/sshkit/backends/local.rb +21 -50
- data/lib/sshkit/backends/netssh.rb +45 -98
- data/lib/sshkit/backends/printer.rb +3 -23
- data/lib/sshkit/backends/skipper.rb +4 -8
- data/lib/sshkit/color.rb +51 -20
- data/lib/sshkit/command.rb +68 -47
- data/lib/sshkit/configuration.rb +38 -5
- data/lib/sshkit/deprecation_logger.rb +17 -0
- data/lib/sshkit/formatters/abstract.rb +28 -4
- data/lib/sshkit/formatters/black_hole.rb +1 -2
- data/lib/sshkit/formatters/dot.rb +3 -10
- data/lib/sshkit/formatters/pretty.rb +31 -56
- data/lib/sshkit/formatters/simple_text.rb +6 -44
- data/lib/sshkit/host.rb +5 -6
- data/lib/sshkit/logger.rb +0 -1
- data/lib/sshkit/mapping_interaction_handler.rb +47 -0
- data/lib/sshkit/runners/parallel.rb +1 -1
- data/lib/sshkit/runners/sequential.rb +1 -1
- data/lib/sshkit/version.rb +1 -1
- data/sshkit.gemspec +0 -1
- data/test/functional/backends/test_local.rb +14 -1
- data/test/functional/backends/test_netssh.rb +58 -50
- data/test/helper.rb +2 -2
- data/test/unit/backends/test_abstract.rb +145 -0
- data/test/unit/backends/test_connection_pool.rb +27 -2
- data/test/unit/backends/test_printer.rb +47 -47
- data/test/unit/formatters/test_custom.rb +65 -0
- data/test/unit/formatters/test_dot.rb +25 -32
- data/test/unit/formatters/test_pretty.rb +114 -22
- data/test/unit/formatters/test_simple_text.rb +83 -0
- data/test/unit/test_color.rb +69 -5
- data/test/unit/test_command.rb +53 -18
- data/test/unit/test_command_map.rb +0 -4
- data/test/unit/test_configuration.rb +47 -7
- data/test/unit/test_coordinator.rb +45 -52
- data/test/unit/test_deprecation_logger.rb +38 -0
- data/test/unit/test_host.rb +3 -4
- data/test/unit/test_logger.rb +0 -1
- data/test/unit/test_mapping_interaction_handler.rb +101 -0
- metadata +37 -41
- data/lib/sshkit/utils/capture_output_methods.rb +0 -13
- data/test/functional/test_coordinator.rb +0 -17
data/lib/sshkit/color.rb
CHANGED
@@ -1,27 +1,58 @@
|
|
1
|
-
|
1
|
+
module SSHKit
|
2
|
+
# Very basic support for ANSI color, so that we don't have to rely on
|
3
|
+
# any external dependencies. This class handles colorizing strings, and
|
4
|
+
# automatically disabling color if the underlying output is not a tty.
|
5
|
+
#
|
6
|
+
class Color
|
7
|
+
COLOR_CODES = {
|
8
|
+
:black => 30,
|
9
|
+
:red => 31,
|
10
|
+
:green => 32,
|
11
|
+
:yellow => 33,
|
12
|
+
:blue => 34,
|
13
|
+
:magenta => 35,
|
14
|
+
:cyan => 36,
|
15
|
+
:white => 37,
|
16
|
+
:light_black => 90,
|
17
|
+
:light_red => 91,
|
18
|
+
:light_green => 92,
|
19
|
+
:light_yellow => 93,
|
20
|
+
:light_blue => 94,
|
21
|
+
:light_magenta => 95,
|
22
|
+
:light_cyan => 96,
|
23
|
+
:light_white => 97
|
24
|
+
}.freeze
|
2
25
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
def #{color}(string = '')
|
7
|
-
string = yield if block_given?
|
8
|
-
colorize? ? string.colorize(:color => :#{color}) : string
|
9
|
-
end
|
10
|
-
RUBY
|
11
|
-
end
|
26
|
+
def initialize(output, env=ENV)
|
27
|
+
@output, @env = output, env
|
28
|
+
end
|
12
29
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
30
|
+
# Converts the given obj to string and surrounds in the appropriate ANSI
|
31
|
+
# color escape sequence, based on the specified color and mode. The color
|
32
|
+
# must be a symbol (see COLOR_CODES for a complete list).
|
33
|
+
#
|
34
|
+
# If the underlying output does not support ANSI color (see `colorize?),
|
35
|
+
# the string will be not be colorized. Likewise if the specified color
|
36
|
+
# symbol is unrecognized, the string will not be colorized.
|
37
|
+
#
|
38
|
+
# Note that the only mode currently support is :bold. All other values
|
39
|
+
# will be silently ignored (i.e. treated the same as mode=nil).
|
40
|
+
#
|
41
|
+
def colorize(obj, color, mode=nil)
|
42
|
+
string = obj.to_s
|
43
|
+
return string unless colorize?
|
44
|
+
return string unless COLOR_CODES.key?(color)
|
45
|
+
|
46
|
+
result = mode == :bold ? "\e[1;" : "\e[0;"
|
47
|
+
result << COLOR_CODES.fetch(color).to_s
|
48
|
+
result << ";49m#{string}\e[0m"
|
49
|
+
end
|
21
50
|
|
22
|
-
|
51
|
+
# Returns `true` if the underlying output is a tty, or if the SSHKIT_COLOR
|
52
|
+
# environment variable is set.
|
53
|
+
#
|
23
54
|
def colorize?
|
24
|
-
|
55
|
+
@env['SSHKIT_COLOR'] || (@output.respond_to?(:tty?) && @output.tty?)
|
25
56
|
end
|
26
57
|
end
|
27
58
|
end
|
data/lib/sshkit/command.rb
CHANGED
@@ -4,38 +4,12 @@ require 'securerandom'
|
|
4
4
|
# @author Lee Hambley
|
5
5
|
module SSHKit
|
6
6
|
|
7
|
-
# @author Lee Hambley
|
8
|
-
module CommandHelper
|
9
|
-
|
10
|
-
def rake(tasks=[])
|
11
|
-
execute :rake, tasks
|
12
|
-
end
|
13
|
-
|
14
|
-
def make(tasks=[])
|
15
|
-
execute :make, tasks
|
16
|
-
end
|
17
|
-
|
18
|
-
def execute(command, args=[])
|
19
|
-
Command.new(command, args)
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def map(command)
|
25
|
-
SSHKit.config.command_map[command.to_sym]
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
7
|
# @author Lee Hambley
|
31
8
|
class Command
|
32
9
|
|
33
10
|
Failed = Class.new(SSHKit::StandardError)
|
34
11
|
|
35
|
-
attr_reader :command, :args, :options, :started_at, :started, :exit_status
|
36
|
-
|
37
|
-
attr_accessor :stdout, :stderr
|
38
|
-
attr_accessor :full_stdout, :full_stderr
|
12
|
+
attr_reader :command, :args, :options, :started_at, :started, :exit_status, :full_stdout, :full_stderr
|
39
13
|
|
40
14
|
# Initialize a new Command object
|
41
15
|
#
|
@@ -45,14 +19,13 @@ module SSHKit
|
|
45
19
|
# nothing in stdin or stdout
|
46
20
|
#
|
47
21
|
def initialize(*args)
|
48
|
-
raise ArgumentError, "
|
22
|
+
raise ArgumentError, "Must pass arguments to Command.new" if args.empty?
|
49
23
|
@options = default_options.merge(args.extract_options!)
|
50
24
|
@command = args.shift.to_s.strip.to_sym
|
51
25
|
@args = args
|
52
26
|
@options.symbolize_keys!
|
53
27
|
sanitize_command!
|
54
|
-
@stdout, @stderr = String.new, String.new
|
55
|
-
@full_stdout, @full_stderr = String.new, String.new
|
28
|
+
@stdout, @stderr, @full_stdout, @full_stderr = String.new, String.new, String.new, String.new
|
56
29
|
end
|
57
30
|
|
58
31
|
def complete?
|
@@ -83,6 +56,38 @@ module SSHKit
|
|
83
56
|
end
|
84
57
|
alias :failed? :failure?
|
85
58
|
|
59
|
+
def stdout
|
60
|
+
log_reader_deprecation('stdout')
|
61
|
+
@stdout
|
62
|
+
end
|
63
|
+
|
64
|
+
def stdout=(new_value)
|
65
|
+
log_writer_deprecation('stdout')
|
66
|
+
@stdout = new_value
|
67
|
+
end
|
68
|
+
|
69
|
+
def stderr
|
70
|
+
log_reader_deprecation('stderr')
|
71
|
+
@stderr
|
72
|
+
end
|
73
|
+
|
74
|
+
def stderr=(new_value)
|
75
|
+
log_writer_deprecation('stderr')
|
76
|
+
@stderr = new_value
|
77
|
+
end
|
78
|
+
|
79
|
+
def on_stdout(channel, data)
|
80
|
+
@stdout = data
|
81
|
+
@full_stdout += data
|
82
|
+
call_interaction_handler(:stdout, data, channel)
|
83
|
+
end
|
84
|
+
|
85
|
+
def on_stderr(channel, data)
|
86
|
+
@stderr = data
|
87
|
+
@full_stderr += data
|
88
|
+
call_interaction_handler(:stderr, data, channel)
|
89
|
+
end
|
90
|
+
|
86
91
|
def exit_status=(new_exit_status)
|
87
92
|
@finished_at = Time.now
|
88
93
|
@exit_status = new_exit_status
|
@@ -125,7 +130,7 @@ module SSHKit
|
|
125
130
|
end
|
126
131
|
|
127
132
|
def verbosity
|
128
|
-
if vb = options[:verbosity]
|
133
|
+
if (vb = options[:verbosity])
|
129
134
|
case vb.class.name
|
130
135
|
when 'Symbol' then return Logger.const_get(vb.to_s.upcase)
|
131
136
|
when 'Fixnum' then return vb
|
@@ -136,12 +141,12 @@ module SSHKit
|
|
136
141
|
end
|
137
142
|
|
138
143
|
def should_map?
|
139
|
-
!command.match
|
144
|
+
!command.match(/\s/)
|
140
145
|
end
|
141
146
|
|
142
|
-
def within(&
|
147
|
+
def within(&_block)
|
143
148
|
return yield unless options[:in]
|
144
|
-
"cd #{options[:in]} && %s"
|
149
|
+
sprintf("cd #{options[:in]} && %s", yield)
|
145
150
|
end
|
146
151
|
|
147
152
|
def environment_hash
|
@@ -150,35 +155,33 @@ module SSHKit
|
|
150
155
|
|
151
156
|
def environment_string
|
152
157
|
environment_hash.collect do |key,value|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
"#{key.to_s}=#{value}"
|
157
|
-
end
|
158
|
+
key_string = key.is_a?(Symbol) ? key.to_s.upcase : key.to_s
|
159
|
+
escaped_value = value.to_s.gsub(/"/, '\"')
|
160
|
+
%{#{key_string}="#{escaped_value}"}
|
158
161
|
end.join(' ')
|
159
162
|
end
|
160
163
|
|
161
|
-
def with(&
|
164
|
+
def with(&_block)
|
162
165
|
return yield unless environment_hash.any?
|
163
|
-
"( #{environment_string} %s )"
|
166
|
+
sprintf("( export #{environment_string} ; %s )", yield)
|
164
167
|
end
|
165
168
|
|
166
|
-
def user(&
|
169
|
+
def user(&_block)
|
167
170
|
return yield unless options[:user]
|
168
171
|
"sudo -u #{options[:user]} #{environment_string + " " unless environment_string.empty?}-- sh -c '%s'" % %Q{#{yield}}
|
169
172
|
end
|
170
173
|
|
171
|
-
def in_background(&
|
174
|
+
def in_background(&_block)
|
172
175
|
return yield unless options[:run_in_background]
|
173
|
-
"( nohup %s > /dev/null & )"
|
176
|
+
sprintf("( nohup %s > /dev/null & )", yield)
|
174
177
|
end
|
175
178
|
|
176
|
-
def umask(&
|
179
|
+
def umask(&_block)
|
177
180
|
return yield unless SSHKit.config.umask
|
178
|
-
"umask #{SSHKit.config.umask} && %s"
|
181
|
+
sprintf("umask #{SSHKit.config.umask} && %s", yield)
|
179
182
|
end
|
180
183
|
|
181
|
-
def group(&
|
184
|
+
def group(&_block)
|
182
185
|
return yield unless options[:group]
|
183
186
|
"sg #{options[:group]} -c \\\"%s\\\"" % %Q{#{yield}}
|
184
187
|
# We could also use the so-called heredoc format perhaps:
|
@@ -227,6 +230,24 @@ module SSHKit
|
|
227
230
|
end
|
228
231
|
end
|
229
232
|
|
233
|
+
def call_interaction_handler(stream_name, data, channel)
|
234
|
+
interaction_handler = options[:interaction_handler]
|
235
|
+
interaction_handler = MappingInteractionHandler.new(interaction_handler) if interaction_handler.kind_of?(Hash)
|
236
|
+
interaction_handler.on_data(self, stream_name, data, channel) if interaction_handler.respond_to?(:on_data)
|
237
|
+
end
|
238
|
+
|
239
|
+
def log_reader_deprecation(stream)
|
240
|
+
SSHKit.config.deprecation_logger.log(
|
241
|
+
"The #{stream} method on Command is deprecated. " \
|
242
|
+
"The @#{stream} attribute will be removed in a future release. Use full_#{stream}() instead."
|
243
|
+
)
|
244
|
+
end
|
245
|
+
|
246
|
+
def log_writer_deprecation(stream)
|
247
|
+
SSHKit.config.deprecation_logger.log(
|
248
|
+
"The #{stream}= method on Command is deprecated. The @#{stream} attribute will be removed in a future release."
|
249
|
+
)
|
250
|
+
end
|
230
251
|
end
|
231
252
|
|
232
253
|
end
|
data/lib/sshkit/configuration.rb
CHANGED
@@ -6,7 +6,16 @@ module SSHKit
|
|
6
6
|
attr_writer :output, :backend, :default_env
|
7
7
|
|
8
8
|
def output
|
9
|
-
@output ||=
|
9
|
+
@output ||= use_format(:pretty)
|
10
|
+
end
|
11
|
+
|
12
|
+
def deprecation_logger
|
13
|
+
self.deprecation_output = $stderr if @deprecation_logger.nil?
|
14
|
+
@deprecation_logger
|
15
|
+
end
|
16
|
+
|
17
|
+
def deprecation_output=(out)
|
18
|
+
@deprecation_logger = DeprecationLogger.new(out)
|
10
19
|
end
|
11
20
|
|
12
21
|
def default_env
|
@@ -25,8 +34,29 @@ module SSHKit
|
|
25
34
|
@output_verbosity = logger(verbosity)
|
26
35
|
end
|
27
36
|
|
37
|
+
# TODO: deprecate in favor of `use_format`
|
28
38
|
def format=(format)
|
29
|
-
|
39
|
+
use_format(format)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Tell SSHKit to use the specified `formatter` for stdout. The formatter
|
43
|
+
# can be the name of a built-in SSHKit formatter, like `:pretty`, a
|
44
|
+
# formatter class, like `SSHKit::Formatter::Pretty`, or a custom formatter
|
45
|
+
# class you've written yourself.
|
46
|
+
#
|
47
|
+
# Additional arguments will be passed to the formatter's constructor.
|
48
|
+
#
|
49
|
+
# Example:
|
50
|
+
#
|
51
|
+
# config.use_format(:pretty)
|
52
|
+
#
|
53
|
+
# Is equivalent to:
|
54
|
+
#
|
55
|
+
# config.output = SSHKit::Formatter::Pretty.new($stdout)
|
56
|
+
#
|
57
|
+
def use_format(formatter, *args)
|
58
|
+
klass = formatter.is_a?(Class) ? formatter : formatter_class(formatter)
|
59
|
+
self.output = klass.new($stdout, *args)
|
30
60
|
end
|
31
61
|
|
32
62
|
def command_map
|
@@ -43,10 +73,13 @@ module SSHKit
|
|
43
73
|
verbosity.is_a?(Integer) ? verbosity : Logger.const_get(verbosity.upcase)
|
44
74
|
end
|
45
75
|
|
46
|
-
def
|
47
|
-
|
48
|
-
|
76
|
+
def formatter_class(symbol)
|
77
|
+
name = symbol.to_s.downcase
|
78
|
+
found = SSHKit::Formatter.constants.find do |const|
|
79
|
+
const.to_s.downcase == name
|
49
80
|
end
|
81
|
+
fail NameError, 'Unrecognized SSHKit::Formatter "#{symbol}"' if found.nil?
|
82
|
+
SSHKit::Formatter.const_get(found)
|
50
83
|
end
|
51
84
|
|
52
85
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module SSHKit
|
2
|
+
class DeprecationLogger
|
3
|
+
def initialize(out)
|
4
|
+
@out = out
|
5
|
+
@previous_warnings = Set.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def log(message)
|
9
|
+
return if @out.nil?
|
10
|
+
warning_msg = "[Deprecated] #{message}\n"
|
11
|
+
caller_line = caller.find { |line| !line.include?('lib/sshkit') }
|
12
|
+
warning_msg << " (Called from #{caller_line})\n" unless caller_line.nil?
|
13
|
+
@out << warning_msg unless @previous_warnings.include?(warning_msg)
|
14
|
+
@previous_warnings << warning_msg
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -9,15 +9,39 @@ module SSHKit
|
|
9
9
|
extend Forwardable
|
10
10
|
attr_reader :original_output
|
11
11
|
def_delegators :@original_output, :read, :rewind
|
12
|
+
def_delegators :@color, :colorize
|
12
13
|
|
13
|
-
def initialize(
|
14
|
-
@original_output =
|
14
|
+
def initialize(output)
|
15
|
+
@original_output = output
|
16
|
+
@color = SSHKit::Color.new(output)
|
15
17
|
end
|
16
18
|
|
17
|
-
|
19
|
+
%w(fatal error warn info debug).each do |level|
|
20
|
+
define_method(level) do |message|
|
21
|
+
write(LogMessage.new(Logger.const_get(level.upcase), message))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
alias :log :info
|
25
|
+
|
26
|
+
def log_command_start(command)
|
27
|
+
write(command)
|
28
|
+
end
|
29
|
+
|
30
|
+
def log_command_data(command, _stream_type, _stream_data)
|
31
|
+
write(command)
|
32
|
+
end
|
33
|
+
|
34
|
+
def log_command_exit(command)
|
35
|
+
write(command)
|
36
|
+
end
|
37
|
+
|
38
|
+
def <<(obj)
|
39
|
+
write(obj)
|
40
|
+
end
|
41
|
+
|
42
|
+
def write(_obj)
|
18
43
|
raise "Abstract formatter should not be used directly, maybe you want SSHKit::Formatter::BlackHole"
|
19
44
|
end
|
20
|
-
alias :<< :write
|
21
45
|
|
22
46
|
end
|
23
47
|
|
@@ -4,18 +4,11 @@ module SSHKit
|
|
4
4
|
|
5
5
|
class Dot < Abstract
|
6
6
|
|
7
|
-
def
|
8
|
-
|
9
|
-
if obj.finished?
|
10
|
-
original_output << (obj.failure? ? c.red('.') : c.green('.'))
|
11
|
-
end
|
7
|
+
def log_command_exit(command)
|
8
|
+
original_output << colorize('.', command.failure? ? :red : :green)
|
12
9
|
end
|
13
|
-
alias :<< :write
|
14
10
|
|
15
|
-
|
16
|
-
|
17
|
-
def c
|
18
|
-
@c ||= Color
|
11
|
+
def write(_obj)
|
19
12
|
end
|
20
13
|
|
21
14
|
end
|
@@ -4,77 +4,52 @@ module SSHKit
|
|
4
4
|
|
5
5
|
class Pretty < Abstract
|
6
6
|
|
7
|
+
LEVEL_NAMES = %w{ DEBUG INFO WARN ERROR FATAL }.freeze
|
8
|
+
LEVEL_COLORS = [:black, :blue, :yellow, :red, :red].freeze
|
9
|
+
|
7
10
|
def write(obj)
|
8
|
-
|
9
|
-
|
10
|
-
when SSHKit::Command then write_command(obj)
|
11
|
-
when SSHKit::LogMessage then write_log_message(obj)
|
11
|
+
if obj.kind_of?(SSHKit::LogMessage)
|
12
|
+
write_message(obj.verbosity, obj.to_s)
|
12
13
|
else
|
13
|
-
|
14
|
+
raise "write only supports formatting SSHKit::LogMessage, called with #{obj.class}: #{obj.inspect}"
|
14
15
|
end
|
15
16
|
end
|
16
|
-
alias :<< :write
|
17
|
-
|
18
|
-
private
|
19
17
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
original_output << "%6s %s\n" % [level(Logger::DEBUG),
|
26
|
-
uuid(command) + "Command: #{c.blue(command.to_command)}"]
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
if SSHKit.config.output_verbosity == Logger::DEBUG
|
31
|
-
unless command.stdout.empty?
|
32
|
-
command.stdout.lines.each do |line|
|
33
|
-
original_output << "%6s %s" % [level(Logger::DEBUG),
|
34
|
-
uuid(command) + c.green("\t" + line)]
|
35
|
-
original_output << "\n" unless line[-1] == "\n"
|
36
|
-
end
|
37
|
-
command.stdout = ''
|
38
|
-
end
|
39
|
-
|
40
|
-
unless command.stderr.empty?
|
41
|
-
command.stderr.lines.each do |line|
|
42
|
-
original_output << "%6s %s" % [level(Logger::DEBUG),
|
43
|
-
uuid(command) + c.red("\t" + line)]
|
44
|
-
original_output << "\n" unless line[-1] == "\n"
|
45
|
-
end
|
46
|
-
command.stderr = ''
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
if command.finished?
|
51
|
-
original_output << "%6s %s\n" % [level(command.verbosity),
|
52
|
-
uuid(command) + "Finished in #{sprintf('%5.3f seconds', command.runtime)} with exit status #{command.exit_status} (#{c.bold { command.failure? ? c.red('failed') : c.green('successful') }})."]
|
53
|
-
end
|
18
|
+
def log_command_start(command)
|
19
|
+
host_prefix = command.host.user ? "as #{colorize(command.host.user, :blue)}@" : 'on '
|
20
|
+
message = "Running #{colorize(command, :yellow, :bold)} #{host_prefix}#{colorize(command.host, :blue)}"
|
21
|
+
write_message(command.verbosity, message, command.uuid)
|
22
|
+
write_message(Logger::DEBUG, "Command: #{colorize(command.to_command, :blue)}", command.uuid)
|
54
23
|
end
|
55
24
|
|
56
|
-
def
|
57
|
-
|
25
|
+
def log_command_data(command, stream_type, stream_data)
|
26
|
+
color = case stream_type
|
27
|
+
when :stdout then :green
|
28
|
+
when :stderr then :red
|
29
|
+
else raise "Unrecognised stream_type #{stream_type}, expected :stdout or :stderr"
|
30
|
+
end
|
31
|
+
write_message(Logger::DEBUG, colorize("\t#{stream_data}".chomp, color), command.uuid)
|
58
32
|
end
|
59
33
|
|
60
|
-
def
|
61
|
-
|
34
|
+
def log_command_exit(command)
|
35
|
+
runtime = sprintf('%5.3f seconds', command.runtime)
|
36
|
+
successful_or_failed = command.failure? ? colorize('failed', :red, :bold) : colorize('successful', :green, :bold)
|
37
|
+
message = "Finished in #{runtime} with exit status #{command.exit_status} (#{successful_or_failed})."
|
38
|
+
write_message(command.verbosity, message, command.uuid)
|
62
39
|
end
|
63
40
|
|
64
|
-
|
65
|
-
"[#{c.green(obj.uuid)}] "
|
66
|
-
end
|
41
|
+
protected
|
67
42
|
|
68
|
-
def
|
69
|
-
|
43
|
+
def format_message(verbosity, message, uuid=nil)
|
44
|
+
message = "[#{colorize(uuid, :green)}] #{message}" unless uuid.nil?
|
45
|
+
level = colorize(Pretty::LEVEL_NAMES[verbosity], Pretty::LEVEL_COLORS[verbosity])
|
46
|
+
'%6s %s' % [level, message]
|
70
47
|
end
|
71
48
|
|
72
|
-
|
73
|
-
%w{ black blue yellow red red }[level_num]
|
74
|
-
end
|
49
|
+
private
|
75
50
|
|
76
|
-
def
|
77
|
-
|
51
|
+
def write_message(verbosity, message, uuid=nil)
|
52
|
+
original_output << "#{format_message(verbosity, message, uuid)}\n" if verbosity >= SSHKit.config.output_verbosity
|
78
53
|
end
|
79
54
|
|
80
55
|
end
|