console 1.19.0 → 1.29.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/bake/console.rb +3 -3
- data/lib/console/adapter.rb +2 -1
- data/lib/console/capture.rb +46 -17
- data/lib/console/compatible/logger.rb +4 -3
- data/lib/console/event/failure.rb +43 -39
- data/lib/console/event/generic.rb +9 -6
- data/lib/console/event/spawn.rb +35 -27
- data/lib/console/event.rb +3 -4
- data/lib/console/filter.rb +24 -10
- data/lib/console/format/safe.rb +136 -0
- data/lib/console/format.rb +14 -0
- data/lib/console/interface.rb +53 -0
- data/lib/console/logger.rb +17 -16
- data/lib/console/output/default.rb +8 -5
- data/lib/console/output/failure.rb +32 -0
- data/lib/console/output/null.rb +5 -1
- data/lib/console/output/sensitive.rb +12 -10
- data/lib/console/{serialized/logger.rb → output/serialized.rb} +14 -49
- data/lib/console/output/split.rb +3 -3
- data/lib/console/{terminal/logger.rb → output/terminal.rb} +98 -54
- data/lib/console/output/wrapper.rb +28 -0
- data/lib/console/output.rb +7 -8
- data/lib/console/progress.rb +20 -9
- data/lib/console/resolver.rb +5 -5
- data/lib/console/terminal/formatter/failure.rb +57 -0
- data/lib/console/terminal/formatter/progress.rb +58 -0
- data/lib/console/terminal/formatter/spawn.rb +42 -0
- data/lib/console/terminal/text.rb +6 -2
- data/lib/console/terminal/xterm.rb +10 -3
- data/lib/console/terminal.rb +19 -2
- data/lib/console/version.rb +2 -2
- data/lib/console/warn.rb +33 -0
- data/lib/console.rb +4 -22
- data/license.md +5 -1
- data/readme.md +39 -2
- data/releases.md +25 -0
- data.tar.gz.sig +0 -0
- metadata +31 -92
- metadata.gz.sig +0 -0
- data/lib/console/buffer.rb +0 -25
- data/lib/console/event/progress.rb +0 -60
- data/lib/console/output/json.rb +0 -16
- data/lib/console/output/text.rb +0 -16
- data/lib/console/output/xterm.rb +0 -16
- data/lib/console/split.rb +0 -10
data/lib/console/progress.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2020-
|
4
|
+
# Copyright, 2020-2024, by Samuel Williams.
|
5
|
+
# Copyright, 2022, by Anton Sozontov.
|
5
6
|
|
6
|
-
require_relative
|
7
|
-
require_relative 'clock'
|
7
|
+
require_relative "clock"
|
8
8
|
|
9
9
|
module Console
|
10
10
|
class Progress
|
@@ -12,9 +12,9 @@ module Console
|
|
12
12
|
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
13
13
|
end
|
14
14
|
|
15
|
-
def initialize(
|
16
|
-
@output = output
|
15
|
+
def initialize(subject, total = 0, minimum_output_duration: 0.1, **options)
|
17
16
|
@subject = subject
|
17
|
+
@options = options
|
18
18
|
|
19
19
|
@start_time = Progress.now
|
20
20
|
|
@@ -53,11 +53,22 @@ module Console
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
+
def to_hash
|
57
|
+
Hash.new.tap do |hash|
|
58
|
+
hash[:type] = :progress
|
59
|
+
hash[:current] = @current
|
60
|
+
hash[:total] = @total
|
61
|
+
|
62
|
+
hash[:duration] = self.duration
|
63
|
+
hash[:estimated_remaining_time] = self.estimated_remaining_time
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
56
67
|
def increment(amount = 1)
|
57
68
|
@current += amount
|
58
69
|
|
59
70
|
if output?
|
60
|
-
|
71
|
+
Console.call(@subject, self.to_s, event: self.to_hash, **@options)
|
61
72
|
@last_output_time = Progress.now
|
62
73
|
end
|
63
74
|
|
@@ -67,14 +78,14 @@ module Console
|
|
67
78
|
def resize(total)
|
68
79
|
@total = total
|
69
80
|
|
70
|
-
|
81
|
+
Console.call(@subject, self.to_s, event: self.to_hash, **@options)
|
71
82
|
@last_output_time = Progress.now
|
72
83
|
|
73
84
|
return self
|
74
85
|
end
|
75
86
|
|
76
|
-
def mark(
|
77
|
-
|
87
|
+
def mark(*arguments, **options)
|
88
|
+
Console.call(@subject, *arguments, **options, **@options)
|
78
89
|
end
|
79
90
|
|
80
91
|
def to_s
|
data/lib/console/resolver.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-
|
4
|
+
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
# Copyright, 2021, by Robert Schulze.
|
6
6
|
|
7
|
-
require_relative
|
7
|
+
require_relative "filter"
|
8
8
|
|
9
9
|
module Console
|
10
10
|
class Resolver
|
@@ -22,12 +22,12 @@ module Console
|
|
22
22
|
def self.default_resolver(logger, env = ENV)
|
23
23
|
# Find all CONSOLE_$LEVEL variables from environment:
|
24
24
|
levels = logger.class::LEVELS
|
25
|
-
.map{|label, level| [level, env["CONSOLE_#{label.upcase}"]&.split(
|
25
|
+
.map{|label, level| [level, env["CONSOLE_#{label.upcase}"]&.split(",")]}
|
26
26
|
.to_h
|
27
27
|
.compact
|
28
28
|
|
29
|
-
off_klasses = env[
|
30
|
-
on_klasses = env[
|
29
|
+
off_klasses = env["CONSOLE_OFF"]&.split(",")
|
30
|
+
on_klasses = env["CONSOLE_ON"]&.split(",")
|
31
31
|
|
32
32
|
resolver = nil
|
33
33
|
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2024, by Samuel Williams.
|
5
|
+
|
6
|
+
module Console
|
7
|
+
module Terminal
|
8
|
+
module Formatter
|
9
|
+
class Failure
|
10
|
+
KEY = :failure
|
11
|
+
|
12
|
+
def initialize(terminal)
|
13
|
+
@terminal = terminal
|
14
|
+
|
15
|
+
@terminal[:exception_title] ||= @terminal.style(:red, nil, :bold)
|
16
|
+
@terminal[:exception_detail] ||= @terminal.style(:yellow)
|
17
|
+
@terminal[:exception_backtrace] ||= @terminal.style(:red)
|
18
|
+
@terminal[:exception_backtrace_other] ||= @terminal.style(:red, nil, :faint)
|
19
|
+
@terminal[:exception_message] ||= @terminal.style(:default)
|
20
|
+
end
|
21
|
+
|
22
|
+
def format(event, output, prefix: nil, verbose: false, width: 80)
|
23
|
+
title = event[:class]
|
24
|
+
message = event[:message]
|
25
|
+
backtrace = event[:backtrace]
|
26
|
+
root = event[:root]
|
27
|
+
|
28
|
+
lines = message.lines.map(&:chomp)
|
29
|
+
|
30
|
+
output.puts " #{prefix}#{@terminal[:exception_title]}#{title}#{@terminal.reset}: #{lines.shift}"
|
31
|
+
|
32
|
+
lines.each do |line|
|
33
|
+
output.puts " #{@terminal[:exception_detail]}#{line}#{@terminal.reset}"
|
34
|
+
end
|
35
|
+
|
36
|
+
root_pattern = /^#{root}\// if root
|
37
|
+
|
38
|
+
backtrace&.each_with_index do |line, index|
|
39
|
+
path, offset, message = line.split(":", 3)
|
40
|
+
style = :exception_backtrace
|
41
|
+
|
42
|
+
# Make the path a bit more readable:
|
43
|
+
if root_pattern and path.sub!(root_pattern, "").nil?
|
44
|
+
style = :exception_backtrace_other
|
45
|
+
end
|
46
|
+
|
47
|
+
output.puts " #{index == 0 ? "→" : " "} #{@terminal[style]}#{path}:#{offset}#{@terminal[:exception_message]} #{message}#{@terminal.reset}"
|
48
|
+
end
|
49
|
+
|
50
|
+
if cause = event[:cause]
|
51
|
+
format(cause, output, prefix: "Caused by ", verbose: verbose, width: width)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2020-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
module Console
|
7
|
+
module Terminal
|
8
|
+
module Formatter
|
9
|
+
class Progress
|
10
|
+
KEY = :progress
|
11
|
+
|
12
|
+
BLOCK = [
|
13
|
+
" ",
|
14
|
+
"▏",
|
15
|
+
"▎",
|
16
|
+
"▍",
|
17
|
+
"▌",
|
18
|
+
"▋",
|
19
|
+
"▊",
|
20
|
+
"▉",
|
21
|
+
"█",
|
22
|
+
]
|
23
|
+
|
24
|
+
def initialize(terminal)
|
25
|
+
@terminal = terminal
|
26
|
+
@terminal[:progress_bar] ||= terminal.style(:blue, :white)
|
27
|
+
end
|
28
|
+
|
29
|
+
def format(event, output, verbose: false, width: 80)
|
30
|
+
current = event[:current].to_f
|
31
|
+
total = event[:total].to_f
|
32
|
+
value = current / total
|
33
|
+
|
34
|
+
# Clamp value to 1.0 to avoid rendering issues:
|
35
|
+
if value > 1.0
|
36
|
+
value = 1.0
|
37
|
+
end
|
38
|
+
|
39
|
+
output.puts "#{@terminal[:progress_bar]}#{self.bar(value, width-10)}#{@terminal.reset} #{sprintf('%6.2f', value * 100)}%"
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def bar(value, width)
|
45
|
+
blocks = width * value
|
46
|
+
full_blocks = blocks.floor
|
47
|
+
partial_block = ((blocks - full_blocks) * BLOCK.size).floor
|
48
|
+
|
49
|
+
if partial_block.zero?
|
50
|
+
BLOCK.last * full_blocks
|
51
|
+
else
|
52
|
+
"#{BLOCK.last * full_blocks}#{BLOCK[partial_block]}"
|
53
|
+
end.ljust(width)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2019-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
module Console
|
7
|
+
module Terminal
|
8
|
+
module Formatter
|
9
|
+
# Format spawn events.
|
10
|
+
class Spawn
|
11
|
+
KEY = :spawn
|
12
|
+
|
13
|
+
def initialize(terminal)
|
14
|
+
@terminal = terminal
|
15
|
+
@terminal[:spawn_command] ||= @terminal.style(:blue, nil, :bold)
|
16
|
+
end
|
17
|
+
|
18
|
+
def format(event, output, verbose: false, width: 80)
|
19
|
+
environment, arguments, options = event.values_at(:environment, :arguments, :options)
|
20
|
+
|
21
|
+
arguments = arguments.flatten.collect(&:to_s)
|
22
|
+
|
23
|
+
output.puts "#{@terminal[:spawn_command]}#{arguments.join(' ')}#{@terminal.reset}#{chdir_string(options)}"
|
24
|
+
|
25
|
+
if verbose and environment
|
26
|
+
environment.each do |key, value|
|
27
|
+
output.puts "export #{key}=#{value}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def chdir_string(options)
|
35
|
+
if options and chdir = options[:chdir]
|
36
|
+
" in #{chdir}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-
|
4
|
+
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
6
|
+
require "io/console"
|
7
7
|
|
8
8
|
module Console
|
9
9
|
# Styled terminal output.
|
@@ -26,6 +26,10 @@ module Console
|
|
26
26
|
false
|
27
27
|
end
|
28
28
|
|
29
|
+
def width
|
30
|
+
80
|
31
|
+
end
|
32
|
+
|
29
33
|
def style(foreground, background = nil, *attributes)
|
30
34
|
end
|
31
35
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-
|
4
|
+
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
6
|
+
require "io/console"
|
7
7
|
|
8
|
-
require_relative
|
8
|
+
require_relative "text"
|
9
9
|
|
10
10
|
module Console
|
11
11
|
# Styled terminal output.
|
@@ -41,6 +41,13 @@ module Console
|
|
41
41
|
|
42
42
|
def size
|
43
43
|
@output.winsize
|
44
|
+
rescue Errno::ENOTTY
|
45
|
+
# Fake it...
|
46
|
+
[24, 80]
|
47
|
+
end
|
48
|
+
|
49
|
+
def width
|
50
|
+
size.last
|
44
51
|
end
|
45
52
|
|
46
53
|
def style(foreground, background = nil, *attributes)
|
data/lib/console/terminal.rb
CHANGED
@@ -1,6 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-
|
4
|
+
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "terminal/text"
|
7
|
+
require_relative "terminal/xterm"
|
8
|
+
|
9
|
+
require_relative "terminal/formatter/progress"
|
10
|
+
require_relative "terminal/formatter/failure"
|
11
|
+
require_relative "terminal/formatter/spawn"
|
12
|
+
|
13
|
+
module Console
|
14
|
+
module Terminal
|
15
|
+
def self.for(io)
|
16
|
+
if io.tty?
|
17
|
+
XTerm.new(io)
|
18
|
+
else
|
19
|
+
Text.new(io)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/console/version.rb
CHANGED
data/lib/console/warn.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require_relative "logger"
|
7
|
+
|
8
|
+
module Console
|
9
|
+
# Whether the current fiber is emitting a warning.
|
10
|
+
Fiber.attr_accessor :console_warn
|
11
|
+
|
12
|
+
# Redirect warnings to Console.warn.
|
13
|
+
module Warn
|
14
|
+
# Redirect warnings to {Console.warn}.
|
15
|
+
def warn(message, **options)
|
16
|
+
fiber = Fiber.current
|
17
|
+
|
18
|
+
# We do this to be extra pendantic about avoiding infinite recursion.
|
19
|
+
return super if fiber.console_warn
|
20
|
+
|
21
|
+
begin
|
22
|
+
fiber.console_warn = true
|
23
|
+
message.chomp!
|
24
|
+
|
25
|
+
Console::Logger.instance.warn(message, **options)
|
26
|
+
ensure
|
27
|
+
fiber.console_warn = false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
::Warning.extend(Warn)
|
33
|
+
end
|
data/lib/console.rb
CHANGED
@@ -1,32 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-
|
4
|
+
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
# Copyright, 2019, by Bryan Powell.
|
6
6
|
# Copyright, 2020, by Michael Adams.
|
7
7
|
# Copyright, 2021, by Cédric Boutillier.
|
8
8
|
|
9
|
-
require_relative
|
10
|
-
require_relative
|
9
|
+
require_relative "console/version"
|
10
|
+
require_relative "console/interface"
|
11
11
|
|
12
12
|
module Console
|
13
|
-
|
14
|
-
Logger.instance
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.logger= instance
|
18
|
-
Logger.instance= instance
|
19
|
-
end
|
20
|
-
|
21
|
-
def logger= logger
|
22
|
-
@logger = logger
|
23
|
-
end
|
24
|
-
|
25
|
-
def logger
|
26
|
-
@logger || Logger.instance
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.extended(klass)
|
30
|
-
klass.instance_variable_set(:@logger, nil)
|
31
|
-
end
|
13
|
+
Console.extend(Interface)
|
32
14
|
end
|
data/license.md
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
# MIT License
|
2
2
|
|
3
|
-
Copyright, 2019-
|
3
|
+
Copyright, 2019-2024, by Samuel Williams.
|
4
4
|
Copyright, 2019-2021, by Bryan Powell.
|
5
5
|
Copyright, 2019, by Cyril Roelandt.
|
6
6
|
Copyright, 2020, by Olle Jonsson.
|
7
7
|
Copyright, 2020, by Michael Adams.
|
8
8
|
Copyright, 2021, by Cédric Boutillier.
|
9
9
|
Copyright, 2021, by Robert Schulze.
|
10
|
+
Copyright, 2022, by Anton Sozontov.
|
11
|
+
Copyright, 2022, by William T. Nelson.
|
12
|
+
Copyright, 2023, by Felix Yan.
|
13
|
+
Copyright, 2024, by Patrik Wenger.
|
10
14
|
|
11
15
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
12
16
|
of this software and associated documentation files (the "Software"), to deal
|
data/readme.md
CHANGED
@@ -6,7 +6,7 @@ Provides beautiful console logging for Ruby applications. Implements fast, buffe
|
|
6
6
|
|
7
7
|
## Motivation
|
8
8
|
|
9
|
-
When Ruby decided to reverse the order of exception backtraces, I finally gave up using the built in logging and decided restore sanity to the output of my programs once and for all
|
9
|
+
When Ruby decided to reverse the order of exception backtraces, I finally gave up using the built in logging and decided restore sanity to the output of my programs once and for all\!
|
10
10
|
|
11
11
|
## Features
|
12
12
|
|
@@ -18,7 +18,29 @@ When Ruby decided to reverse the order of exception backtraces, I finally gave u
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
Please see the [project documentation](https://socketry.github.io/console).
|
21
|
+
Please see the [project documentation](https://socketry.github.io/console/) for more details.
|
22
|
+
|
23
|
+
- [Getting Started](https://socketry.github.io/console/guides/getting-started/index) - This guide explains how to use `console` for logging.
|
24
|
+
|
25
|
+
- [Command Line](https://socketry.github.io/console/guides/command-line/index) - This guide explains how the `console` gem can be controlled using environment variables.
|
26
|
+
|
27
|
+
- [Integration](https://socketry.github.io/console/guides/integration/index) - This guide explains how to integrate the `console` output into different systems.
|
28
|
+
|
29
|
+
- [Events](https://socketry.github.io/console/guides/events/index) - This guide explains how to log structured events with a well-defined schema.
|
30
|
+
|
31
|
+
## Releases
|
32
|
+
|
33
|
+
Please see the [project releases](https://socketry.github.io/console/releases/index) for all releases.
|
34
|
+
|
35
|
+
### v1.29.0
|
36
|
+
|
37
|
+
- Don't make `Kernel#warn` redirection to `Console.warn` the default behavior, you must `require 'console/warn'` to enable it.
|
38
|
+
- Remove deprecated `Console::Logger#failure`.
|
39
|
+
- [Consistent Handling of Exceptions](https://socketry.github.io/console/releases/index#consistent-handling-of-exceptions)
|
40
|
+
|
41
|
+
### v1.28.0
|
42
|
+
|
43
|
+
- Add support for `Kernel#warn` redirection to `Console.warn`.
|
22
44
|
|
23
45
|
## Contributing
|
24
46
|
|
@@ -29,3 +51,18 @@ We welcome contributions to this project.
|
|
29
51
|
3. Commit your changes (`git commit -am 'Add some feature'`).
|
30
52
|
4. Push to the branch (`git push origin my-new-feature`).
|
31
53
|
5. Create new Pull Request.
|
54
|
+
|
55
|
+
### Developer Certificate of Origin
|
56
|
+
|
57
|
+
In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
|
58
|
+
|
59
|
+
### Community Guidelines
|
60
|
+
|
61
|
+
This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
|
62
|
+
|
63
|
+
## See Also
|
64
|
+
|
65
|
+
- [console-adapter-rails](https://github.com/socketry/console-adapter-rails)
|
66
|
+
- [console-adapter-sidekiq](https://github.com/socketry/console-adapter-sidekiq)
|
67
|
+
- [console-output-datadog](https://github.com/socketry/console-output-datadog)
|
68
|
+
- [sus-fixtures-console](https://github.com/sus-rb/sus-fixtures-console)
|
data/releases.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Releases
|
2
|
+
|
3
|
+
## v1.29.0
|
4
|
+
|
5
|
+
- Don't make `Kernel#warn` redirection to `Console.warn` the default behavior, you must `require 'console/warn'` to enable it.
|
6
|
+
- Remove deprecated `Console::Logger#failure`.
|
7
|
+
|
8
|
+
### Consistent Handling of Exceptions
|
9
|
+
|
10
|
+
`Console.call` and all wrapper methods will now consistently handle exceptions that are the last positional argument or keyword argument. This means that the following code will work as expected:
|
11
|
+
|
12
|
+
``` ruby
|
13
|
+
begin
|
14
|
+
rescue => error
|
15
|
+
# Last positional argument:
|
16
|
+
Console.warn(self, "There may be an issue", error)
|
17
|
+
|
18
|
+
# Keyword argument (preferable):
|
19
|
+
Console.error(self, "There is an issue", exception: error)
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
## v1.28.0
|
24
|
+
|
25
|
+
- Add support for `Kernel#warn` redirection to `Console.warn`.
|
data.tar.gz.sig
CHANGED
Binary file
|