helium-console 0.1.7 → 0.1.8
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
- data/.rubocop.yml +70 -0
- data/Gemfile +10 -5
- data/Gemfile.lock +29 -1
- data/Rakefile +5 -3
- data/bin/console +3 -8
- data/helium-console.gemspec +16 -14
- data/lib/helium/console/formatters/indent.rb +3 -1
- data/lib/helium/console/formatters/max_lines.rb +4 -2
- data/lib/helium/console/formatters/overflow/wrap.rb +4 -2
- data/lib/helium/console/formatters/overflow.rb +3 -2
- data/lib/helium/console/printer.rb +4 -2
- data/lib/helium/console/registry/array.rb +40 -35
- data/lib/helium/console/registry/booleans.rb +2 -0
- data/lib/helium/console/registry/hash.rb +48 -40
- data/lib/helium/console/registry/module.rb +2 -0
- data/lib/helium/console/registry/nil.rb +2 -0
- data/lib/helium/console/registry/numeric.rb +2 -0
- data/lib/helium/console/registry/object.rb +47 -37
- data/lib/helium/console/registry/string.rb +6 -4
- data/lib/helium/console/registry/symbol.rb +3 -1
- data/lib/helium/console/registry/table.rb +39 -32
- data/lib/helium/console/registry.rb +22 -12
- data/lib/helium/console/table.rb +3 -2
- data/lib/helium/console/version.rb +3 -1
- data/lib/helium/console.rb +25 -19
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7552b990faace56da88a1832368189a46120a6f223312c753d5242a3f7a3f027
|
|
4
|
+
data.tar.gz: c394e81ab462b5459067a8185ba30c2c5f0f41d42100c0c920b4fcd9ed2ae7f8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 96edfd58fb6fe13cc4c00e614093f40ae31b2caad6b5986cefa95fbca9834e9ae583d7cb830cdeceb7b579079ed5105111b9c3fbb4fd8223f7bfc60d9e9ae301
|
|
7
|
+
data.tar.gz: c27ef0e881621f47024b487ff158a5aeaa82eec3f9db468f33abec79cacb4c597ce3c91928802d8f6c2d7275f05d7f007682ac39df400fa83f3a23014f1b7eff
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require:
|
|
2
|
+
- rubocop-rspec
|
|
3
|
+
- rubocop-rake
|
|
4
|
+
|
|
5
|
+
AllCops:
|
|
6
|
+
NewCops: enable
|
|
7
|
+
|
|
8
|
+
Style/LambdaCall:
|
|
9
|
+
EnforcedStyle: braces
|
|
10
|
+
|
|
11
|
+
Layout/CaseIndentation:
|
|
12
|
+
EnforcedStyle: end
|
|
13
|
+
IndentOneStep: true
|
|
14
|
+
|
|
15
|
+
Style/NestedParenthesizedCalls:
|
|
16
|
+
AllowedMethods:
|
|
17
|
+
- be
|
|
18
|
+
- be_a
|
|
19
|
+
- be_an
|
|
20
|
+
- be_between
|
|
21
|
+
- be_falsey
|
|
22
|
+
- be_kind_of
|
|
23
|
+
- be_instance_of
|
|
24
|
+
- be_truthy
|
|
25
|
+
- be_within
|
|
26
|
+
- eq
|
|
27
|
+
- eql
|
|
28
|
+
- end_with
|
|
29
|
+
- expect
|
|
30
|
+
- include
|
|
31
|
+
- match
|
|
32
|
+
- raise_error
|
|
33
|
+
- respond_to
|
|
34
|
+
- start_with
|
|
35
|
+
|
|
36
|
+
Layout/EndAlignment:
|
|
37
|
+
EnforcedStyleAlignWith: start_of_line
|
|
38
|
+
|
|
39
|
+
Layout/MultilineMethodCallIndentation:
|
|
40
|
+
EnforcedStyle: indented
|
|
41
|
+
|
|
42
|
+
Style/Documentation:
|
|
43
|
+
Enabled: false
|
|
44
|
+
|
|
45
|
+
Bundler/OrderedGems:
|
|
46
|
+
Enabled: false
|
|
47
|
+
|
|
48
|
+
Style/EmptyMethod:
|
|
49
|
+
EnforcedStyle: expanded
|
|
50
|
+
|
|
51
|
+
Metrics/BlockLength:
|
|
52
|
+
IgnoredMethods:
|
|
53
|
+
- define_formatter_for
|
|
54
|
+
Exclude:
|
|
55
|
+
- "*.gemspec"
|
|
56
|
+
- "spec/**/*_spec.rb"
|
|
57
|
+
|
|
58
|
+
Metrics/MethodLength:
|
|
59
|
+
Max: 15
|
|
60
|
+
|
|
61
|
+
RSpec/MultipleExpectations:
|
|
62
|
+
Enabled: false
|
|
63
|
+
|
|
64
|
+
Style/NumericPredicate:
|
|
65
|
+
Enabled: false
|
|
66
|
+
|
|
67
|
+
Style/EachWithObject:
|
|
68
|
+
Enabled: false
|
|
69
|
+
|
|
70
|
+
|
data/Gemfile
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source 'https://rubygems.org'
|
|
2
4
|
|
|
3
5
|
# Specify your gem's dependencies in helium-console.gemspec
|
|
4
6
|
gemspec
|
|
5
7
|
|
|
6
|
-
gem
|
|
7
|
-
gem
|
|
8
|
-
gem
|
|
9
|
-
gem
|
|
8
|
+
gem 'rake', '~> 12.0'
|
|
9
|
+
gem 'rspec', '~> 3.0'
|
|
10
|
+
gem 'ffaker'
|
|
11
|
+
gem 'byebug'
|
|
12
|
+
gem 'rubocop', require: false
|
|
13
|
+
gem 'rubocop-rspec', require: false
|
|
14
|
+
gem 'rubocop-rake', require: false
|
data/Gemfile.lock
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
helium-console (0.1.
|
|
4
|
+
helium-console (0.1.8)
|
|
5
5
|
colorize
|
|
6
6
|
pry
|
|
7
7
|
|
|
8
8
|
GEM
|
|
9
9
|
remote: https://rubygems.org/
|
|
10
10
|
specs:
|
|
11
|
+
ast (2.4.2)
|
|
11
12
|
byebug (11.1.3)
|
|
12
13
|
coderay (1.1.3)
|
|
13
14
|
colorize (0.8.1)
|
|
14
15
|
diff-lcs (1.4.4)
|
|
15
16
|
ffaker (2.18.0)
|
|
16
17
|
method_source (1.0.0)
|
|
18
|
+
parallel (1.20.1)
|
|
19
|
+
parser (3.0.2.0)
|
|
20
|
+
ast (~> 2.4.1)
|
|
17
21
|
pry (0.14.1)
|
|
18
22
|
coderay (~> 1.1)
|
|
19
23
|
method_source (~> 1.0)
|
|
24
|
+
rainbow (3.0.0)
|
|
20
25
|
rake (12.3.3)
|
|
26
|
+
regexp_parser (2.1.1)
|
|
27
|
+
rexml (3.2.5)
|
|
21
28
|
rspec (3.10.0)
|
|
22
29
|
rspec-core (~> 3.10.0)
|
|
23
30
|
rspec-expectations (~> 3.10.0)
|
|
@@ -31,6 +38,24 @@ GEM
|
|
|
31
38
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
32
39
|
rspec-support (~> 3.10.0)
|
|
33
40
|
rspec-support (3.10.2)
|
|
41
|
+
rubocop (1.19.0)
|
|
42
|
+
parallel (~> 1.10)
|
|
43
|
+
parser (>= 3.0.0.0)
|
|
44
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
45
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
46
|
+
rexml
|
|
47
|
+
rubocop-ast (>= 1.9.1, < 2.0)
|
|
48
|
+
ruby-progressbar (~> 1.7)
|
|
49
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
50
|
+
rubocop-ast (1.10.0)
|
|
51
|
+
parser (>= 3.0.1.1)
|
|
52
|
+
rubocop-rake (0.6.0)
|
|
53
|
+
rubocop (~> 1.0)
|
|
54
|
+
rubocop-rspec (2.4.0)
|
|
55
|
+
rubocop (~> 1.0)
|
|
56
|
+
rubocop-ast (>= 1.1.0)
|
|
57
|
+
ruby-progressbar (1.11.0)
|
|
58
|
+
unicode-display_width (2.0.0)
|
|
34
59
|
|
|
35
60
|
PLATFORMS
|
|
36
61
|
ruby
|
|
@@ -41,6 +66,9 @@ DEPENDENCIES
|
|
|
41
66
|
helium-console!
|
|
42
67
|
rake (~> 12.0)
|
|
43
68
|
rspec (~> 3.0)
|
|
69
|
+
rubocop
|
|
70
|
+
rubocop-rake
|
|
71
|
+
rubocop-rspec
|
|
44
72
|
|
|
45
73
|
BUNDLED WITH
|
|
46
74
|
2.1.4
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'helium/console'
|
|
5
6
|
|
|
6
7
|
require 'byebug'
|
|
7
8
|
require 'ffaker'
|
|
8
9
|
|
|
9
|
-
class A
|
|
10
|
-
def initialize(a)
|
|
11
|
-
@a = a
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
10
|
Pry.start
|
data/helium-console.gemspec
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'lib/helium/console/version'
|
|
2
4
|
|
|
3
5
|
Gem::Specification.new do |spec|
|
|
4
|
-
spec.name =
|
|
6
|
+
spec.name = 'helium-console'
|
|
5
7
|
spec.version = Helium::Console::VERSION
|
|
6
|
-
spec.authors = [
|
|
7
|
-
spec.email = [
|
|
8
|
+
spec.authors = ['Stanislaw Klajn']
|
|
9
|
+
spec.email = ['sklajn@gmail.com']
|
|
8
10
|
|
|
9
|
-
spec.summary =
|
|
10
|
-
spec.homepage =
|
|
11
|
-
spec.license =
|
|
12
|
-
spec.required_ruby_version = Gem::Requirement.new(
|
|
11
|
+
spec.summary = 'Collection of tools for smooth integration with console'
|
|
12
|
+
spec.homepage = 'https://github.com/helium-rb/console'
|
|
13
|
+
spec.license = 'MIT'
|
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
|
|
13
15
|
|
|
14
|
-
spec.metadata[
|
|
15
|
-
spec.metadata[
|
|
16
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
17
|
+
spec.metadata['source_code_uri'] = 'https://github.com/helium-rb/console'
|
|
16
18
|
|
|
17
19
|
# Specify which files should be added to the gem when it is released.
|
|
18
20
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
19
|
-
spec.files
|
|
21
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
20
22
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
21
23
|
end
|
|
22
|
-
spec.bindir =
|
|
24
|
+
spec.bindir = 'exe'
|
|
23
25
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
24
|
-
spec.require_paths = [
|
|
25
|
-
spec.add_dependency
|
|
26
|
-
spec.add_dependency
|
|
26
|
+
spec.require_paths = ['lib']
|
|
27
|
+
spec.add_dependency 'colorize'
|
|
28
|
+
spec.add_dependency 'pry'
|
|
27
29
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Helium
|
|
2
4
|
class Console
|
|
3
5
|
module Formatters
|
|
@@ -7,7 +9,7 @@ module Helium
|
|
|
7
9
|
end
|
|
8
10
|
|
|
9
11
|
def call(string)
|
|
10
|
-
string.lines.map {|line| ' ' * @indent + line }.join
|
|
12
|
+
string.lines.map { |line| ' ' * @indent + line }.join
|
|
11
13
|
end
|
|
12
14
|
end
|
|
13
15
|
end
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Helium
|
|
2
4
|
class Console
|
|
3
5
|
module Formatters
|
|
4
6
|
class MaxLines
|
|
5
|
-
ELLIPSES = "
|
|
7
|
+
ELLIPSES = '..."'
|
|
6
8
|
|
|
7
9
|
def initialize(max_lines:, max_width:, ellipses:)
|
|
8
10
|
@max_lines = max_lines
|
|
@@ -16,7 +18,7 @@ module Helium
|
|
|
16
18
|
lines = string.lines.first(@max_lines)
|
|
17
19
|
last_line = lines.pop
|
|
18
20
|
lines << last_line.chars.first(@max_width - @ellipses.length).join + @ellipses
|
|
19
|
-
lines.join
|
|
21
|
+
lines.join
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Helium
|
|
2
4
|
class Console
|
|
3
5
|
module Formatters
|
|
@@ -11,8 +13,8 @@ module Helium
|
|
|
11
13
|
result = string.lines.flat_map do |line|
|
|
12
14
|
line.chomp.chars.each_slice(@max_width).map(&:join)
|
|
13
15
|
end
|
|
14
|
-
result = result.join(
|
|
15
|
-
result +=
|
|
16
|
+
result = result.join("\n")
|
|
17
|
+
result += "\n" if string.end_with?("\n")
|
|
16
18
|
result
|
|
17
19
|
end
|
|
18
20
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
|
|
2
3
|
module Helium
|
|
3
4
|
class Console
|
|
@@ -6,8 +7,8 @@ module Helium
|
|
|
6
7
|
def self.get(type)
|
|
7
8
|
require "helium/console/formatters/overflow/#{type}"
|
|
8
9
|
const_get(type.to_s.split('_').map(&:capitalize).join)
|
|
9
|
-
rescue
|
|
10
|
-
raise Error
|
|
10
|
+
rescue LoadError
|
|
11
|
+
raise Error, "Unknown overflow option: #{type}"
|
|
11
12
|
end
|
|
12
13
|
end
|
|
13
14
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Helium
|
|
2
4
|
class Console
|
|
3
5
|
class ColorPrinter < Pry::ColorPrinter
|
|
@@ -10,11 +12,11 @@ module Helium
|
|
|
10
12
|
|
|
11
13
|
def pp(object)
|
|
12
14
|
formatted = Helium::Console.format(object)
|
|
13
|
-
formatted =
|
|
15
|
+
formatted = "\n#{formatted}" if formatted.lines.count > 1
|
|
14
16
|
output << formatted
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
::Pry.config.print =
|
|
19
|
+
::Pry.config.print = method(:default)
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
end
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Helium
|
|
2
4
|
class Console
|
|
3
5
|
define_formatter_for Array do
|
|
4
6
|
def call
|
|
5
|
-
return
|
|
6
|
-
return
|
|
7
|
+
return '[]' if object.none?
|
|
8
|
+
return inline_with_truncation if force_inline?
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
inline_without_truncation || format_as_table
|
|
9
11
|
end
|
|
10
12
|
|
|
11
|
-
def
|
|
13
|
+
def simple?
|
|
12
14
|
object.none?
|
|
13
15
|
end
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
private
|
|
16
18
|
|
|
17
19
|
def format_as_table
|
|
18
20
|
table = Table.new(runner: ' ', format_keys: false)
|
|
@@ -21,50 +23,53 @@ module Helium
|
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
[
|
|
24
|
-
|
|
26
|
+
'[',
|
|
25
27
|
format(table),
|
|
26
|
-
|
|
27
|
-
].join(
|
|
28
|
+
']'
|
|
29
|
+
].join("\n")
|
|
28
30
|
end
|
|
29
31
|
|
|
30
|
-
def
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
def inline_with_truncation
|
|
33
|
+
formatted = formatted_elements.with_index.inject([]) do |joined, (element, index)|
|
|
34
|
+
new_joined = [*joined[0..-2], element, trunc_message(object_size - index - 1, all_truncated: index.zero?)]
|
|
35
|
+
break joined if too_long?(new_joined, max_width: max_width - 4)
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
new_joined
|
|
38
|
+
end
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
"[ #{formatted.compact.join(' | ')} ]"
|
|
41
|
+
end
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
def inline_without_truncation
|
|
44
|
+
return unless object.all? { |element| Helium::Console.simple? element }
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
formatted = formatted_elements.inject([]) do |joined, element|
|
|
47
|
+
joined = [*joined, element]
|
|
48
|
+
break if too_long?(joined, max_width: max_width - 4)
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
joined = [" ", joined, trunc, " "].compact.join if joined
|
|
49
|
-
["[", joined, "]"].compact.join
|
|
50
|
-
else
|
|
51
|
-
"[...(#{object.length})]"
|
|
50
|
+
joined
|
|
52
51
|
end
|
|
52
|
+
|
|
53
|
+
"[ #{formatted.join(' | ')} ]" unless formatted.nil?
|
|
53
54
|
end
|
|
54
55
|
|
|
55
|
-
def
|
|
56
|
-
|
|
56
|
+
def too_long?(object, max_width:)
|
|
57
|
+
string = object.respond_to?(:join) ? object.join(' | ') : object
|
|
58
|
+
length_of(string) > max_width - 4
|
|
59
|
+
end
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
def formatted_elements(**options)
|
|
62
|
+
object.each.lazy.map { |element| format_nested(element, **options) }
|
|
63
|
+
end
|
|
60
64
|
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
def trunc_message(count, all_truncated: false)
|
|
66
|
+
return if count < 1
|
|
63
67
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
"(#{count} #{all_truncated ? 'elements' : 'more'})"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def object_size
|
|
72
|
+
@object_size ||= object.size
|
|
68
73
|
end
|
|
69
74
|
|
|
70
75
|
def force_inline?
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Helium
|
|
2
4
|
class Console
|
|
3
5
|
define_formatter_for Hash do
|
|
4
6
|
def call
|
|
5
|
-
return
|
|
6
|
-
|
|
7
|
+
return '{}' if object.none?
|
|
8
|
+
return inline_with_truncation if force_inline?
|
|
9
|
+
|
|
10
|
+
inline_without_truncation || format_as_table
|
|
7
11
|
end
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
private
|
|
10
14
|
|
|
11
15
|
def format_as_table
|
|
12
16
|
table = Table.new(runner: ' ', after_key: after_key, format_keys: !all_symbol?)
|
|
@@ -16,65 +20,69 @@ module Helium
|
|
|
16
20
|
end
|
|
17
21
|
|
|
18
22
|
[
|
|
19
|
-
|
|
23
|
+
'{',
|
|
20
24
|
format(table, **options),
|
|
21
|
-
|
|
22
|
-
].join(
|
|
25
|
+
'}'
|
|
26
|
+
].join("\n")
|
|
23
27
|
end
|
|
24
28
|
|
|
25
|
-
def
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
object.each.with_index do |(key, value), index|
|
|
31
|
-
formatted_key = format(key, max_lines: 1, nesting: 1, max_with: 15)
|
|
32
|
-
formatted_value = format(value, max_lines: 1, nesting: 1, max_width: 15)
|
|
33
|
-
|
|
34
|
-
formatted = "#{formatted_key} => #{formatted_value}"
|
|
35
|
-
|
|
36
|
-
new_joined = [joined, formatted].compact.join(", ")
|
|
37
|
-
new_trunc = (", (#{total - index - 1} #{index.zero? ? 'elements' : 'more'})" unless index == total - 1)
|
|
29
|
+
def inline_with_truncation
|
|
30
|
+
truncated = formatted_inline_elements.with_index.inject([]) do |collected, (formatted, index)|
|
|
31
|
+
new_collected = [*collected[0..-2], formatted, trunc_text(index + 1)].compact
|
|
32
|
+
break collected if new_collected.join(', ').length > max_width - 4
|
|
38
33
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
joined = new_joined
|
|
42
|
-
trunc = new_trunc
|
|
34
|
+
new_collected
|
|
43
35
|
end
|
|
44
36
|
|
|
45
|
-
|
|
46
|
-
["{", joined, "}"].compact.join
|
|
37
|
+
['{ ', truncated.join(', '), ' }'].compact.join
|
|
47
38
|
end
|
|
48
39
|
|
|
49
|
-
def
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
object.each do |key, value|
|
|
54
|
-
return unless simple?(value)
|
|
40
|
+
def inline_without_truncation
|
|
41
|
+
formatted = formatted_inline_elements.inject([]) do |collected, element|
|
|
42
|
+
collected << element
|
|
43
|
+
break if collected.join(', ').length > max_width - 4
|
|
55
44
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
formatted = "#{formatted_key} => #{formatted_value}"
|
|
45
|
+
collected
|
|
46
|
+
end
|
|
59
47
|
|
|
60
|
-
|
|
48
|
+
return if formatted.nil?
|
|
61
49
|
|
|
62
|
-
|
|
63
|
-
end
|
|
64
|
-
joined = " #{joined} " if joined
|
|
65
|
-
["{", joined, "}"].compact.join
|
|
50
|
+
['{ ', formatted.join(', '), ' }'].compact.join
|
|
66
51
|
end
|
|
67
52
|
|
|
68
53
|
def force_inline?
|
|
69
54
|
level > 2
|
|
70
55
|
end
|
|
71
56
|
|
|
57
|
+
def formatted_inline_elements
|
|
58
|
+
object.each.lazy.map do |key, value|
|
|
59
|
+
formatted_key = format_key(key, max_lines: 1, nesting: 1, max_with: 15)
|
|
60
|
+
formatted_value = format_nested(value, max_lines: 1, nesting: 1, max_width: 15)
|
|
61
|
+
[formatted_key, after_key, formatted_value].join
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
72
65
|
def all_symbol?
|
|
73
66
|
object.keys.all? { |key| key.is_a? Symbol }
|
|
74
67
|
end
|
|
75
68
|
|
|
69
|
+
def format_key(key, **options)
|
|
70
|
+
return light_blue(key.to_s) if all_symbol?
|
|
71
|
+
|
|
72
|
+
format_nested(key, **options)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def total_elements
|
|
76
|
+
@total_elements ||= object.length
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def trunc_text(count)
|
|
80
|
+
truncated_elements = total_elements - count
|
|
81
|
+
light_black("(#{truncated_elements} #{count.zero? ? 'elements' : 'more'})")
|
|
82
|
+
end
|
|
83
|
+
|
|
76
84
|
def after_key
|
|
77
|
-
all_symbol? ? light_blue(
|
|
85
|
+
all_symbol? ? light_blue(': ') : light_black(' => ')
|
|
78
86
|
end
|
|
79
87
|
end
|
|
80
88
|
end
|
|
@@ -1,63 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Helium
|
|
2
4
|
class Console
|
|
3
5
|
define_formatter_for Object do
|
|
4
6
|
def call
|
|
5
|
-
return
|
|
7
|
+
return inline_with_truncation if force_inline?
|
|
8
|
+
|
|
6
9
|
format_as_table
|
|
7
10
|
end
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
private
|
|
10
13
|
|
|
11
14
|
def format_as_table
|
|
12
|
-
table = Table.new(runner: light_black('| '), after_key: light_black(
|
|
15
|
+
table = Table.new(runner: light_black('| '), after_key: light_black(': '), format_keys: false)
|
|
13
16
|
|
|
14
17
|
object.instance_variables.each do |inst|
|
|
15
18
|
table.row(magenta(inst.to_s), object.instance_variable_get(inst))
|
|
16
19
|
end
|
|
17
20
|
|
|
18
21
|
[
|
|
19
|
-
|
|
20
|
-
format(table)
|
|
21
|
-
].reject(&:empty?).join(
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def format_inline_with_truncation
|
|
25
|
-
"#{object.class.name}##{object.object_id.to_s(16)}"
|
|
22
|
+
"#{light_black '#'} #{class_name}",
|
|
23
|
+
format(table)
|
|
24
|
+
].reject(&:empty?).join("\n")
|
|
26
25
|
end
|
|
27
26
|
|
|
28
|
-
def
|
|
29
|
-
|
|
27
|
+
def inline_with_truncation
|
|
28
|
+
class_name = class_name(short: true)
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
vars = formatted_instance_variables(max_width: 15, max_lines: 1).inject([]) do |collected, element|
|
|
31
|
+
new_collected = [*collected, element]
|
|
32
|
+
break collected if new_collected.join(', ').length > max_width - length_of(class_name) - 2
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
formatted_value = format(value, level: 3, max_width: 15)
|
|
36
|
-
formatted = "#{formatted_key} => #{formatted_value}"
|
|
37
|
-
|
|
38
|
-
joined = [joined, formatted].compact.join(", ")
|
|
39
|
-
|
|
40
|
-
return if joined.length > max_width - 4
|
|
34
|
+
new_collected
|
|
41
35
|
end
|
|
42
|
-
joined = " #{joined} " if joined
|
|
43
|
-
["{", joined, "}"].compact.join
|
|
44
|
-
end
|
|
45
36
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
when Class then :class
|
|
49
|
-
when Module then :module
|
|
50
|
-
else :instance
|
|
51
|
-
end
|
|
52
|
-
klass = type == :instance ? object.class : object
|
|
53
|
-
klass_name = klass.name
|
|
54
|
-
if !klass_name
|
|
55
|
-
named_ancestor = klass.ancestors.find(&:name)
|
|
56
|
-
klass_name = ['anonymous', named_ancestor&.name].compact.join(" ")
|
|
57
|
-
end
|
|
58
|
-
"#{light_black('#')} #{light_yellow(klass_name)} #{type}"
|
|
37
|
+
formatted_vars = "( #{vars.join(', ')} )" if vars.any?
|
|
38
|
+
[class_name, formatted_vars].compact.join
|
|
59
39
|
end
|
|
60
40
|
|
|
41
|
+
# def inline_without_truncation
|
|
42
|
+
# joined = nil
|
|
43
|
+
#
|
|
44
|
+
# object.each do |key, value|
|
|
45
|
+
# return unless simple?(value)
|
|
46
|
+
#
|
|
47
|
+
# formatted_key = format(key, level: 3, max_with: 15)
|
|
48
|
+
# formatted_value = format(value, level: 3, max_width: 15)
|
|
49
|
+
# formatted = "#{formatted_key} => #{formatted_value}"
|
|
50
|
+
#
|
|
51
|
+
# joined = [joined, formatted].compact.join(', ')
|
|
52
|
+
#
|
|
53
|
+
# return if joined.length > max_width - 4
|
|
54
|
+
# end
|
|
55
|
+
# joined = " #{joined} " if joined
|
|
56
|
+
# ['{', joined, '}'].compact.join
|
|
57
|
+
# end
|
|
58
|
+
|
|
61
59
|
def force_inline?
|
|
62
60
|
level > 2
|
|
63
61
|
end
|
|
@@ -65,6 +63,18 @@ module Helium
|
|
|
65
63
|
def all_symbol?
|
|
66
64
|
object.keys.all? { |key| key.is_a? Symbol }
|
|
67
65
|
end
|
|
66
|
+
|
|
67
|
+
def formatted_instance_variables(**options)
|
|
68
|
+
object.instance_variables.sort.each.lazy.map do |var_name|
|
|
69
|
+
value = object.instance_variable_get(var_name)
|
|
70
|
+
"#{magenta(var_name.to_s)} = #{format_nested(value, **options)}"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def class_name(short: false)
|
|
75
|
+
formatted = format(object.class, short: short)
|
|
76
|
+
short ? "##{formatted}" : "#{formatted} instance"
|
|
77
|
+
end
|
|
68
78
|
end
|
|
69
79
|
end
|
|
70
80
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Helium
|
|
2
4
|
class Console
|
|
3
5
|
define_formatter_for String do
|
|
@@ -7,7 +9,7 @@ module Helium
|
|
|
7
9
|
max_width: max_width,
|
|
8
10
|
max_lines: max_lines,
|
|
9
11
|
overflow: overflow,
|
|
10
|
-
ellipses: "
|
|
12
|
+
ellipses: '..."'
|
|
11
13
|
)
|
|
12
14
|
|
|
13
15
|
formatted.lines
|
|
@@ -17,9 +19,9 @@ module Helium
|
|
|
17
19
|
|
|
18
20
|
def max_lines
|
|
19
21
|
case level
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
when 1 then nil
|
|
23
|
+
when 2 then 3
|
|
24
|
+
else 1
|
|
23
25
|
end
|
|
24
26
|
end
|
|
25
27
|
end
|
|
@@ -1,37 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Helium
|
|
2
4
|
class Console
|
|
3
5
|
define_formatter_for Table do
|
|
4
6
|
def call
|
|
5
7
|
[
|
|
6
8
|
*formatted_values,
|
|
7
|
-
truncation
|
|
8
|
-
].compact.join(
|
|
9
|
+
truncation
|
|
10
|
+
].compact.join("\n")
|
|
9
11
|
end
|
|
10
12
|
|
|
13
|
+
private
|
|
14
|
+
|
|
11
15
|
def formatted_values
|
|
12
16
|
rows.flat_map do |key, value, options = {}|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
formatted_value.lines.map.with_index do |line, index|
|
|
16
|
-
[
|
|
17
|
-
object.runner,
|
|
18
|
-
index.zero? ? rjust(format_key(key), key_width) : " " * key_width,
|
|
19
|
-
index.zero? ? object.after_key : " " * length_of(object.after_key),
|
|
20
|
-
line.chomp,
|
|
21
|
-
].join
|
|
22
|
-
end
|
|
17
|
+
format_pair(key, value, **options)
|
|
23
18
|
end
|
|
24
19
|
end
|
|
25
20
|
|
|
26
|
-
def
|
|
27
|
-
|
|
21
|
+
def format_pair(key, value, **options)
|
|
22
|
+
formatted_value = format_nested(value, max_width: max_value_width, **options)
|
|
28
23
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
formatted_value.lines.map.with_index do |line, index|
|
|
25
|
+
[
|
|
26
|
+
object.runner,
|
|
27
|
+
text_or_blank(rjust(format_key(key), key_width), blank: index > 0),
|
|
28
|
+
text_or_blank(object.after_key, blank: index > 0),
|
|
29
|
+
line.chomp
|
|
30
|
+
].join
|
|
31
|
+
end
|
|
33
32
|
end
|
|
34
33
|
|
|
34
|
+
def text_or_blank(text, blank:)
|
|
35
|
+
return text unless blank
|
|
36
|
+
|
|
37
|
+
' ' * length_of(text)
|
|
38
|
+
end
|
|
35
39
|
|
|
36
40
|
def key_width
|
|
37
41
|
@key_width ||= rows
|
|
@@ -50,26 +54,29 @@ module Helium
|
|
|
50
54
|
end
|
|
51
55
|
|
|
52
56
|
def rjust(string, width)
|
|
53
|
-
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def length_of(string)
|
|
57
|
-
if string.respond_to?(:uncolorize)
|
|
58
|
-
string.uncolorize.length
|
|
59
|
-
else
|
|
60
|
-
string.length
|
|
61
|
-
end
|
|
57
|
+
' ' * (width - length_of(string)) + string
|
|
62
58
|
end
|
|
63
59
|
|
|
64
60
|
def rows
|
|
65
61
|
@rows ||= case level
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
else
|
|
70
|
-
object.rows.count < 3 ? object.rows : object.rows.first(2)
|
|
62
|
+
when 1 then object.rows
|
|
63
|
+
when 2 then rows_limited_by(10)
|
|
64
|
+
else rows_limited_by(3)
|
|
71
65
|
end
|
|
72
66
|
end
|
|
67
|
+
|
|
68
|
+
def rows_limited_by(number)
|
|
69
|
+
object.rows.count <= number ? object.rows : object.rows.first(number - 1)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def truncation
|
|
73
|
+
return unless object.rows.length > rows.length
|
|
74
|
+
|
|
75
|
+
[
|
|
76
|
+
object.runner,
|
|
77
|
+
light_black("(#{object.rows.length - rows.length} more)")
|
|
78
|
+
].join
|
|
79
|
+
end
|
|
73
80
|
end
|
|
74
81
|
end
|
|
75
82
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'colorized_string'
|
|
2
4
|
|
|
3
5
|
module Helium
|
|
@@ -9,6 +11,9 @@ module Helium
|
|
|
9
11
|
@options = options
|
|
10
12
|
end
|
|
11
13
|
|
|
14
|
+
def call
|
|
15
|
+
end
|
|
16
|
+
|
|
12
17
|
attr_reader :object, :options
|
|
13
18
|
|
|
14
19
|
def format_nested(other_object, **options)
|
|
@@ -23,28 +28,31 @@ module Helium
|
|
|
23
28
|
Helium::Console.format_string(string, **options)
|
|
24
29
|
end
|
|
25
30
|
|
|
26
|
-
def simple?
|
|
27
|
-
Helium::Console.simple?(object)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def is_simple
|
|
31
|
+
def simple?
|
|
31
32
|
false
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
def method_missing(name, *args)
|
|
35
36
|
return @options[name] if @options.key?(name)
|
|
36
|
-
if ColorizedString.colors.include?(name)
|
|
37
|
-
|
|
38
|
-
end
|
|
37
|
+
return ColorizedString.new(*args).colorize(name) if ColorizedString.colors.include?(name)
|
|
38
|
+
|
|
39
39
|
super
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
def respond_to_missing?(name, private = false)
|
|
43
|
+
@options.key?(name) || ColorizedString.colors.include?(name) || super
|
|
44
|
+
end
|
|
45
|
+
|
|
42
46
|
def nested_opts(new_options, increase_level: true)
|
|
43
47
|
new_options = options.merge(new_options)
|
|
44
48
|
new_options[:level] += 1 if increase_level
|
|
45
49
|
new_options[:ignore_objects] << object.object_id
|
|
46
50
|
new_options
|
|
47
51
|
end
|
|
52
|
+
|
|
53
|
+
def length_of(string)
|
|
54
|
+
ColorizedString.new(string).uncolorize.length
|
|
55
|
+
end
|
|
48
56
|
end
|
|
49
57
|
|
|
50
58
|
def add(klass, &handler)
|
|
@@ -58,13 +66,15 @@ module Helium
|
|
|
58
66
|
end
|
|
59
67
|
|
|
60
68
|
def handler_for(object, **options)
|
|
61
|
-
object.class.ancestors.
|
|
62
|
-
|
|
69
|
+
element_class = object.class.ancestors.find do |ancestor|
|
|
70
|
+
break handlers[ancestor] if handlers.key?(ancestor)
|
|
63
71
|
end
|
|
64
|
-
|
|
72
|
+
return unless element_class
|
|
73
|
+
|
|
74
|
+
element_class.new(object, **options)
|
|
65
75
|
end
|
|
66
76
|
|
|
67
|
-
|
|
77
|
+
private
|
|
68
78
|
|
|
69
79
|
def handlers
|
|
70
80
|
@handlers ||= {}
|
data/lib/helium/console/table.rb
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Helium
|
|
2
4
|
class Console
|
|
3
5
|
class Table
|
|
4
|
-
|
|
5
|
-
def initialize(runner: "|", after_key: " ", format_keys: true)
|
|
6
|
+
def initialize(runner: '|', after_key: ' ', format_keys: true)
|
|
6
7
|
@runner = runner
|
|
7
8
|
@after_key = after_key
|
|
8
9
|
@format_keys = format_keys
|
data/lib/helium/console.rb
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require "helium/console/formatters/indent"
|
|
5
|
-
require "helium/console/formatters/overflow"
|
|
6
|
-
require "helium/console/formatters/max_lines"
|
|
7
|
-
require "helium/console/table"
|
|
8
|
-
require "helium/console/registry"
|
|
3
|
+
require 'pry'
|
|
9
4
|
|
|
10
|
-
require
|
|
5
|
+
require 'helium/console/version'
|
|
6
|
+
require 'helium/console/formatters/indent'
|
|
7
|
+
require 'helium/console/formatters/overflow'
|
|
8
|
+
require 'helium/console/formatters/max_lines'
|
|
9
|
+
require 'helium/console/table'
|
|
10
|
+
require 'helium/console/registry'
|
|
11
|
+
|
|
12
|
+
require 'helium/console/printer'
|
|
11
13
|
|
|
12
14
|
module Helium
|
|
13
15
|
class Console
|
|
@@ -19,7 +21,7 @@ module Helium
|
|
|
19
21
|
FalseClass,
|
|
20
22
|
TrueClass,
|
|
21
23
|
Symbol
|
|
22
|
-
]
|
|
24
|
+
].freeze
|
|
23
25
|
|
|
24
26
|
class << self
|
|
25
27
|
def instance
|
|
@@ -31,6 +33,10 @@ module Helium
|
|
|
31
33
|
|
|
32
34
|
instance.public_send(name, *args, &block)
|
|
33
35
|
end
|
|
36
|
+
|
|
37
|
+
def respond_to_missing?(name, private = false)
|
|
38
|
+
instance.respond_to?(name) || super
|
|
39
|
+
end
|
|
34
40
|
end
|
|
35
41
|
|
|
36
42
|
def initialize(registry:)
|
|
@@ -39,12 +45,12 @@ module Helium
|
|
|
39
45
|
|
|
40
46
|
def format(object, **options)
|
|
41
47
|
options = default_options.merge(options)
|
|
42
|
-
return
|
|
48
|
+
return '(...)' if options[:ignore_objects].include?(object.object_id)
|
|
43
49
|
|
|
44
50
|
handler = registry.handler_for(object, **options)
|
|
45
51
|
|
|
46
52
|
if handler
|
|
47
|
-
handler.
|
|
53
|
+
handler.()
|
|
48
54
|
else
|
|
49
55
|
format(object.inspect, **options)
|
|
50
56
|
end
|
|
@@ -59,8 +65,8 @@ module Helium
|
|
|
59
65
|
end
|
|
60
66
|
|
|
61
67
|
def simple?(object)
|
|
62
|
-
SIMPLE_OBJECTS.any? {|simple_obj_class| object.is_a? simple_obj_class } ||
|
|
63
|
-
registry.handler_for(object).
|
|
68
|
+
SIMPLE_OBJECTS.any? { |simple_obj_class| object.is_a? simple_obj_class } ||
|
|
69
|
+
registry.handler_for(object).simple?
|
|
64
70
|
end
|
|
65
71
|
|
|
66
72
|
def default_options
|
|
@@ -69,11 +75,11 @@ module Helium
|
|
|
69
75
|
indent: 0,
|
|
70
76
|
max_width: `tput cols`.chomp.to_i,
|
|
71
77
|
level: 1,
|
|
72
|
-
ignore_objects: []
|
|
78
|
+
ignore_objects: []
|
|
73
79
|
}
|
|
74
80
|
end
|
|
75
81
|
|
|
76
|
-
def format_string(string, ellipses:
|
|
82
|
+
def format_string(string, ellipses: '...', **options)
|
|
77
83
|
options = default_options.merge(options)
|
|
78
84
|
|
|
79
85
|
formatters = [
|
|
@@ -86,17 +92,17 @@ module Helium
|
|
|
86
92
|
)
|
|
87
93
|
]
|
|
88
94
|
|
|
89
|
-
formatters.inject(string) do |
|
|
90
|
-
formatter.
|
|
95
|
+
formatters.inject(string) do |str, formatter|
|
|
96
|
+
formatter.(str)
|
|
91
97
|
end
|
|
92
98
|
end
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
private
|
|
95
101
|
|
|
96
102
|
attr_reader :registry
|
|
97
103
|
end
|
|
98
104
|
end
|
|
99
105
|
|
|
100
|
-
Dir.glob(File.join(File.dirname(__FILE__),
|
|
106
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'console', 'registry', '**/*.rb')).sort.each do |file|
|
|
101
107
|
require file
|
|
102
108
|
end
|
metadata
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: helium-console
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stanislaw Klajn
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-08-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
14
|
+
name: colorize
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
@@ -25,7 +25,7 @@ dependencies:
|
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: pry
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - ">="
|
|
@@ -47,6 +47,7 @@ extra_rdoc_files: []
|
|
|
47
47
|
files:
|
|
48
48
|
- ".gitignore"
|
|
49
49
|
- ".rspec"
|
|
50
|
+
- ".rubocop.yml"
|
|
50
51
|
- ".travis.yml"
|
|
51
52
|
- CODE_OF_CONDUCT.md
|
|
52
53
|
- Gemfile
|
|
@@ -90,14 +91,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
90
91
|
requirements:
|
|
91
92
|
- - ">="
|
|
92
93
|
- !ruby/object:Gem::Version
|
|
93
|
-
version: 2.
|
|
94
|
+
version: 2.5.0
|
|
94
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
96
|
requirements:
|
|
96
97
|
- - ">="
|
|
97
98
|
- !ruby/object:Gem::Version
|
|
98
99
|
version: '0'
|
|
99
100
|
requirements: []
|
|
100
|
-
rubygems_version: 3.
|
|
101
|
+
rubygems_version: 3.1.4
|
|
101
102
|
signing_key:
|
|
102
103
|
specification_version: 4
|
|
103
104
|
summary: Collection of tools for smooth integration with console
|