output_mode 1.4.0 → 1.5.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
- data/Gemfile +7 -0
- data/bin/demo +17 -0
- data/lib/output_mode/builder_dsl.rb +3 -1
- data/lib/output_mode/callable.rb +64 -8
- data/lib/output_mode/output.rb +16 -52
- data/lib/output_mode/outputs/delimited.rb +6 -1
- data/lib/output_mode/outputs/tabulated.rb +13 -16
- data/lib/output_mode/outputs/templated.rb +16 -18
- data/lib/output_mode/tldr/index.rb +28 -8
- data/lib/output_mode/tldr/show.rb +24 -4
- data/lib/output_mode/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 33db72e9e5872a974df80e11a0d4bae3735c13d49d3be4d4ab1366b7e461551f
|
|
4
|
+
data.tar.gz: f1ac7923d6cb9beda1f3af36ebaa41b84cdb6567d5fb71db4f2d1a2503ee731b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f12f87485cdad45ceb4fba9b9b26c405366009b1ad39e87c223fc246424bd0501421a75570caf48c351523d55483f4ea1d705659a3e6185ae8213c6147d9ad96
|
|
7
|
+
data.tar.gz: cafd82a58648d5e4900c91d242a1128b2b1c5d1123716385160801a3d85959324df691ecd7c8443e038612e4c2b2afb221745da598483e239a15a7ef9a701c0a
|
data/Gemfile
CHANGED
|
@@ -28,3 +28,10 @@ source "https://rubygems.org"
|
|
|
28
28
|
|
|
29
29
|
# Specify your gem's dependencies in output_mode.gemspec
|
|
30
30
|
gemspec
|
|
31
|
+
|
|
32
|
+
# NOTE: Checks out the openflight version of tty-table with the 'rotate' flag
|
|
33
|
+
# fix. This should eventually become part of the mainline version of TTY::Table
|
|
34
|
+
#
|
|
35
|
+
# This is intentionally not part of the gemspec so older versions of TTY::Table
|
|
36
|
+
# can still be used
|
|
37
|
+
gem 'tty-table', github: 'openflighthpc/tty-table', branch: '9b326fcbe04968463da58c000fbb1dd5ce178243'
|
data/bin/demo
CHANGED
|
@@ -36,9 +36,22 @@ module DemoIndex
|
|
|
36
36
|
register_callable(header: 'Standard', header_color: [:strikethrough] ) { 'always visible' }
|
|
37
37
|
register_callable(header: 'Verbose', verbose: true) { 'verbose visible' }
|
|
38
38
|
register_callable(header: 'Simplified', verbose: false) { 'simplified visible' }
|
|
39
|
+
register_callable(header: 'Interactive', interactive: true) { 'interactive visible' }
|
|
40
|
+
register_callable(header: 'Non Interactive', interactive: false) { 'non-interactive visible' }
|
|
39
41
|
register_callable(header: 'Yes/True') { true }
|
|
40
42
|
register_callable(header: 'No/False', row_color: [:clear]) { false }
|
|
41
43
|
register_callable(header: 'Missing') { nil }
|
|
44
|
+
register_callable(header: 'Inline') do |interactive:, verbose:|
|
|
45
|
+
if interactive && verbose
|
|
46
|
+
'interactive-verbose'
|
|
47
|
+
elsif interactive
|
|
48
|
+
'interactive-simplified'
|
|
49
|
+
elsif verbose
|
|
50
|
+
'non-interactive-verbose'
|
|
51
|
+
else
|
|
52
|
+
'non-interactive-simplified'
|
|
53
|
+
end
|
|
54
|
+
end
|
|
42
55
|
end
|
|
43
56
|
|
|
44
57
|
module DemoShow
|
|
@@ -48,9 +61,13 @@ module DemoShow
|
|
|
48
61
|
register_callable(header: 'Standard') { 'always visible' }
|
|
49
62
|
register_callable(header: 'Verbose', verbose: true) { 'verbose visible' }
|
|
50
63
|
register_callable(header: 'Simplified', verbose: false) { 'simplified visible' }
|
|
64
|
+
register_callable(header: 'Interactive', interactive: true) { 'interactive visible' }
|
|
65
|
+
register_callable(header: 'Non Interactive', interactive: false) { 'non-interactive visible' }
|
|
51
66
|
register_callable(header: 'Yes/True', section: :boolean) { true }
|
|
52
67
|
register_callable(header: 'No/False', section: :boolean) { false }
|
|
53
68
|
register_callable(header: 'Missing') { nil }
|
|
69
|
+
register_callable(header: 'Tab') { "tab1\ttab2" }
|
|
70
|
+
register_callable(header: 'New line') { "line1\nline2" }
|
|
54
71
|
end
|
|
55
72
|
|
|
56
73
|
data = [1, 2, 3]
|
|
@@ -36,7 +36,9 @@ module OutputMode
|
|
|
36
36
|
# @param config Directly provided to {OutputMode::Callable#initialize}
|
|
37
37
|
# @yield Directly provided to {OutputMode::Callable#initialize}
|
|
38
38
|
def register_callable(**config, &b)
|
|
39
|
-
|
|
39
|
+
Callable.new(**config, &b).tap do |c|
|
|
40
|
+
output_callables << c
|
|
41
|
+
end
|
|
40
42
|
end
|
|
41
43
|
|
|
42
44
|
# Provides the base method signature
|
data/lib/output_mode/callable.rb
CHANGED
|
@@ -26,16 +26,17 @@
|
|
|
26
26
|
|
|
27
27
|
module OutputMode
|
|
28
28
|
# Internal array like object that will convert procs to Callable
|
|
29
|
-
class Callables
|
|
29
|
+
class Callables
|
|
30
|
+
include Enumerable
|
|
31
|
+
|
|
30
32
|
# @api private
|
|
31
33
|
def initialize(callables = nil)
|
|
34
|
+
@callables = []
|
|
32
35
|
case callables
|
|
33
|
-
when Array
|
|
34
|
-
|
|
35
|
-
callables.each { |c| all << c }
|
|
36
|
-
end
|
|
36
|
+
when Array, Callables
|
|
37
|
+
callables.each { |c| @callables << c }
|
|
37
38
|
when nil
|
|
38
|
-
|
|
39
|
+
# NOOP
|
|
39
40
|
else
|
|
40
41
|
raise "Can not convert #{callables.class} into a #{self.class}"
|
|
41
42
|
end
|
|
@@ -43,13 +44,45 @@ module OutputMode
|
|
|
43
44
|
|
|
44
45
|
def <<(item)
|
|
45
46
|
if item.is_a? Callable
|
|
46
|
-
|
|
47
|
+
@callables << item
|
|
47
48
|
elsif item.respond_to?(:call)
|
|
48
|
-
|
|
49
|
+
@callables << Callable.new(&item)
|
|
49
50
|
else
|
|
50
51
|
raise Error, "#{item.class} is not callable"
|
|
51
52
|
end
|
|
52
53
|
end
|
|
54
|
+
|
|
55
|
+
def each(&block)
|
|
56
|
+
@callables.each(&block)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def pad_each(key = :header)
|
|
60
|
+
max_length = self.map { |c| c.config[key].to_s.length }
|
|
61
|
+
.max
|
|
62
|
+
|
|
63
|
+
pads = self.map do |callable|
|
|
64
|
+
length = max_length - callable.config[key].to_s.length
|
|
65
|
+
[callable, { padding: ' ' * length }]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
if block_given?
|
|
69
|
+
pads.each { |*args| yield(*args) }
|
|
70
|
+
else
|
|
71
|
+
pads.each
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def config_select(key, *values)
|
|
76
|
+
selected = self.select do |callable|
|
|
77
|
+
conf = callable.config[key]
|
|
78
|
+
if conf.is_a? Array
|
|
79
|
+
!(conf & values).empty?
|
|
80
|
+
else
|
|
81
|
+
values.include?(conf)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
Callables.new(selected)
|
|
85
|
+
end
|
|
53
86
|
end
|
|
54
87
|
|
|
55
88
|
class Callable
|
|
@@ -141,6 +174,29 @@ module OutputMode
|
|
|
141
174
|
def call(*a)
|
|
142
175
|
callable.call(*a)
|
|
143
176
|
end
|
|
177
|
+
|
|
178
|
+
def generator(output)
|
|
179
|
+
->(*a) do
|
|
180
|
+
# Implicitly determine which parts of the context can be passed through
|
|
181
|
+
ctx = if callable.parameters.any? { |type, _| type == :keyrest }
|
|
182
|
+
output.context
|
|
183
|
+
else
|
|
184
|
+
keys = callable.parameters.select { |type, _| [:key, :keyreq].include?(type) }
|
|
185
|
+
.map { |_, k| k }
|
|
186
|
+
output.context.slice(*keys)
|
|
187
|
+
end
|
|
188
|
+
raw = call(*a, **ctx)
|
|
189
|
+
if raw == true
|
|
190
|
+
config[:yes] || output.yes
|
|
191
|
+
elsif raw == false
|
|
192
|
+
config[:no] || output.no
|
|
193
|
+
elsif [nil, ''].include?(raw)
|
|
194
|
+
config[:default] || output.default
|
|
195
|
+
else
|
|
196
|
+
raw
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
144
200
|
end
|
|
145
201
|
end
|
|
146
202
|
|
data/lib/output_mode/output.rb
CHANGED
|
@@ -36,45 +36,41 @@ module OutputMode
|
|
|
36
36
|
# @!attribute [r] config
|
|
37
37
|
# @return [Hash] additional key-values to modify the render
|
|
38
38
|
# @!attribute [r] default
|
|
39
|
-
# @return either a static default
|
|
39
|
+
# @return either a static default
|
|
40
40
|
# @!attribute [r] yes
|
|
41
|
-
# @return either a static yes value
|
|
41
|
+
# @return either a static yes value
|
|
42
42
|
# @!attribute [r] no
|
|
43
|
-
# @return either a static no value
|
|
44
|
-
|
|
43
|
+
# @return either a static no value
|
|
44
|
+
# @!attribute [r] context
|
|
45
|
+
# @return a hash of keys to be provided to the callables
|
|
46
|
+
attr_reader :procs, :config, :yes, :no, :default, :context
|
|
45
47
|
|
|
46
48
|
# Creates a new outputting instance from an array of procs
|
|
47
49
|
#
|
|
48
50
|
# @param *procs [Array<#call>] an array of procs (or callable objects)
|
|
49
51
|
# @param default: [String] replaces _blanks_ with a static string
|
|
50
|
-
# @param default: [Array] replace _blanks_ on a per column basis. The last value is repeated if the +procs+ are longer.
|
|
51
52
|
# @param yes: [String] replaces +true+ with a static string
|
|
52
|
-
# @param yes: [Array] replaces +true+ on a per column basis. The last value is repeated if the +procs+ are longer.
|
|
53
53
|
# @param no: [String] replaces +false+ with a static string
|
|
54
|
-
# @param
|
|
54
|
+
# @param context: [Hash] of keys to be provided to the callables
|
|
55
55
|
# @param **config [Hash] a hash of additional keys to be stored
|
|
56
|
-
def initialize(*procs, default: nil, yes: 'true', no: 'false', **config)
|
|
57
|
-
@procs = procs
|
|
56
|
+
def initialize(*procs, default: nil, yes: 'true', no: 'false', context: {}, **config)
|
|
57
|
+
@procs = Callables.new(procs)
|
|
58
58
|
@config = config
|
|
59
59
|
@yes = yes
|
|
60
60
|
@no = no
|
|
61
61
|
@default = default
|
|
62
|
+
@context = context
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def callables
|
|
66
|
+
procs
|
|
62
67
|
end
|
|
63
68
|
|
|
64
69
|
# Returns the results of the +procs+ for a particular +object+. It will apply the
|
|
65
70
|
# +default+, +yes+, and +no+ values.
|
|
66
71
|
def generate(object)
|
|
67
|
-
procs.
|
|
68
|
-
|
|
69
|
-
if raw == true
|
|
70
|
-
index_selector(:yes, idx)
|
|
71
|
-
elsif raw == false
|
|
72
|
-
index_selector(:no, idx)
|
|
73
|
-
elsif !default.nil? && (raw.nil? || raw == '')
|
|
74
|
-
index_selector(:default, idx)
|
|
75
|
-
else
|
|
76
|
-
raw
|
|
77
|
-
end
|
|
72
|
+
procs.map do |callable|
|
|
73
|
+
callable.generator(self).call(object)
|
|
78
74
|
end
|
|
79
75
|
end
|
|
80
76
|
|
|
@@ -91,37 +87,5 @@ module OutputMode
|
|
|
91
87
|
def render(*data)
|
|
92
88
|
raise NotImplementedError
|
|
93
89
|
end
|
|
94
|
-
|
|
95
|
-
# A helper method for selecting elements from a source array or return
|
|
96
|
-
# a static value.
|
|
97
|
-
#
|
|
98
|
-
# @param [Symbol] method The source method on the +output+
|
|
99
|
-
# @param [Integer] index The index to lookup
|
|
100
|
-
#
|
|
101
|
-
# @overload index_selector(array_method, valid_index)
|
|
102
|
-
# @param array_method A method that returns an array
|
|
103
|
-
# @param valid_index An index that is less than the array's length
|
|
104
|
-
# @return the value at the index
|
|
105
|
-
#
|
|
106
|
-
# @overload index_selector(array_method, out_of_bounds)
|
|
107
|
-
# @param array_method A method that returns an array
|
|
108
|
-
# @param out_of_bounds An index greater than the maximum array length
|
|
109
|
-
# @return the last element of the array
|
|
110
|
-
#
|
|
111
|
-
# @overload index_selector(non_array_method, _)
|
|
112
|
-
# @param non_array_method A method that does not return an array
|
|
113
|
-
# @param _ The index is ignored
|
|
114
|
-
# @return the result of the non_array_method
|
|
115
|
-
def index_selector(method, index)
|
|
116
|
-
source = public_send(method)
|
|
117
|
-
is_array = source.is_a? Array
|
|
118
|
-
if is_array && source.length > index
|
|
119
|
-
source[index]
|
|
120
|
-
elsif is_array
|
|
121
|
-
source.last
|
|
122
|
-
else
|
|
123
|
-
source
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
90
|
end
|
|
127
91
|
end
|
|
@@ -40,7 +40,12 @@ module OutputMode
|
|
|
40
40
|
def render(*data)
|
|
41
41
|
io = StringIO.new
|
|
42
42
|
csv = CSV.new(io, **config)
|
|
43
|
-
data.each
|
|
43
|
+
data.each do |datum|
|
|
44
|
+
csv << generate(datum).map do |value|
|
|
45
|
+
next nil if value.nil?
|
|
46
|
+
value.to_s.dump[1...-1]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
44
49
|
io.tap(&:rewind).read
|
|
45
50
|
end
|
|
46
51
|
end
|
|
@@ -31,8 +31,6 @@ module OutputMode
|
|
|
31
31
|
class Tabulated < Output
|
|
32
32
|
# @!attribute [r] renderer
|
|
33
33
|
# @return [Symbol] the renderer type, see: https://github.com/piotrmurach/tty-table#32-renderer
|
|
34
|
-
# @!attribute [r] header
|
|
35
|
-
# @return [Array] An optional header row for the table
|
|
36
34
|
# @!attribute [r] block
|
|
37
35
|
# @return [#call] an optional block of code that configures the renderer
|
|
38
36
|
# @!attribute [r] colorize
|
|
@@ -41,28 +39,25 @@ module OutputMode
|
|
|
41
39
|
# @return An optional header color or array of colors
|
|
42
40
|
# @!attribute [r] row_color
|
|
43
41
|
# @return An optional data color or array of colors
|
|
44
|
-
attr_reader :renderer, :
|
|
42
|
+
attr_reader :renderer, :default, :block, :yes, :no,
|
|
45
43
|
:header_color, :row_color, :colorize
|
|
46
44
|
|
|
47
45
|
# @return [Hash] additional options to +TTY::Table+ renderer
|
|
48
46
|
# @see https://github.com/piotrmurach/tty-table#33-options
|
|
49
47
|
def config; super; end
|
|
50
48
|
|
|
51
|
-
# @overload initialize(*procs, renderer: nil,
|
|
49
|
+
# @overload initialize(*procs, renderer: nil, **config)
|
|
52
50
|
# @param [Array] *procs see {OutputMode::Outputs::Base#initialize}
|
|
53
51
|
# @param [Symbol] :renderer override the default renderer
|
|
54
|
-
# @param [Array<String>] :header the header row of the table
|
|
55
52
|
# @param [Hash] **config additional options to the renderer
|
|
56
53
|
# @yieldparam tty_table_renderer [TTY::Table::Renderer::Base] optional access the underlining TTY::Table renderer
|
|
57
54
|
def initialize(*procs,
|
|
58
55
|
renderer: :unicode,
|
|
59
56
|
colorize: false,
|
|
60
|
-
header: nil,
|
|
61
57
|
header_color: nil,
|
|
62
58
|
row_color: nil,
|
|
63
59
|
**config,
|
|
64
60
|
&block)
|
|
65
|
-
@header = header
|
|
66
61
|
@renderer = renderer
|
|
67
62
|
@block = block
|
|
68
63
|
@header_color = header_color
|
|
@@ -76,7 +71,7 @@ module OutputMode
|
|
|
76
71
|
# @see https://github.com/piotrmurach/tty-table
|
|
77
72
|
def render(*data)
|
|
78
73
|
table = TTY::Table.new header: processed_header
|
|
79
|
-
data.each { |d| table << process_row(
|
|
74
|
+
data.each { |d| table << process_row(d) }
|
|
80
75
|
table.render(renderer, **config, &block) || ''
|
|
81
76
|
end
|
|
82
77
|
|
|
@@ -84,23 +79,25 @@ module OutputMode
|
|
|
84
79
|
|
|
85
80
|
# Colorizes the header when requested
|
|
86
81
|
def processed_header
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
callables.map do |callable|
|
|
83
|
+
header = callable.config.fetch(:header, '')
|
|
84
|
+
color = callable.config.fetch(:header_color) || header_color
|
|
89
85
|
case color
|
|
90
86
|
when nil
|
|
91
|
-
|
|
87
|
+
header.to_s
|
|
92
88
|
when Array
|
|
93
|
-
pastel.decorate(
|
|
89
|
+
pastel.decorate(header.to_s, *color)
|
|
94
90
|
else
|
|
95
|
-
pastel.decorate(
|
|
91
|
+
pastel.decorate(header.to_s, color)
|
|
96
92
|
end
|
|
97
93
|
end
|
|
98
94
|
end
|
|
99
95
|
|
|
100
96
|
# Colorizes the row when requested
|
|
101
|
-
def process_row(
|
|
102
|
-
|
|
103
|
-
|
|
97
|
+
def process_row(model)
|
|
98
|
+
callables.map do |callable|
|
|
99
|
+
d = callable.generator(self).call(model)
|
|
100
|
+
color = callable.config[:row_color] || row_color
|
|
104
101
|
case color
|
|
105
102
|
when NilClass
|
|
106
103
|
d.to_s
|
|
@@ -38,27 +38,25 @@ module OutputMode
|
|
|
38
38
|
# @yieldparam field: An optional field header for the value
|
|
39
39
|
# @yieldparam padding: A padding string which will right align the +field+
|
|
40
40
|
# @yieldparam **config TBA
|
|
41
|
-
def each(section = nil)
|
|
42
|
-
# Select the
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
# Find the max field length
|
|
51
|
-
max = indices.map do |idx|
|
|
52
|
-
output.index_selector(:fields, idx).to_s.length
|
|
53
|
-
end.max
|
|
41
|
+
def each(section = nil, &block)
|
|
42
|
+
# Select the callable objects
|
|
43
|
+
callables = if section == nil
|
|
44
|
+
output.callables
|
|
45
|
+
elsif section == :default
|
|
46
|
+
output.callables.config_select(:section, :default, nil)
|
|
47
|
+
else
|
|
48
|
+
output.callables.config_select(:section, section)
|
|
49
|
+
end
|
|
54
50
|
|
|
55
51
|
# Yield each selected attribute
|
|
56
|
-
|
|
57
|
-
value =
|
|
58
|
-
field =
|
|
59
|
-
|
|
60
|
-
yield(value, field: field, padding: padding)
|
|
52
|
+
objs = callables.pad_each.map do |callable, padding:|
|
|
53
|
+
value = callable.generator(output).call(model)
|
|
54
|
+
field = callable.config[:header]
|
|
55
|
+
[value, {field: field, padding: padding }]
|
|
61
56
|
end
|
|
57
|
+
|
|
58
|
+
# Runs the provided block
|
|
59
|
+
objs.each(&block)
|
|
62
60
|
end
|
|
63
61
|
|
|
64
62
|
# Renders an ERB object within the entry's context. This provides access to the
|
|
@@ -35,12 +35,18 @@ module OutputMode
|
|
|
35
35
|
# @overload register_callable(header:, verbose: true)
|
|
36
36
|
# @param header: The column's header field when displaying to humans
|
|
37
37
|
# @param verbose: Whether the column will be shown in the verbose output
|
|
38
|
+
# @param interactive: Whether the field will be show in the interactive output
|
|
38
39
|
# @param header_color: Override the default color for the header
|
|
39
40
|
# @param row_color: Override the default color for the row
|
|
41
|
+
# @param modes: Additional modes flags for the callable
|
|
40
42
|
# @yieldparam model The subject the column is describing, some sort of data model
|
|
41
|
-
def register_callable(header:, verbose: nil, header_color: nil, row_color: nil, &b)
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
def register_callable(modes: {}, header:, verbose: nil, interactive: nil, header_color: nil, row_color: nil, &b)
|
|
44
|
+
modes = modes.map { |m| [m, true] }.to_h if modes.is_a? Array
|
|
45
|
+
super(modes: modes.merge(verbose: verbose, interactive: interactive),
|
|
46
|
+
header: header,
|
|
47
|
+
header_color: header_color,
|
|
48
|
+
row_color: row_color,
|
|
49
|
+
&b)
|
|
44
50
|
end
|
|
45
51
|
alias_method :register_column, :register_callable
|
|
46
52
|
|
|
@@ -65,10 +71,14 @@ module OutputMode
|
|
|
65
71
|
#
|
|
66
72
|
# An interative/ non-interactive output can be forced by setting the
|
|
67
73
|
# +interactive+ flag to +true+/+false+ respectively
|
|
68
|
-
def build_output(verbose: nil, ascii:
|
|
74
|
+
def build_output(verbose: nil, ascii: nil, interactive: nil, header_color: [:blue, :bold], row_color: :green, context: {})
|
|
69
75
|
# Set the interactive and verbose flags if not provided
|
|
70
76
|
interactive = $stdout.tty? if interactive.nil?
|
|
71
77
|
verbose = !interactive if verbose.nil?
|
|
78
|
+
ascii = !interactive if ascii.nil?
|
|
79
|
+
|
|
80
|
+
# Update the rendering context with the verbosity/interactive settings
|
|
81
|
+
context = context.merge(interactive: interactive, verbose: verbose, ascii: ascii)
|
|
72
82
|
|
|
73
83
|
callables = if verbose
|
|
74
84
|
# Filter out columns that are explicitly not verbose
|
|
@@ -78,6 +88,14 @@ module OutputMode
|
|
|
78
88
|
output_callables.reject(&:verbose?)
|
|
79
89
|
end
|
|
80
90
|
|
|
91
|
+
callables = if interactive
|
|
92
|
+
# Filter out columns that are explicitly not interactive
|
|
93
|
+
callables.select { |o| o.interactive?(true) }
|
|
94
|
+
else
|
|
95
|
+
# Filter out columns that are explicitly interactive
|
|
96
|
+
callables.reject { |o| o.interactive? }
|
|
97
|
+
end
|
|
98
|
+
|
|
81
99
|
if interactive
|
|
82
100
|
# Creates the human readable output
|
|
83
101
|
opts = if ascii
|
|
@@ -85,20 +103,22 @@ module OutputMode
|
|
|
85
103
|
else
|
|
86
104
|
{
|
|
87
105
|
yes: '✓', no: '✕', renderer: :unicode, colorize: TTY::Color.color?,
|
|
88
|
-
header_color:
|
|
89
|
-
row_color:
|
|
106
|
+
header_color: header_color,
|
|
107
|
+
row_color: row_color
|
|
90
108
|
}
|
|
91
109
|
end
|
|
92
110
|
|
|
93
111
|
Outputs::Tabulated.new(*callables,
|
|
94
|
-
|
|
112
|
+
rotate: false,
|
|
95
113
|
padding: [0,1],
|
|
96
114
|
default: '(none)',
|
|
115
|
+
context: context,
|
|
97
116
|
**opts
|
|
98
117
|
)
|
|
99
118
|
else
|
|
100
119
|
# Creates the machine readable output
|
|
101
|
-
Outputs::Delimited.new(*callables, col_sep: "\t", yes: 'yes', no: 'no', default:
|
|
120
|
+
Outputs::Delimited.new(*callables, col_sep: "\t", yes: 'yes', no: 'no', default: nil,
|
|
121
|
+
context: context)
|
|
102
122
|
end
|
|
103
123
|
end
|
|
104
124
|
end
|
|
@@ -35,10 +35,16 @@ module OutputMode
|
|
|
35
35
|
# @overload register_callable(header:, verbose: true)
|
|
36
36
|
# @param header: The human readable key to the field, uses the term 'header' for consistency
|
|
37
37
|
# @param verbose: Whether the field will be shown in the verbose output
|
|
38
|
+
# @param interactive: Whether the field will be show in the interactive output
|
|
38
39
|
# @param section: Define the grouping a callable belongs to. Ignored by default
|
|
40
|
+
# @param modes: Additional modes flags for the callable
|
|
39
41
|
# @yieldparam model The subject the column is describing, some sort of data model
|
|
40
|
-
def register_callable(header:, verbose: nil, section: :other, &b)
|
|
41
|
-
|
|
42
|
+
def register_callable(modes: {}, header:, verbose: nil, interactive: nil, section: :other, &b)
|
|
43
|
+
modes = modes.map { |m| [m, true] }.to_h if modes.is_a? Array
|
|
44
|
+
super(modes: modes.merge(verbose: verbose, interactive: interactive),
|
|
45
|
+
header: header,
|
|
46
|
+
section: section,
|
|
47
|
+
&b)
|
|
42
48
|
end
|
|
43
49
|
alias_method :register_attribute, :register_callable
|
|
44
50
|
|
|
@@ -65,10 +71,14 @@ module OutputMode
|
|
|
65
71
|
#
|
|
66
72
|
# An interative/ non-interactive output can be forced by setting the
|
|
67
73
|
# +interactive+ flag to +true+/+false+ respectively
|
|
68
|
-
def build_output(verbose: nil, ascii:
|
|
74
|
+
def build_output(verbose: nil, ascii: nil, interactive: nil, template: nil, context: {})
|
|
69
75
|
# Set the interactive and verbose flags if not provided
|
|
70
76
|
interactive = $stdout.tty? if interactive.nil?
|
|
71
77
|
verbose = !interactive if verbose.nil?
|
|
78
|
+
ascii = !interactive if ascii.nil?
|
|
79
|
+
|
|
80
|
+
# Update the rendering context with the verbosity/interactive settings
|
|
81
|
+
context = context.merge(interactive: interactive, verbose: verbose, ascii: ascii)
|
|
72
82
|
|
|
73
83
|
callables = if verbose
|
|
74
84
|
# Filter out columns that are explicitly not verbose
|
|
@@ -78,6 +88,14 @@ module OutputMode
|
|
|
78
88
|
output_callables.reject(&:verbose?)
|
|
79
89
|
end
|
|
80
90
|
|
|
91
|
+
callables = if interactive
|
|
92
|
+
# Filter out columns that are explicitly not interactive
|
|
93
|
+
callables.select { |o| o.interactive?(true) }
|
|
94
|
+
else
|
|
95
|
+
# Filter out columns that are explicitly interactive
|
|
96
|
+
callables.reject { |o| o.interactive? }
|
|
97
|
+
end
|
|
98
|
+
|
|
81
99
|
if interactive
|
|
82
100
|
# Creates the human readable output
|
|
83
101
|
opts = if ascii
|
|
@@ -93,10 +111,12 @@ module OutputMode
|
|
|
93
111
|
default: '(none)',
|
|
94
112
|
sections: sections,
|
|
95
113
|
template: template,
|
|
114
|
+
context: context,
|
|
96
115
|
**opts)
|
|
97
116
|
else
|
|
98
117
|
# Creates the machine readable output
|
|
99
|
-
Outputs::Delimited.new(*callables, col_sep: "\t", yes: 'yes', no: 'no', default:
|
|
118
|
+
Outputs::Delimited.new(*callables, col_sep: "\t", yes: 'yes', no: 'no', default: nil,
|
|
119
|
+
context: context)
|
|
100
120
|
end
|
|
101
121
|
end
|
|
102
122
|
end
|
data/lib/output_mode/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: output_mode
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- William McCumsite
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-04-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: tty-table
|