console 1.29.3 → 1.30.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
- checksums.yaml.gz.sig +0 -0
- data/lib/console/capture.rb +26 -1
- data/lib/console/clock.rb +6 -1
- data/lib/console/compatible/logger.rb +30 -1
- data/lib/console/config.rb +93 -0
- data/lib/console/event/failure.rb +32 -3
- data/lib/console/event/generic.rb +14 -0
- data/lib/console/event/spawn.rb +38 -6
- data/lib/console/event.rb +6 -0
- data/lib/console/filter.rb +62 -2
- data/lib/console/format/safe.rb +35 -7
- data/lib/console/format.rb +3 -0
- data/lib/console/interface.rb +17 -9
- data/lib/console/logger.rb +22 -37
- data/lib/console/output/default.rb +11 -5
- data/lib/console/output/failure.rb +8 -1
- data/lib/console/output/null.rb +4 -1
- data/lib/console/output/sensitive.rb +41 -0
- data/lib/console/output/serialized.rb +25 -4
- data/lib/console/output/split.rb +11 -0
- data/lib/console/output/terminal.rb +66 -14
- data/lib/console/output/wrapper.rb +11 -0
- data/lib/console/output.rb +11 -0
- data/lib/console/progress.rb +55 -8
- data/lib/console/resolver.rb +18 -1
- data/lib/console/terminal/formatter/failure.rb +17 -5
- data/lib/console/terminal/formatter/progress.rb +15 -2
- data/lib/console/terminal/formatter/spawn.rb +15 -4
- data/lib/console/terminal/formatter.rb +16 -0
- data/lib/console/terminal/text.rb +60 -19
- data/lib/console/terminal/xterm.rb +16 -1
- data/lib/console/terminal.rb +6 -8
- data/lib/console/version.rb +1 -1
- data/lib/console/warn.rb +1 -1
- data/lib/console.rb +1 -0
- data/readme.md +7 -1
- data/releases.md +24 -1
- data.tar.gz.sig +0 -0
- metadata +4 -2
- metadata.gz.sig +0 -0
@@ -5,21 +5,32 @@
|
|
5
5
|
|
6
6
|
module Console
|
7
7
|
module Output
|
8
|
+
# A generic wrapper for output handling.
|
8
9
|
class Wrapper
|
10
|
+
# Create a new wrapper output.
|
11
|
+
#
|
12
|
+
# @parameter delegate [Console::Output] The output to delegate to.
|
13
|
+
# @parameter options [Hash] Additional options to customize the output.
|
9
14
|
def initialize(delegate, **options)
|
10
15
|
@delegate = delegate
|
11
16
|
end
|
12
17
|
|
18
|
+
# @attribute [Console::Output] The output to delegate to.
|
13
19
|
attr :delegate
|
14
20
|
|
21
|
+
# The last output is the last output of the delegate.
|
15
22
|
def last_output
|
16
23
|
@delegate.last_output
|
17
24
|
end
|
18
25
|
|
26
|
+
# Set the verbose flag for the delegate.
|
27
|
+
#
|
28
|
+
# @parameter value [Boolean] The new value.
|
19
29
|
def verbose!(value = true)
|
20
30
|
@delegate.verbose!(value)
|
21
31
|
end
|
22
32
|
|
33
|
+
# Invoke the delegate.
|
23
34
|
def call(...)
|
24
35
|
@delegate.call(...)
|
25
36
|
end
|
data/lib/console/output.rb
CHANGED
@@ -9,7 +9,18 @@ require_relative "output/terminal"
|
|
9
9
|
require_relative "output/null"
|
10
10
|
|
11
11
|
module Console
|
12
|
+
# Output handling.
|
12
13
|
module Output
|
14
|
+
# Create a new output based on the environment.
|
15
|
+
#
|
16
|
+
# The environment variable `CONSOLE_OUTPUT` can be used to specify a list of output classes to wrap around the output. If not specified the {Default} output is used.
|
17
|
+
#
|
18
|
+
# The output argument is deliberately unders-specified but can be an IO object or an instance of {Output}.
|
19
|
+
#
|
20
|
+
# @parameter output [Console::Output] The output to wrap OR an IO object.
|
21
|
+
# @parameter env [Hash] The environment to read configuration from.
|
22
|
+
# @parameter options [Hash] Additional options to customize the output.
|
23
|
+
# @returns [Console::Output] The output instance.
|
13
24
|
def self.new(output = nil, env = ENV, **options)
|
14
25
|
if names = env["CONSOLE_OUTPUT"]
|
15
26
|
names = names.split(",").reverse
|
data/lib/console/progress.rb
CHANGED
@@ -7,16 +7,24 @@
|
|
7
7
|
require_relative "clock"
|
8
8
|
|
9
9
|
module Console
|
10
|
+
# A simple progress indicator
|
10
11
|
class Progress
|
12
|
+
# @deprecated Use {Clock.now} instead.
|
11
13
|
def self.now
|
12
|
-
|
14
|
+
Clock.now
|
13
15
|
end
|
14
16
|
|
17
|
+
# Create a new progress indicator.
|
18
|
+
#
|
19
|
+
# @parameter subject [Object] The subject of the progress indicator.
|
20
|
+
# @parameter total [Integer] The total number of steps.
|
21
|
+
# @parameter minimum_output_duration [Numeric] The minimum duration between outputs.
|
22
|
+
# @parameter options [Hash] Additional options to customize the output.
|
15
23
|
def initialize(subject, total = 0, minimum_output_duration: 0.1, **options)
|
16
24
|
@subject = subject
|
17
25
|
@options = options
|
18
26
|
|
19
|
-
@start_time =
|
27
|
+
@start_time = Clock.now
|
20
28
|
|
21
29
|
@last_output_time = nil
|
22
30
|
@minimum_output_duration = minimum_output_duration
|
@@ -25,34 +33,53 @@ module Console
|
|
25
33
|
@total = total
|
26
34
|
end
|
27
35
|
|
36
|
+
# @attribute [Object] The subject of the progress indicator.
|
28
37
|
attr :subject
|
38
|
+
|
39
|
+
# @attribute [Numeric] The minimum duration between outputs.
|
40
|
+
attr :minimum_output_duration
|
41
|
+
|
42
|
+
# @attribute [Time] The time the progress indicator was started.
|
43
|
+
attr :start_time
|
44
|
+
|
45
|
+
# @attribute [Numeric] The current number of steps completed.
|
29
46
|
attr :current
|
47
|
+
|
48
|
+
# @attribute [Numeric] The total number of steps.
|
30
49
|
attr :total
|
31
50
|
|
51
|
+
# @returns [Numeric] The duration since the progress indicator was started.
|
32
52
|
def duration
|
33
|
-
|
53
|
+
Clock.now - @start_time
|
34
54
|
end
|
35
55
|
|
56
|
+
# @returns [Rational] The ratio of steps completed to total steps.
|
36
57
|
def ratio
|
37
58
|
Rational(@current.to_f, @total.to_f)
|
38
59
|
end
|
39
60
|
|
61
|
+
# @returns [Numeric] The number of steps remaining.
|
40
62
|
def remaining
|
41
63
|
@total - @current
|
42
64
|
end
|
43
65
|
|
66
|
+
# @returns [Numeric | Nil] The average duration per step, or `nil` if no steps have been completed.
|
44
67
|
def average_duration
|
45
68
|
if @current > 0
|
46
69
|
duration / @current
|
47
70
|
end
|
48
71
|
end
|
49
72
|
|
73
|
+
# @returns [Numeric | Nil] The estimated remaining time, or `nil` if no steps have been completed.
|
50
74
|
def estimated_remaining_time
|
51
75
|
if average_duration = self.average_duration
|
52
76
|
average_duration * remaining
|
53
77
|
end
|
54
78
|
end
|
55
79
|
|
80
|
+
# Generate an appropriate event for the progress indicator.
|
81
|
+
#
|
82
|
+
# @returns [Hash] The progress indicator as a hash.
|
56
83
|
def to_hash
|
57
84
|
Hash.new.tap do |hash|
|
58
85
|
hash[:type] = :progress
|
@@ -64,30 +91,44 @@ module Console
|
|
64
91
|
end
|
65
92
|
end
|
66
93
|
|
94
|
+
# Increment the progress indicator by the given amount.
|
95
|
+
#
|
96
|
+
# @parameter amount [Numeric] The amount to increment by.
|
97
|
+
# @returns [Progress] The progress indicator itself.
|
67
98
|
def increment(amount = 1)
|
68
99
|
@current += amount
|
69
100
|
|
70
101
|
if output?
|
71
102
|
Console.call(@subject, self.to_s, event: self.to_hash, **@options)
|
72
|
-
@last_output_time =
|
103
|
+
@last_output_time = Clock.now
|
73
104
|
end
|
74
105
|
|
75
106
|
return self
|
76
107
|
end
|
77
108
|
|
109
|
+
# Resize the progress indicator to the given total.
|
110
|
+
#
|
111
|
+
# @parameter total [Numeric] The new total number of steps.
|
112
|
+
# @returns [Progress] The progress indicator itself.
|
78
113
|
def resize(total)
|
79
114
|
@total = total
|
80
115
|
|
81
116
|
Console.call(@subject, self.to_s, event: self.to_hash, **@options)
|
82
|
-
@last_output_time =
|
117
|
+
@last_output_time = Clock.now
|
83
118
|
|
84
119
|
return self
|
85
120
|
end
|
86
121
|
|
87
|
-
|
88
|
-
|
122
|
+
# Augment the progress indicator with additional information.
|
123
|
+
#
|
124
|
+
# @parameter *arguments [Array] The arguments to log.
|
125
|
+
# @parameter **options [Hash] Additional options to log.
|
126
|
+
# @parameter &block [Proc] An optional block used to generate the log message.
|
127
|
+
def mark(*arguments, **options, &block)
|
128
|
+
Console.call(@subject, *arguments, **options, **@options, &block)
|
89
129
|
end
|
90
130
|
|
131
|
+
# @returns [String] A human-readable representation of the progress indicator.
|
91
132
|
def to_s
|
92
133
|
if estimated_remaining_time = self.estimated_remaining_time
|
93
134
|
"#{@current}/#{@total} completed in #{Clock.formatted_duration(self.duration)}, #{Clock.formatted_duration(estimated_remaining_time)} remaining."
|
@@ -98,12 +139,18 @@ module Console
|
|
98
139
|
|
99
140
|
private
|
100
141
|
|
142
|
+
# Compute a time delta since the last output, used for rate limiting the output.
|
143
|
+
#
|
144
|
+
# @returns [Numeric | Nil] The duration since the last output.
|
101
145
|
def duration_since_last_output
|
102
146
|
if @last_output_time
|
103
|
-
|
147
|
+
Clock.now - @last_output_time
|
104
148
|
end
|
105
149
|
end
|
106
150
|
|
151
|
+
# Whether an output should be generated at this time, taking into account the remaining steps, and the duration since the last output.
|
152
|
+
#
|
153
|
+
# @returns [Boolean] Whether an output should be generated.
|
107
154
|
def output?
|
108
155
|
if remaining.zero?
|
109
156
|
return true
|
data/lib/console/resolver.rb
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
require_relative "filter"
|
8
8
|
|
9
9
|
module Console
|
10
|
+
# Represents a class resolver that can be used to set log levels for different classes as they become available.
|
10
11
|
class Resolver
|
11
12
|
# You can change the log level for different classes using CONSOLE_$LEVEL env vars.
|
12
13
|
#
|
@@ -16,7 +17,6 @@ module Console
|
|
16
17
|
#
|
17
18
|
# @parameter logger [Logger] A logger instance to set the logging levels on.
|
18
19
|
# @parameter env [Hash] The environment to read levels from.
|
19
|
-
#
|
20
20
|
# @returns [Nil] If there were no custom logging levels specified in the environment.
|
21
21
|
# @returns [Resolver] If there were custom logging levels, then the created resolver is returned.
|
22
22
|
def self.default_resolver(logger, env = ENV)
|
@@ -59,12 +59,21 @@ module Console
|
|
59
59
|
return resolver
|
60
60
|
end
|
61
61
|
|
62
|
+
# Create a new class resolver.
|
62
63
|
def initialize
|
63
64
|
@names = {}
|
64
65
|
|
65
66
|
@trace_point = TracePoint.new(:class, &self.method(:resolve))
|
66
67
|
end
|
67
68
|
|
69
|
+
# Bind the given class names to the given block. When the class name is resolved into an actual class, the block will be called with the class as an argument.
|
70
|
+
#
|
71
|
+
# If the class is already defined, the block will be called immediately.
|
72
|
+
#
|
73
|
+
# If the class is not defined, the block will be called when the class is defined, using a trace point.
|
74
|
+
#
|
75
|
+
# @parameter names [Array(String)] The class names to bind.
|
76
|
+
# @parameter block [Proc] The block to call when the class is resolved.
|
68
77
|
def bind(names, &block)
|
69
78
|
names.each do |name|
|
70
79
|
if klass = Object.const_get(name) rescue nil
|
@@ -81,10 +90,18 @@ module Console
|
|
81
90
|
end
|
82
91
|
end
|
83
92
|
|
93
|
+
# @returns [Boolean] True if the resolver is waiting for classes to be defined.
|
84
94
|
def waiting?
|
85
95
|
@trace_point.enabled?
|
86
96
|
end
|
87
97
|
|
98
|
+
# Invoked by the trace point when a class is defined.
|
99
|
+
#
|
100
|
+
# This will call the block associated with the class name, if any, and remove it from the list of names to resolve.
|
101
|
+
#
|
102
|
+
# If the list of names is empty, the trace point will be disabled.
|
103
|
+
#
|
104
|
+
# @parameter trace_point [TracePoint] The trace point that triggered the event.
|
88
105
|
def resolve(trace_point)
|
89
106
|
if block = @names.delete(trace_point.self.to_s)
|
90
107
|
block.call(trace_point.self)
|
@@ -6,9 +6,14 @@
|
|
6
6
|
module Console
|
7
7
|
module Terminal
|
8
8
|
module Formatter
|
9
|
+
# Format a failure event, including the exception message and backtrace.
|
9
10
|
class Failure
|
11
|
+
# The key used to identify this formatter.
|
10
12
|
KEY = :failure
|
11
13
|
|
14
|
+
# Create a new failure formatter.
|
15
|
+
#
|
16
|
+
# @param terminal [Terminal::Text] The terminal to use for formatting.
|
12
17
|
def initialize(terminal)
|
13
18
|
@terminal = terminal
|
14
19
|
|
@@ -19,7 +24,14 @@ module Console
|
|
19
24
|
@terminal[:exception_message] ||= @terminal.style(:default)
|
20
25
|
end
|
21
26
|
|
22
|
-
|
27
|
+
# Format the given event.
|
28
|
+
#
|
29
|
+
# @parameter event [Hash] The event to format.
|
30
|
+
# @parameter stream [IO] The stream to write the formatted event to.
|
31
|
+
# @parameter prefix [String] The prefix to use before the title.
|
32
|
+
# @parameter verbose [Boolean] Whether to include additional information.
|
33
|
+
# @parameter options [Hash] Additional options.
|
34
|
+
def format(event, stream, prefix: nil, verbose: false, **options)
|
23
35
|
title = event[:class]
|
24
36
|
message = event[:message]
|
25
37
|
backtrace = event[:backtrace]
|
@@ -27,10 +39,10 @@ module Console
|
|
27
39
|
|
28
40
|
lines = message.lines.map(&:chomp)
|
29
41
|
|
30
|
-
|
42
|
+
stream.puts " #{prefix}#{@terminal[:exception_title]}#{title}#{@terminal.reset}: #{lines.shift}"
|
31
43
|
|
32
44
|
lines.each do |line|
|
33
|
-
|
45
|
+
stream.puts " #{@terminal[:exception_detail]}#{line}#{@terminal.reset}"
|
34
46
|
end
|
35
47
|
|
36
48
|
root_pattern = /^#{root}\// if root
|
@@ -44,11 +56,11 @@ module Console
|
|
44
56
|
style = :exception_backtrace_other
|
45
57
|
end
|
46
58
|
|
47
|
-
|
59
|
+
stream.puts " #{index == 0 ? "→" : " "} #{@terminal[style]}#{path}:#{offset}#{@terminal[:exception_message]} #{message}#{@terminal.reset}"
|
48
60
|
end
|
49
61
|
|
50
62
|
if cause = event[:cause]
|
51
|
-
format(cause,
|
63
|
+
format(cause, stream, prefix: "Caused by ", verbose: verbose, **options)
|
52
64
|
end
|
53
65
|
end
|
54
66
|
end
|
@@ -6,9 +6,12 @@
|
|
6
6
|
module Console
|
7
7
|
module Terminal
|
8
8
|
module Formatter
|
9
|
+
# Format a progress event, including the current progress and total.
|
9
10
|
class Progress
|
11
|
+
# The key used to identify this formatter.
|
10
12
|
KEY = :progress
|
11
13
|
|
14
|
+
# The block characters used to render the progress bar.
|
12
15
|
BLOCK = [
|
13
16
|
" ",
|
14
17
|
"▏",
|
@@ -21,12 +24,21 @@ module Console
|
|
21
24
|
"█",
|
22
25
|
]
|
23
26
|
|
27
|
+
# Create a new progress formatter.
|
28
|
+
#
|
29
|
+
# @param terminal [Terminal::Text] The terminal to use for formatting.
|
24
30
|
def initialize(terminal)
|
25
31
|
@terminal = terminal
|
26
32
|
@terminal[:progress_bar] ||= terminal.style(:blue, :white)
|
27
33
|
end
|
28
34
|
|
29
|
-
|
35
|
+
# Format the given event.
|
36
|
+
#
|
37
|
+
# @parameter event [Hash] The event to format.
|
38
|
+
# @parameter stream [IO] The stream to write the formatted event to.
|
39
|
+
# @parameter verbose [Boolean] Whether to include additional information.
|
40
|
+
# @parameter width [Integer] The width of the progress bar.
|
41
|
+
def format(event, stream, verbose: false, width: 80)
|
30
42
|
current = event[:current].to_f
|
31
43
|
total = event[:total].to_f
|
32
44
|
value = current / total
|
@@ -36,11 +48,12 @@ module Console
|
|
36
48
|
value = 1.0
|
37
49
|
end
|
38
50
|
|
39
|
-
|
51
|
+
stream.puts "#{@terminal[:progress_bar]}#{self.bar(value, width-10)}#{@terminal.reset} #{sprintf('%6.2f', value * 100)}%"
|
40
52
|
end
|
41
53
|
|
42
54
|
private
|
43
55
|
|
56
|
+
# Render a progress bar with the given value and width.
|
44
57
|
def bar(value, width)
|
45
58
|
blocks = width * value
|
46
59
|
full_blocks = blocks.floor
|
@@ -6,31 +6,42 @@
|
|
6
6
|
module Console
|
7
7
|
module Terminal
|
8
8
|
module Formatter
|
9
|
-
# Format spawn
|
9
|
+
# Format a spawn event, including the command and arguments.
|
10
10
|
class Spawn
|
11
|
+
# The key used to identify this formatter.
|
11
12
|
KEY = :spawn
|
12
13
|
|
14
|
+
# Create a new spawn formatter.
|
15
|
+
#
|
16
|
+
# @param terminal [Terminal::Text] The terminal to use for formatting.
|
13
17
|
def initialize(terminal)
|
14
18
|
@terminal = terminal
|
15
19
|
@terminal[:spawn_command] ||= @terminal.style(:blue, nil, :bold)
|
16
20
|
end
|
17
21
|
|
18
|
-
|
22
|
+
# Format the given event.
|
23
|
+
#
|
24
|
+
# @parameter event [Hash] The event to format.
|
25
|
+
# @parameter stream [IO] The stream to write the formatted event to.
|
26
|
+
# @parameter verbose [Boolean] Whether to include additional information.
|
27
|
+
# @parameter width [Integer] The width of the progress bar.
|
28
|
+
def format(event, stream, verbose: false, width: 80)
|
19
29
|
environment, arguments, options = event.values_at(:environment, :arguments, :options)
|
20
30
|
|
21
31
|
arguments = arguments.flatten.collect(&:to_s)
|
22
32
|
|
23
|
-
|
33
|
+
stream.puts "#{@terminal[:spawn_command]}#{arguments.join(' ')}#{@terminal.reset}#{chdir_string(options)}"
|
24
34
|
|
25
35
|
if verbose and environment
|
26
36
|
environment.each do |key, value|
|
27
|
-
|
37
|
+
stream.puts "export #{key}=#{value}"
|
28
38
|
end
|
29
39
|
end
|
30
40
|
end
|
31
41
|
|
32
42
|
private
|
33
43
|
|
44
|
+
# Generate a string to represent the working directory.
|
34
45
|
def chdir_string(options)
|
35
46
|
if options and chdir = options[:chdir]
|
36
47
|
" in #{chdir}"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2025, by Samuel Williams.
|
5
|
+
|
6
|
+
require_relative "formatter/progress"
|
7
|
+
require_relative "formatter/failure"
|
8
|
+
require_relative "formatter/spawn"
|
9
|
+
|
10
|
+
module Console
|
11
|
+
module Terminal
|
12
|
+
# Formatters for various types of events.
|
13
|
+
module Formatter
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -8,75 +8,116 @@ require "io/console"
|
|
8
8
|
module Console
|
9
9
|
# Styled terminal output.
|
10
10
|
module Terminal
|
11
|
+
# A simple text-based terminal output.
|
11
12
|
class Text
|
12
|
-
|
13
|
-
|
13
|
+
# Create a new text terminal output.
|
14
|
+
#
|
15
|
+
# @parameter stream [IO] The stream to write to.
|
16
|
+
def initialize(stream)
|
17
|
+
@stream = stream
|
14
18
|
@styles = {reset: self.reset}
|
15
19
|
end
|
16
20
|
|
21
|
+
# @attribute [IO] The stream to write to.
|
22
|
+
attr :stream
|
23
|
+
|
24
|
+
# Get the style associated with the given key.
|
25
|
+
#
|
26
|
+
# @parameter key [Symbol] The key to look up.
|
27
|
+
# @returns [String] The style associated with the key.
|
17
28
|
def [] key
|
18
29
|
@styles[key]
|
19
30
|
end
|
20
31
|
|
32
|
+
# Set the style associated with the given key.
|
33
|
+
#
|
34
|
+
# @parameter key [Symbol] The key to associate the style with.
|
35
|
+
# @parameter value [String] The style to associate with the key.
|
21
36
|
def []= key, value
|
22
37
|
@styles[key] = value
|
23
38
|
end
|
24
39
|
|
40
|
+
# @returns [Boolean] Whether the terminal supports colors.
|
25
41
|
def colors?
|
26
42
|
false
|
27
43
|
end
|
28
44
|
|
45
|
+
# @returns [Tuple(Integer, Integer)] The size of the terminal, or a default value of [24, 80].
|
46
|
+
def size
|
47
|
+
[24, 80]
|
48
|
+
end
|
49
|
+
|
50
|
+
# @returns [Integer] The width of the terminal.
|
29
51
|
def width
|
30
|
-
|
52
|
+
self.size.last
|
31
53
|
end
|
32
54
|
|
55
|
+
# Generate a style string for the given foreground, background, and attributes.
|
56
|
+
#
|
57
|
+
# @returns [String | Nil] The style string if colors are supported, otherwise nil.
|
33
58
|
def style(foreground, background = nil, *attributes)
|
34
59
|
end
|
35
60
|
|
61
|
+
# Generate a reset sequence.
|
62
|
+
#
|
63
|
+
# @returns [String | Nil] The reset sequence if colors are supported, otherwise nil.
|
36
64
|
def reset
|
37
65
|
end
|
38
66
|
|
67
|
+
# Write the given arguments to the output stream using the given style. The reset sequence is automatically appended.
|
68
|
+
#
|
69
|
+
# @parameter arguments [Array] The arguments to write.
|
70
|
+
# @parameter style [Symbol] The style to apply.
|
39
71
|
def write(*arguments, style: nil)
|
40
72
|
if style and prefix = self[style]
|
41
|
-
@
|
42
|
-
@
|
43
|
-
@
|
73
|
+
@stream.write(prefix)
|
74
|
+
@stream.write(*arguments)
|
75
|
+
@stream.write(self.reset)
|
44
76
|
else
|
45
|
-
@
|
77
|
+
@stream.write(*arguments)
|
46
78
|
end
|
47
79
|
end
|
48
80
|
|
81
|
+
# Write the given arguments to the output stream using the given style. The reset sequence is automatically appended.
|
82
|
+
#
|
83
|
+
# @parameter arguments [Array] The arguments to write, each on a new line.
|
84
|
+
# @parameter style [Symbol] The style to apply.
|
49
85
|
def puts(*arguments, style: nil)
|
50
86
|
if style and prefix = self[style]
|
51
|
-
@
|
52
|
-
@
|
53
|
-
@
|
87
|
+
@stream.write(prefix)
|
88
|
+
@stream.puts(*arguments)
|
89
|
+
@stream.write(self.reset)
|
54
90
|
else
|
55
|
-
@
|
91
|
+
@stream.puts(*arguments)
|
56
92
|
end
|
57
93
|
end
|
58
94
|
|
59
|
-
# Print
|
60
|
-
#
|
61
|
-
# When the argument is a
|
62
|
-
# When the argument is
|
95
|
+
# Print rich text to the output stream.
|
96
|
+
#
|
97
|
+
# - When the argument is a symbol, look up the style and inject it into the output stream.
|
98
|
+
# - When the argument is a proc/lambda, call it with self as the argument.
|
99
|
+
# - When the argument is anything else, write it directly to the output.
|
100
|
+
#
|
101
|
+
# @parameter arguments [Array] The arguments to print.
|
63
102
|
def print(*arguments)
|
64
103
|
arguments.each do |argument|
|
65
104
|
case argument
|
66
105
|
when Symbol
|
67
|
-
@
|
106
|
+
@stream.write(self[argument])
|
68
107
|
when Proc
|
69
108
|
argument.call(self)
|
70
109
|
else
|
71
|
-
@
|
110
|
+
@stream.write(argument)
|
72
111
|
end
|
73
112
|
end
|
74
113
|
end
|
75
114
|
|
76
|
-
# Print
|
115
|
+
# Print rich text to the output stream, followed by the reset sequence and a newline.
|
116
|
+
#
|
117
|
+
# @parameter arguments [Array] The arguments to print.
|
77
118
|
def print_line(*arguments)
|
78
119
|
print(*arguments)
|
79
|
-
@
|
120
|
+
@stream.puts(self.reset)
|
80
121
|
end
|
81
122
|
end
|
82
123
|
end
|
@@ -10,7 +10,9 @@ require_relative "text"
|
|
10
10
|
module Console
|
11
11
|
# Styled terminal output.
|
12
12
|
module Terminal
|
13
|
+
# XTerm style terminal output.
|
13
14
|
class XTerm < Text
|
15
|
+
# XTerm color codes.
|
14
16
|
COLORS = {
|
15
17
|
black: 0,
|
16
18
|
red: 1,
|
@@ -23,6 +25,7 @@ module Console
|
|
23
25
|
default: 9,
|
24
26
|
}.freeze
|
25
27
|
|
28
|
+
# XTerm attribute codes.
|
26
29
|
ATTRIBUTES = {
|
27
30
|
normal: 0,
|
28
31
|
bold: 1,
|
@@ -35,21 +38,30 @@ module Console
|
|
35
38
|
hidden: 8,
|
36
39
|
}.freeze
|
37
40
|
|
41
|
+
# Whether the terminal supports colors.
|
38
42
|
def colors?
|
39
43
|
true
|
40
44
|
end
|
41
45
|
|
46
|
+
# The size of the terminal.
|
42
47
|
def size
|
43
|
-
@
|
48
|
+
@stream.winsize
|
44
49
|
rescue Errno::ENOTTY
|
45
50
|
# Fake it...
|
46
51
|
[24, 80]
|
47
52
|
end
|
48
53
|
|
54
|
+
# The width of the terminal.
|
49
55
|
def width
|
50
56
|
size.last
|
51
57
|
end
|
52
58
|
|
59
|
+
# Apply the given style to the output.
|
60
|
+
#
|
61
|
+
# @parameter foreground [Symbol] The foreground color.
|
62
|
+
# @parameter background [Symbol] The background color.
|
63
|
+
# @parameter attributes [Array(Symbol)] The attributes to apply.
|
64
|
+
# @returns [String] The style code.
|
53
65
|
def style(foreground, background = nil, *attributes)
|
54
66
|
tokens = []
|
55
67
|
|
@@ -68,6 +80,9 @@ module Console
|
|
68
80
|
return "\e[#{tokens.join(';')}m"
|
69
81
|
end
|
70
82
|
|
83
|
+
# Reset the style.
|
84
|
+
#
|
85
|
+
# @returns [String] The reset code.
|
71
86
|
def reset
|
72
87
|
"\e[0m"
|
73
88
|
end
|
data/lib/console/terminal.rb
CHANGED
@@ -5,18 +5,16 @@
|
|
5
5
|
|
6
6
|
require_relative "terminal/text"
|
7
7
|
require_relative "terminal/xterm"
|
8
|
-
|
9
|
-
require_relative "terminal/formatter/progress"
|
10
|
-
require_relative "terminal/formatter/failure"
|
11
|
-
require_relative "terminal/formatter/spawn"
|
8
|
+
require_relative "terminal/formatter"
|
12
9
|
|
13
10
|
module Console
|
14
11
|
module Terminal
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
# Create a new terminal output for the given stream.
|
13
|
+
def self.for(stream)
|
14
|
+
if stream.tty?
|
15
|
+
XTerm.new(stream)
|
18
16
|
else
|
19
|
-
Text.new(
|
17
|
+
Text.new(stream)
|
20
18
|
end
|
21
19
|
end
|
22
20
|
end
|
data/lib/console/version.rb
CHANGED
data/lib/console/warn.rb
CHANGED