console 0.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +15 -0
- data/Gemfile +8 -0
- data/README.md +165 -0
- data/Rakefile +13 -0
- data/console.gemspec +24 -0
- data/lib/console.rb +65 -0
- data/lib/console/buffer.rb +40 -0
- data/lib/console/capture.rb +66 -0
- data/lib/console/error.rb +76 -0
- data/lib/console/filter.rb +119 -0
- data/lib/console/generic.rb +26 -0
- data/lib/console/logger.rb +31 -0
- data/lib/console/serialized/logger.rb +71 -0
- data/lib/console/shell.rb +65 -0
- data/lib/console/split.rb +42 -0
- data/lib/console/terminal.rb +21 -0
- data/lib/console/terminal/logger.rb +150 -0
- data/lib/console/terminal/text.rb +67 -0
- data/lib/console/terminal/xterm.rb +80 -0
- data/lib/console/version.rb +23 -0
- data/proposal.md +84 -0
- metadata +107 -58
- data/README +0 -51
- data/ext/console/console.c +0 -271
- data/ext/console/extconf.rb +0 -2
- data/lib/console/string.rb +0 -37
- data/test/console.rb +0 -126
@@ -0,0 +1,119 @@
|
|
1
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'buffer'
|
22
|
+
|
23
|
+
module Console
|
24
|
+
UNKNOWN = 'unknown'
|
25
|
+
|
26
|
+
class Filter
|
27
|
+
def self.[] **levels
|
28
|
+
klass = Class.new(self)
|
29
|
+
|
30
|
+
klass.instance_exec do
|
31
|
+
const_set(:LEVELS, levels)
|
32
|
+
const_set(:MAXIMUM_LEVEL, levels.values.max)
|
33
|
+
|
34
|
+
levels.each do |name, level|
|
35
|
+
const_set(name.to_s.upcase, level)
|
36
|
+
|
37
|
+
define_method(name) do |subject = nil, *arguments, &block|
|
38
|
+
enabled = @subjects[subject.class]
|
39
|
+
|
40
|
+
if enabled == true or (enabled != false and level >= @level)
|
41
|
+
self.call(subject, *arguments, severity: name, **@options, &block)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
define_method("#{name}!") do
|
46
|
+
@level = level
|
47
|
+
end
|
48
|
+
|
49
|
+
define_method("#{name}?") do
|
50
|
+
@level >= level
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
return klass
|
56
|
+
end
|
57
|
+
|
58
|
+
def initialize(output, verbose: true, level: 0, **options)
|
59
|
+
@level = level
|
60
|
+
@verbose = verbose
|
61
|
+
|
62
|
+
@subjects = {}
|
63
|
+
|
64
|
+
@output = output
|
65
|
+
@options = options
|
66
|
+
end
|
67
|
+
|
68
|
+
def dup(**options)
|
69
|
+
super().tap do |logger|
|
70
|
+
logger.options = @options.merge(options)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
attr :level
|
75
|
+
attr :verbose
|
76
|
+
|
77
|
+
attr :subjects
|
78
|
+
|
79
|
+
attr_accessor :output
|
80
|
+
attr_accessor :options
|
81
|
+
|
82
|
+
def level= level
|
83
|
+
if level.is_a? Symbol
|
84
|
+
@level = self.class::LEVELS[level]
|
85
|
+
else
|
86
|
+
@level = level
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def verbose!(value = true)
|
91
|
+
@verbose = value
|
92
|
+
@output.verbose!(value)
|
93
|
+
end
|
94
|
+
|
95
|
+
def off!
|
96
|
+
@level = -1
|
97
|
+
end
|
98
|
+
|
99
|
+
def all!
|
100
|
+
@level = self.class::MAXIMUM_LEVEL
|
101
|
+
end
|
102
|
+
|
103
|
+
def enabled?(subject)
|
104
|
+
@subjects[subject.class] == true
|
105
|
+
end
|
106
|
+
|
107
|
+
def enable(subject)
|
108
|
+
@subjects[subject.class] = true
|
109
|
+
end
|
110
|
+
|
111
|
+
def disable(subject)
|
112
|
+
@subjects[subject.class] = false
|
113
|
+
end
|
114
|
+
|
115
|
+
def call(*arguments, &block)
|
116
|
+
@output.call(*arguments, &block)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Console
|
22
|
+
class Generic
|
23
|
+
def format(buffer, terminal)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'filter'
|
22
|
+
|
23
|
+
module Console
|
24
|
+
class Logger < Filter[debug: 0, info: 1, warn: 2, error: 3, fatal: 4]
|
25
|
+
def initialize(output, **options)
|
26
|
+
super(output, **options)
|
27
|
+
|
28
|
+
self.info!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative '../buffer'
|
22
|
+
require_relative '../filter'
|
23
|
+
|
24
|
+
require 'time'
|
25
|
+
require 'json'
|
26
|
+
|
27
|
+
module Console
|
28
|
+
module Serialized
|
29
|
+
class Logger
|
30
|
+
def initialize(io = $stderr, format: JSON)
|
31
|
+
@io = io
|
32
|
+
@start = Time.now
|
33
|
+
@format = format
|
34
|
+
end
|
35
|
+
|
36
|
+
attr :io
|
37
|
+
attr :start
|
38
|
+
attr :format
|
39
|
+
|
40
|
+
def verbose!(value = true)
|
41
|
+
end
|
42
|
+
|
43
|
+
def call(subject = nil, *arguments, severity: UNKNOWN, &block)
|
44
|
+
message = {
|
45
|
+
time: Time.now.iso8601,
|
46
|
+
severity: severity,
|
47
|
+
}
|
48
|
+
|
49
|
+
if subject
|
50
|
+
message[:subject] = subject
|
51
|
+
end
|
52
|
+
|
53
|
+
if arguments.any?
|
54
|
+
message[:arguments] = arguments
|
55
|
+
end
|
56
|
+
|
57
|
+
if block_given?
|
58
|
+
if block.arity.zero?
|
59
|
+
message[:message] = yield
|
60
|
+
else
|
61
|
+
buffer = StringIO.new
|
62
|
+
yield buffer
|
63
|
+
message[:message] = buffer.string
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
@io.puts(@format.dump(message))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'generic'
|
22
|
+
|
23
|
+
module Console
|
24
|
+
class Shell < Generic
|
25
|
+
def self.for(*arguments, **options)
|
26
|
+
if arguments.first.is_a?(Hash)
|
27
|
+
self.new(*arguments, **options)
|
28
|
+
else
|
29
|
+
self.new(nil, arguments, **options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(environment, *arguments, **options)
|
34
|
+
@environment = environment
|
35
|
+
@arguments = arguments
|
36
|
+
@options = options
|
37
|
+
end
|
38
|
+
|
39
|
+
attr :environment
|
40
|
+
attr :arguments
|
41
|
+
attr :options
|
42
|
+
|
43
|
+
def chdir_string(options)
|
44
|
+
if options and chdir = options[:chdir]
|
45
|
+
" in #{chdir}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.register(terminal)
|
50
|
+
terminal[:shell_command] ||= terminal.style(:blue, nil, :bold)
|
51
|
+
end
|
52
|
+
|
53
|
+
def format(output, terminal, verbose)
|
54
|
+
arguments = @arguments.flatten.collect(&:to_s)
|
55
|
+
|
56
|
+
output.puts " #{terminal[:shell_command]}#{arguments.join(' ')}#{terminal.reset}#{chdir_string(options)}"
|
57
|
+
|
58
|
+
if verbose and @environment
|
59
|
+
@environment.each do |key, value|
|
60
|
+
output.puts " export #{key}=#{value}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
|
22
|
+
module Console
|
23
|
+
class Split
|
24
|
+
def self.[] *outputs
|
25
|
+
self.new(outputs)
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(outputs)
|
29
|
+
@outputs = outputs
|
30
|
+
end
|
31
|
+
|
32
|
+
def verbose!(value = true)
|
33
|
+
@outputs.each{|output| output.verbose!(value)}
|
34
|
+
end
|
35
|
+
|
36
|
+
def call(level, subject = nil, *arguments, **options, &block)
|
37
|
+
@outputs.each do |output|
|
38
|
+
output.call(level, subject, *arguments, **options, &block)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'terminal/logger'
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative '../buffer'
|
22
|
+
|
23
|
+
require_relative '../shell'
|
24
|
+
require_relative '../error'
|
25
|
+
|
26
|
+
require_relative 'text'
|
27
|
+
require_relative 'xterm'
|
28
|
+
|
29
|
+
module Console
|
30
|
+
module Terminal
|
31
|
+
def self.for(io)
|
32
|
+
if io.isatty
|
33
|
+
XTerm.new(io)
|
34
|
+
else
|
35
|
+
Text.new(io)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Logger
|
40
|
+
def initialize(io = $stderr, verbose: false, **options)
|
41
|
+
@io = io
|
42
|
+
@verbose = verbose
|
43
|
+
@start = Time.now
|
44
|
+
|
45
|
+
@terminal = Terminal.for(io)
|
46
|
+
@terminal[:logger_prefix] ||= @terminal.style(nil, nil, :bold)
|
47
|
+
@terminal[:logger_suffix] ||= @terminal.style(:white, nil, :faint)
|
48
|
+
@terminal[:debug] = @terminal.style(:cyan)
|
49
|
+
@terminal[:info] = @terminal.style(:green)
|
50
|
+
@terminal[:warn] = @terminal.style(:yellow)
|
51
|
+
@terminal[:error] = @terminal.style(:red)
|
52
|
+
@terminal[:fatal] = @terminal[:error]
|
53
|
+
|
54
|
+
self.register_defaults(@terminal)
|
55
|
+
end
|
56
|
+
|
57
|
+
attr :io
|
58
|
+
attr_accessor :verbose
|
59
|
+
attr :start
|
60
|
+
attr :terminal
|
61
|
+
|
62
|
+
def verbose!(value = true)
|
63
|
+
@verbose = value
|
64
|
+
end
|
65
|
+
|
66
|
+
def register_defaults(terminal)
|
67
|
+
Shell.register(terminal)
|
68
|
+
Error.register(terminal)
|
69
|
+
end
|
70
|
+
|
71
|
+
UNKNOWN = 'unknown'
|
72
|
+
|
73
|
+
def call(subject = nil, *arguments, name: nil, severity: UNKNOWN, &block)
|
74
|
+
prefix = build_prefix(name || severity.to_s)
|
75
|
+
indent = " " * prefix.size
|
76
|
+
|
77
|
+
buffer = Buffer.new("#{indent}| ")
|
78
|
+
|
79
|
+
if subject
|
80
|
+
format_subject(severity, prefix, subject, buffer)
|
81
|
+
end
|
82
|
+
|
83
|
+
arguments.each do |argument|
|
84
|
+
format_argument(argument, buffer)
|
85
|
+
end
|
86
|
+
|
87
|
+
if block_given?
|
88
|
+
if block.arity.zero?
|
89
|
+
format_argument(yield, buffer)
|
90
|
+
else
|
91
|
+
yield(buffer, @terminal)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
@io.write buffer.string
|
96
|
+
end
|
97
|
+
|
98
|
+
protected
|
99
|
+
|
100
|
+
def format_argument(argument, output)
|
101
|
+
case argument
|
102
|
+
when Exception
|
103
|
+
Error.new(argument).format(output, @terminal, @verbose)
|
104
|
+
when Generic
|
105
|
+
argument.format(output, @terminal, @verbose)
|
106
|
+
else
|
107
|
+
format_value(argument, output)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def format_subject(severity, prefix, subject, output)
|
112
|
+
prefix_style = @terminal[severity]
|
113
|
+
|
114
|
+
if @verbose
|
115
|
+
suffix = " #{@terminal[:logger_suffix]}[pid=#{Process.pid}]#{@terminal.reset}"
|
116
|
+
end
|
117
|
+
|
118
|
+
output.puts "#{@terminal[:logger_prefix]}#{subject}#{@terminal.reset}#{suffix}", prefix: "#{prefix_style}#{prefix}:#{@terminal.reset} "
|
119
|
+
end
|
120
|
+
|
121
|
+
def format_value(value, output)
|
122
|
+
string = value.to_s
|
123
|
+
|
124
|
+
string.each_line do |line|
|
125
|
+
output.puts "#{line}"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def time_offset_prefix
|
130
|
+
offset = Time.now - @start
|
131
|
+
minutes = (offset/60).floor
|
132
|
+
seconds = (offset - (minutes*60))
|
133
|
+
|
134
|
+
if minutes > 0
|
135
|
+
"#{minutes}m#{seconds.floor}s"
|
136
|
+
else
|
137
|
+
"#{seconds.round(2)}s"
|
138
|
+
end.rjust(6)
|
139
|
+
end
|
140
|
+
|
141
|
+
def build_prefix(name)
|
142
|
+
if @verbose
|
143
|
+
"#{time_offset_prefix} #{name.rjust(8)}"
|
144
|
+
else
|
145
|
+
time_offset_prefix
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|