console 1.22.0 → 1.23.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f868615689827a90fa20cb73c9408598bd6cfc9602b21ee939a318213a3aee1
4
- data.tar.gz: 44927a1200deac00fab718aa995f0549eec0301b688a440da83ae13fd87edc33
3
+ metadata.gz: f053978f1ebc28b2973844d0ef018eeb200651ffb9bf00702a09ca3b04614fce
4
+ data.tar.gz: 4f8177c79c3e0d4f9b43e0e4b2c3f02e72837ca7d31e76a6eff308b41848e064
5
5
  SHA512:
6
- metadata.gz: eabb7c42bcb625726e75a7ebc1e7f330b7dcb0b8936b012c96c79b8a5456f0ac2b3fea5d02cdb1511fde9bd696c7ba300b6394952138810824cb18bdbe8e8e6e
7
- data.tar.gz: 1afa8d02eb8e56c81ac39f925e6a5df7edad41198c8aa255eb418847076913b6965b7d5794ba04ed6d5d35b08a1785e8825e12d32a8398f4203f7197584670c1
6
+ metadata.gz: 01bed9d6648e51ca76c7af4944f640eff416510bd7160ce9e9fd54c6c6397a213b45cfe8b4628d0e2071716b2651362e187f119d82053b85a7c4e5bb06d66fed
7
+ data.tar.gz: 80de59979995f867f791052666b20d5d1f50ed01a74af4529797b604934b3f18e064f113963b55014c5f90497b40be82ba124443036f8cb34414b48e6c6bc50b
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2023, by Samuel Williams.
5
+
6
+ require 'json'
7
+
8
+ module Console
9
+ module Format
10
+ # This class is used to safely dump objects.
11
+ # It will attempt to dump the object using the given format, but if it fails, it will generate a safe version of the object.
12
+ class Safe
13
+ def initialize(format: ::JSON, limit: 8, encoding: ::Encoding::UTF_8)
14
+ @format = format
15
+ @limit = limit
16
+ @encoding = encoding
17
+ end
18
+
19
+ def dump(object)
20
+ @format.dump(object, @limit)
21
+ rescue SystemStackError, StandardError => error
22
+ @format.dump(safe_dump(object, error))
23
+ end
24
+
25
+ private
26
+
27
+ def default_objects
28
+ Hash.new.compare_by_identity
29
+ end
30
+
31
+ # The first N frames, noting that the last frame is a placeholder for all the skipped frames:
32
+ FIRST_N_FRAMES = 10 + 1
33
+ LAST_N_FRAMES = 20
34
+ MAXIMUM_FRAMES = FIRST_N_FRAMES + LAST_N_FRAMES
35
+
36
+ def filter_backtrace(error)
37
+ frames = error.backtrace
38
+
39
+ # Select only the first and last few frames:
40
+ if frames.size > MAXIMUM_FRAMES
41
+ frames[FIRST_N_FRAMES-1] = "[... #{frames.size - (MAXIMUM_FRAMES-1)} frames ...]"
42
+ frames.slice!(FIRST_N_FRAMES...-LAST_N_FRAMES)
43
+ end
44
+
45
+ return frames
46
+ end
47
+
48
+ def safe_dump(object, error)
49
+ object = safe_dump_recurse(object)
50
+
51
+ object[:truncated] = true
52
+ object[:error] = {
53
+ class: safe_dump_recurse(error.class.name),
54
+ message: safe_dump_recurse(error.message),
55
+ backtrace: safe_dump_recurse(filter_backtrace(error)),
56
+ }
57
+
58
+ return object
59
+ end
60
+
61
+ def replacement_for(object)
62
+ case object
63
+ when Array
64
+ "[...]"
65
+ when Hash
66
+ "{...}"
67
+ else
68
+ "..."
69
+ end
70
+ end
71
+
72
+ # This will recursively generate a safe version of the object.
73
+ # Nested hashes and arrays will be transformed recursively.
74
+ # Strings will be encoded with the given encoding.
75
+ # Primitive values will be returned as-is.
76
+ # Other values will be converted using `as_json` if available, otherwise `to_s`.
77
+ def safe_dump_recurse(object, limit = @limit, objects = default_objects)
78
+ if limit <= 0 || objects[object]
79
+ return replacement_for(object)
80
+ end
81
+
82
+ case object
83
+ when Hash
84
+ objects[object] = true
85
+
86
+ object.to_h do |key, value|
87
+ [
88
+ String(key).encode(@encoding, invalid: :replace, undef: :replace),
89
+ safe_dump_recurse(value, limit - 1, objects)
90
+ ]
91
+ end
92
+ when Array
93
+ objects[object] = true
94
+
95
+ object.map do |value|
96
+ safe_dump_recurse(value, limit - 1, objects)
97
+ end
98
+ when String
99
+ object.encode(@encoding, invalid: :replace, undef: :replace)
100
+ when Numeric, TrueClass, FalseClass, NilClass
101
+ object
102
+ else
103
+ objects[object] = true
104
+
105
+ # We could do something like this but the chance `as_json` will blow up.
106
+ # We'd need to be extremely careful about it.
107
+ # if object.respond_to?(:as_json)
108
+ # safe_dump_recurse(object.as_json, limit - 1, objects)
109
+ # else
110
+
111
+ safe_dump_recurse(object.to_s, limit - 1, objects)
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2023, by Samuel Williams.
5
+
6
+ require_relative 'format/safe'
7
+
8
+ module Console
9
+ module Format
10
+ def self.default
11
+ Safe.new(format: ::JSON)
12
+ end
13
+
14
+ def self.default_json
15
+ self.default
16
+ end
17
+ end
18
+ end
@@ -8,94 +8,8 @@ require_relative '../serialized/logger'
8
8
  module Console
9
9
  module Output
10
10
  module JSON
11
- # This is a safe JSON serializer that will not raise exceptions.
12
- class Safe
13
- def initialize(limit: 8, encoding: ::Encoding::UTF_8)
14
- @limit = limit
15
- @encoding = encoding
16
- end
17
-
18
- def dump(object)
19
- ::JSON.dump(object, @limit)
20
- rescue => error
21
- ::JSON.dump(safe_dump(object, error))
22
- end
23
-
24
- private
25
-
26
- def default_objects
27
- Hash.new.compare_by_identity
28
- end
29
-
30
- def safe_dump(object, error)
31
- object = safe_dump_recurse(object)
32
-
33
- object[:truncated] = true
34
- object[:error] = {
35
- class: safe_dump_recurse(error.class.name),
36
- message: safe_dump_recurse(error.message),
37
- }
38
-
39
- return object
40
- end
41
-
42
- def replacement_for(object)
43
- case object
44
- when Array
45
- "[...]"
46
- when Hash
47
- "{...}"
48
- else
49
- "..."
50
- end
51
- end
52
-
53
- # This will recursively generate a safe version of the object.
54
- # Nested hashes and arrays will be transformed recursively.
55
- # Strings will be encoded with the given encoding.
56
- # Primitive values will be returned as-is.
57
- # Other values will be converted using `as_json` if available, otherwise `to_s`.
58
- def safe_dump_recurse(object, limit = @limit, objects = default_objects)
59
- if limit <= 0 || objects[object]
60
- return replacement_for(object)
61
- end
62
-
63
- case object
64
- when Hash
65
- objects[object] = true
66
-
67
- object.to_h do |key, value|
68
- [
69
- String(key).encode(@encoding, invalid: :replace, undef: :replace),
70
- safe_dump_recurse(value, limit - 1, objects)
71
- ]
72
- end
73
- when Array
74
- objects[object] = true
75
-
76
- object.map do |value|
77
- safe_dump_recurse(value, limit - 1, objects)
78
- end
79
- when String
80
- object.encode(@encoding, invalid: :replace, undef: :replace)
81
- when Numeric, TrueClass, FalseClass, NilClass
82
- object
83
- else
84
- objects[object] = true
85
-
86
- # We could do something like this but the chance `as_json` will blow up.
87
- # We'd need to be extremely careful about it.
88
- # if object.respond_to?(:as_json)
89
- # safe_dump_recurse(object.as_json, limit - 1, objects)
90
- # else
91
-
92
- safe_dump_recurse(object.to_s, limit - 1, objects)
93
- end
94
- end
95
- end
96
-
97
11
  def self.new(output, **options)
98
- Serialized::Logger.new(output, format: Safe.new, **options)
12
+ Serialized::Logger.new(output, format: Format.default_json, **options)
99
13
  end
100
14
  end
101
15
  end
@@ -5,16 +5,16 @@
5
5
 
6
6
  require_relative '../buffer'
7
7
  require_relative '../filter'
8
+ require_relative '../format'
8
9
 
9
10
  require 'time'
10
- require 'json'
11
11
 
12
12
  require 'fiber/annotation'
13
13
 
14
14
  module Console
15
15
  module Serialized
16
16
  class Logger
17
- def initialize(io = $stderr, format: JSON, verbose: false, **options)
17
+ def initialize(io = $stderr, format: Format.default, verbose: false, **options)
18
18
  @io = io
19
19
  @start = Time.now
20
20
  @format = format
@@ -4,5 +4,5 @@
4
4
  # Copyright, 2019-2023, by Samuel Williams.
5
5
 
6
6
  module Console
7
- VERSION = "1.22.0"
7
+ VERSION = "1.23.1"
8
8
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: console
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.22.0
4
+ version: 1.23.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -95,10 +95,11 @@ files:
95
95
  - lib/console/event/progress.rb
96
96
  - lib/console/event/spawn.rb
97
97
  - lib/console/filter.rb
98
+ - lib/console/format.rb
99
+ - lib/console/format/safe.rb
98
100
  - lib/console/logger.rb
99
101
  - lib/console/output.rb
100
102
  - lib/console/output/default.rb
101
- - lib/console/output/encoder.rb
102
103
  - lib/console/output/json.rb
103
104
  - lib/console/output/null.rb
104
105
  - lib/console/output/sensitive.rb
metadata.gz.sig CHANGED
Binary file
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Released under the MIT License.
4
- # Copyright, 2023, by Samuel Williams.
5
-
6
- module Console
7
- module Output
8
- # @deprecated With no replacement.
9
- class Encoder
10
- def initialize(output, encoding = ::Encoding::UTF_8)
11
- @output = output
12
- @encoding = encoding
13
- end
14
-
15
- attr :output
16
-
17
- attr :encoding
18
-
19
- def call(subject = nil, *arguments, **options, &block)
20
- subject = encode(subject)
21
- arguments = encode(arguments)
22
- options = encode(options)
23
-
24
- @output.call(subject, *arguments, **options, &block)
25
- end
26
-
27
- def encode(value)
28
- case value
29
- when String
30
- value.encode(@encoding, invalid: :replace, undef: :replace)
31
- when Array
32
- value.map{|item| encode(item)}
33
- when Hash
34
- value.transform_values{|item| encode(item)}
35
- else
36
- value
37
- end
38
- end
39
- end
40
- end
41
- end