console 1.29.2 → 1.36.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/context/command-line.md +47 -0
  4. data/context/configuration.md +23 -0
  5. data/context/events.md +71 -0
  6. data/context/getting-started.md +170 -0
  7. data/context/index.yaml +28 -0
  8. data/context/integration.md +37 -0
  9. data/lib/console/capture.rb +29 -3
  10. data/lib/console/clock.rb +9 -3
  11. data/lib/console/compatible/logger.rb +34 -3
  12. data/lib/console/config.rb +96 -0
  13. data/lib/console/event/failure.rb +33 -4
  14. data/lib/console/event/generic.rb +22 -1
  15. data/lib/console/event/spawn.rb +39 -7
  16. data/lib/console/event.rb +7 -1
  17. data/lib/console/filter.rb +83 -7
  18. data/lib/console/format/safe.rb +205 -58
  19. data/lib/console/format.rb +5 -1
  20. data/lib/console/interface.rb +18 -10
  21. data/lib/console/logger.rb +25 -38
  22. data/lib/console/output/default.rb +31 -6
  23. data/lib/console/output/failure.rb +9 -2
  24. data/lib/console/output/null.rb +5 -2
  25. data/lib/console/output/sensitive.rb +42 -1
  26. data/lib/console/output/serialized.rb +32 -7
  27. data/lib/console/output/split.rb +12 -1
  28. data/lib/console/output/terminal.rb +68 -15
  29. data/lib/console/output/wrapper.rb +12 -1
  30. data/lib/console/output.rb +14 -3
  31. data/lib/console/progress.rb +56 -9
  32. data/lib/console/resolver.rb +19 -2
  33. data/lib/console/terminal/formatter/failure.rb +18 -6
  34. data/lib/console/terminal/formatter/progress.rb +16 -3
  35. data/lib/console/terminal/formatter/spawn.rb +16 -5
  36. data/lib/console/terminal/formatter.rb +16 -0
  37. data/lib/console/terminal/text.rb +66 -20
  38. data/lib/console/terminal/xterm.rb +18 -3
  39. data/lib/console/terminal.rb +7 -9
  40. data/lib/console/version.rb +2 -2
  41. data/lib/console/warn.rb +2 -2
  42. data/lib/console.rb +2 -1
  43. data/license.md +6 -3
  44. data/readme.md +60 -6
  45. data/releases.md +115 -1
  46. data.tar.gz.sig +0 -0
  47. metadata +20 -12
  48. metadata.gz.sig +0 -0
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2024, by Samuel Williams.
4
+ # Copyright, 2019-2025, by Samuel Williams.
5
5
  # Copyright, 2021, by Robert Schulze.
6
6
 
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)
@@ -1,14 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2024, by Samuel Williams.
4
+ # Copyright, 2024-2025, by Samuel Williams.
5
5
 
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
- def format(event, output, prefix: nil, verbose: false, width: 80)
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
- output.puts " #{prefix}#{@terminal[:exception_title]}#{title}#{@terminal.reset}: #{lines.shift}"
42
+ stream.puts " #{prefix}#{@terminal[:exception_title]}#{title}#{@terminal.reset}: #{lines.shift}"
31
43
 
32
44
  lines.each do |line|
33
- output.puts " #{@terminal[:exception_detail]}#{line}#{@terminal.reset}"
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
- output.puts " #{index == 0 ? "→" : " "} #{@terminal[style]}#{path}:#{offset}#{@terminal[:exception_message]} #{message}#{@terminal.reset}"
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, output, prefix: "Caused by ", verbose: verbose, width: width)
63
+ format(cause, stream, prefix: "Caused by ", verbose: verbose, **options)
52
64
  end
53
65
  end
54
66
  end
@@ -1,14 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2020-2024, by Samuel Williams.
4
+ # Copyright, 2020-2025, by Samuel Williams.
5
5
 
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
- def format(event, output, verbose: false, width: 80)
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
- output.puts "#{@terminal[:progress_bar]}#{self.bar(value, width-10)}#{@terminal.reset} #{sprintf('%6.2f', value * 100)}%"
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
@@ -1,36 +1,47 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2024, by Samuel Williams.
4
+ # Copyright, 2019-2025, by Samuel Williams.
5
5
 
6
6
  module Console
7
7
  module Terminal
8
8
  module Formatter
9
- # Format spawn events.
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
- def format(event, output, verbose: false, width: 80)
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
- output.puts "#{@terminal[:spawn_command]}#{arguments.join(' ')}#{@terminal.reset}#{chdir_string(options)}"
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
- output.puts "export #{key}=#{value}"
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
@@ -1,82 +1,128 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2024, by Samuel Williams.
4
+ # Copyright, 2019-2025, by Samuel Williams.
5
+ # Copyright, 2025, by Patrik Wenger.
5
6
 
6
7
  require "io/console"
7
8
 
8
9
  module Console
9
10
  # Styled terminal output.
10
11
  module Terminal
12
+ # A simple text-based terminal output.
11
13
  class Text
12
- def initialize(output)
13
- @output = output
14
+ # Create a new text terminal output.
15
+ #
16
+ # @parameter stream [IO] The stream to write to.
17
+ def initialize(stream)
18
+ @stream = stream
14
19
  @styles = {reset: self.reset}
15
20
  end
16
21
 
22
+ # @attribute [IO] The stream to write to.
23
+ attr :stream
24
+
25
+ # Get the style associated with the given key.
26
+ #
27
+ # @parameter key [Symbol] The key to look up.
28
+ # @returns [String] The style associated with the key.
17
29
  def [] key
18
30
  @styles[key]
19
31
  end
20
32
 
33
+ # Set the style associated with the given key.
34
+ #
35
+ # @parameter key [Symbol] The key to associate the style with.
36
+ # @parameter value [String] The style to associate with the key.
21
37
  def []= key, value
22
38
  @styles[key] = value
23
39
  end
24
40
 
41
+ # @returns [Boolean] Whether the terminal supports colors.
25
42
  def colors?
26
43
  false
27
44
  end
28
45
 
46
+ # @returns [Tuple(Integer, Integer)] The size of the terminal, or a default value of [24, 80].
47
+ def size
48
+ [24, 80]
49
+ end
50
+
51
+ # @returns [Integer] The width of the terminal.
29
52
  def width
30
- 80
53
+ self.size.last
31
54
  end
32
55
 
56
+ # Generate a style string for the given foreground, background, and attributes.
57
+ #
58
+ # @returns [String | Nil] The style string if colors are supported, otherwise nil.
33
59
  def style(foreground, background = nil, *attributes)
34
60
  end
35
61
 
62
+ # Generate a reset sequence.
63
+ #
64
+ # @returns [String | Nil] The reset sequence if colors are supported, otherwise nil.
36
65
  def reset
37
66
  end
38
67
 
68
+ # Write the given arguments to the output stream using the given style. The reset sequence is automatically appended.
69
+ #
70
+ # @parameter arguments [Array] The arguments to write.
71
+ # @parameter style [Symbol] The style to apply.
39
72
  def write(*arguments, style: nil)
40
73
  if style and prefix = self[style]
41
- @output.write(prefix)
42
- @output.write(*arguments)
43
- @output.write(self.reset)
74
+ @stream.write(prefix)
75
+ @stream.write(*arguments)
76
+ @stream.write(self.reset)
44
77
  else
45
- @output.write(*arguments)
78
+ @stream.write(*arguments)
46
79
  end
47
80
  end
48
81
 
82
+ # Write the given arguments to the output stream using the given style. The reset sequence is automatically
83
+ # appended at the end of each line.
84
+ #
85
+ # @parameter arguments [Array] The arguments to write, each on a new line.
86
+ # @parameter style [Symbol] The style to apply.
49
87
  def puts(*arguments, style: nil)
50
88
  if style and prefix = self[style]
51
- @output.write(prefix)
52
- @output.puts(*arguments)
53
- @output.write(self.reset)
89
+ arguments.each do |argument|
90
+ argument.to_s.lines.each do |line|
91
+ @stream.write(prefix, line.chomp)
92
+ @stream.puts(self.reset)
93
+ end
94
+ end
54
95
  else
55
- @output.puts(*arguments)
96
+ @stream.puts(*arguments)
56
97
  end
57
98
  end
58
99
 
59
- # Print out the given arguments.
60
- # When the argument is a symbol, look up the style and inject it into the output stream.
61
- # When the argument is a proc/lambda, call it with self as the argument.
62
- # When the argument is anything else, write it directly to the output.
100
+ # Print rich text to the output stream.
101
+ #
102
+ # - When the argument is a symbol, look up the style and inject it into the output stream.
103
+ # - When the argument is a proc/lambda, call it with self as the argument.
104
+ # - When the argument is anything else, write it directly to the output.
105
+ #
106
+ # @parameter arguments [Array] The arguments to print.
63
107
  def print(*arguments)
64
108
  arguments.each do |argument|
65
109
  case argument
66
110
  when Symbol
67
- @output.write(self[argument])
111
+ @stream.write(self[argument])
68
112
  when Proc
69
113
  argument.call(self)
70
114
  else
71
- @output.write(argument)
115
+ @stream.write(argument)
72
116
  end
73
117
  end
74
118
  end
75
119
 
76
- # Print out the arguments as per {#print}, followed by the reset sequence and a newline.
120
+ # Print rich text to the output stream, followed by the reset sequence and a newline.
121
+ #
122
+ # @parameter arguments [Array] The arguments to print.
77
123
  def print_line(*arguments)
78
124
  print(*arguments)
79
- @output.puts(self.reset)
125
+ @stream.puts(self.reset)
80
126
  end
81
127
  end
82
128
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2024, by Samuel Williams.
4
+ # Copyright, 2019-2025, by Samuel Williams.
5
5
 
6
6
  require "io/console"
7
7
 
@@ -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
- @output.winsize
44
- rescue Errno::ENOTTY
48
+ @stream.winsize
49
+ rescue Errno::ENOTTY, Errno::ENODEV
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
@@ -1,22 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2024, by Samuel Williams.
4
+ # Copyright, 2019-2025, by Samuel Williams.
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
- def self.for(io)
16
- if io.tty?
17
- XTerm.new(io)
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(io)
17
+ Text.new(stream)
20
18
  end
21
19
  end
22
20
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2024, by Samuel Williams.
4
+ # Copyright, 2019-2026, by Samuel Williams.
5
5
 
6
6
  module Console
7
- VERSION = "1.29.2"
7
+ VERSION = "1.36.0"
8
8
  end
data/lib/console/warn.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2024, by Samuel Williams.
4
+ # Copyright, 2024-2025, by Samuel Williams.
5
5
 
6
6
  require_relative "logger"
7
7
 
@@ -22,7 +22,7 @@ module Console
22
22
  fiber.console_warn = true
23
23
  message.chomp!
24
24
 
25
- Console::Logger.instance.warn(message, **options)
25
+ Console::Interface.instance.warn(message, **options)
26
26
  ensure
27
27
  fiber.console_warn = false
28
28
  end
data/lib/console.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2024, by Samuel Williams.
4
+ # Copyright, 2019-2025, 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.
@@ -9,6 +9,7 @@
9
9
  require_relative "console/version"
10
10
  require_relative "console/interface"
11
11
 
12
+ # @namespace
12
13
  module Console
13
14
  Console.extend(Interface)
14
15
  end
data/license.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
 
3
- Copyright, 2019-2024, by Samuel Williams.
3
+ Copyright, 2019-2026, 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.
@@ -8,9 +8,12 @@ Copyright, 2020, by Michael Adams.
8
8
  Copyright, 2021, by Cédric Boutillier.
9
9
  Copyright, 2021, by Robert Schulze.
10
10
  Copyright, 2022, by Anton Sozontov.
11
- Copyright, 2022, by William T. Nelson.
11
+ Copyright, 2022-2026, by William T. Nelson.
12
12
  Copyright, 2023, by Felix Yan.
13
- Copyright, 2024, by Patrik Wenger.
13
+ Copyright, 2024-2025, by Patrik Wenger.
14
+ Copyright, 2025, by Shigeru Nakajima.
15
+ Copyright, 2025, by Yasha Krasnou.
16
+ Copyright, 2026, by Copilot.
14
17
 
15
18
  Permission is hereby granted, free of charge, to any person obtaining a copy
16
19
  of this software and associated documentation files (the "Software"), to deal
data/readme.md CHANGED
@@ -24,6 +24,8 @@ Please see the [project documentation](https://socketry.github.io/console/) for
24
24
 
25
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
26
 
27
+ - [Configuration](https://socketry.github.io/console/guides/configuration/index) - This guide explains how to implement per-project configuration for the `console` gem.
28
+
27
29
  - [Integration](https://socketry.github.io/console/guides/integration/index) - This guide explains how to integrate the `console` output into different systems.
28
30
 
29
31
  - [Events](https://socketry.github.io/console/guides/events/index) - This guide explains how to log structured events with a well-defined schema.
@@ -32,15 +34,51 @@ Please see the [project documentation](https://socketry.github.io/console/) for
32
34
 
33
35
  Please see the [project releases](https://socketry.github.io/console/releases/index) for all releases.
34
36
 
35
- ### v1.29.0
37
+ ### v1.36.0
38
+
39
+ - Add a `size_limit` to `Console::Format::Safe` (default 16KiB) which rebuilds oversized records field-by-field, keeping as many top-level fields as fit within the limit.
40
+ - Degraded fields are recorded in a `truncated` object that maps each field name to why it was truncated: `true` (dropped for size) or the error (the value could not be serialized directly and a safe representation was kept in its place).
41
+ - Rename `Console::Format::Safe`'s `limit:` to `depth_limit:` (with a deprecated `limit:` alias) to clarify its purpose alongside the new `size_limit:`.
42
+
43
+ ### v1.35.0
44
+
45
+ - Fix handling of `Errno::ENODEV` errors when calculating the width of a terminal that was been re-opened to `File::NULL`.
46
+
47
+ ### v1.34.1
48
+
49
+ - Add `process_id` to serialized output records for clarity (`pid` is still included for backwards compatibility).
50
+ - Add `object_id` to serialized output records **only** when the subject is not a string or class/module.
51
+
52
+ ### v1.34.0
53
+
54
+ - Allow `Console::Compatible::Logger#add` to accept `**options`.
55
+
56
+ ### v1.32.0
57
+
58
+ - Add `fiber_id` to serialized output records to help identify which fiber logged the message.
59
+ - Ractor support appears broken in older Ruby versions, so we now require Ruby 3.4 or later for Ractor compatibility, if you need Ractor support.
60
+
61
+ ### v1.31.0
62
+
63
+ - [Ractor compatibility.](https://socketry.github.io/console/releases/index#ractor-compatibility.)
64
+ - [Symbol log level compatibility.](https://socketry.github.io/console/releases/index#symbol-log-level-compatibility.)
65
+ - [Improved output format selection for cron jobs and email contexts.](https://socketry.github.io/console/releases/index#improved-output-format-selection-for-cron-jobs-and-email-contexts.)
36
66
 
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)
67
+ ### v1.30.0
40
68
 
41
- ### v1.28.0
69
+ - [Introduce `Console::Config` for fine grained configuration.](https://socketry.github.io/console/releases/index#introduce-console::config-for-fine-grained-configuration.)
42
70
 
43
- - Add support for `Kernel#warn` redirection to `Console.warn`.
71
+ ### v1.29.3
72
+
73
+ - Serialized output now uses `IO#write` with a single string to reduce the chance of interleaved output.
74
+
75
+ ### v1.29.2
76
+
77
+ - Always return `nil` from `Console::Filter` logging methods.
78
+
79
+ ### v1.29.1
80
+
81
+ - Fix logging `exception:` keyword argument when the value was not an exception.
44
82
 
45
83
  ## Contributing
46
84
 
@@ -52,6 +90,22 @@ We welcome contributions to this project.
52
90
  4. Push to the branch (`git push origin my-new-feature`).
53
91
  5. Create new Pull Request.
54
92
 
93
+ ### Running Tests
94
+
95
+ To run the test suite:
96
+
97
+ ``` shell
98
+ bundle exec sus
99
+ ```
100
+
101
+ ### Making Releases
102
+
103
+ To make a new release:
104
+
105
+ ``` shell
106
+ bundle exec bake gem:release:patch # or minor or major
107
+ ```
108
+
55
109
  ### Developer Certificate of Origin
56
110
 
57
111
  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.