dry-cli-ui 0.5.1 → 0.6.1
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/CHANGELOG.md +15 -0
- data/README.md +64 -9
- data/examples/Gemfile.lock +2 -2
- data/lib/dry/cli/ui/version.rb +1 -1
- data/lib/dry/cli/ui/widgets/multi_progress.rb +49 -5
- data/lib/dry/cli/ui/widgets/progress.rb +29 -3
- data/lib/dry/cli/ui.rb +52 -10
- data/sig/dry/cli/ui.rbs +5 -0
- 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: d64ee9f8fedbc7de0fcd1875acf59d07876ef6acaffbfcc8574b197de0e8d6fd
|
|
4
|
+
data.tar.gz: 2f7e11eca1a0dff40b3df7cba685bca7f97d4884515db1107805036e746e20bc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d9105f75325a1a7f8282e989d4c847320fb481880a7a529041d98d4bff9457dc5235d08a5c3b311c0b3d442a6dc4c3923b6c72844bd2fbb55ec04f2824b906e3
|
|
7
|
+
data.tar.gz: d095b784083ba57db9592e51ef2d56274dd9cb187fcac350d35aaea51b8e64c519a800e3f7f899b2b248acfe8035733c4fa63930b64086cdbebea17c8af4636b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## [0.6.1]
|
|
2
|
+
|
|
3
|
+
- A progress handle takes `fail(reason = nil)`, as a `Line` does: the bar ends `𝘅 label 3/3: reason` without raising, in `ui.progress` and in a row of `ui.multi_progress`, where the jobs after it still run and the headline ends `𝘅`. For work that carries on after some of its units failed.
|
|
4
|
+
|
|
5
|
+
## [0.6.0]
|
|
6
|
+
|
|
7
|
+
- `m.spinner(label)` inside `ui.multi_progress` declares a row with a spinner in place of a bar, for a phase whose size is never known, so one widget can show phases of known and unknown size together. The row shows its `Line`'s detail while it runs and ends `[✓] label`; it counts as a job and as no units on the headline.
|
|
8
|
+
|
|
9
|
+
## [0.6.0]
|
|
10
|
+
|
|
11
|
+
- `ui` reads the command's public `stdout`, `stderr` and `stdin`, the streams dry-cli was called with. Before, it looked for `out` and `err`, which dry-cli no longer has, and wrote to `$stdout` and `$stderr` instead. Prompts now read from the command's `stdin`.
|
|
12
|
+
- `ui` builds its console again when those streams change, so a command registered as an instance, or run in-process by `Dry::CLI::Launcher`, writes each call to that call's streams.
|
|
13
|
+
- `ui_options` configures the console `ui` builds, in place of overriding `ui`.
|
|
14
|
+
- Needs dry-cli with public command streams and `Dry::CLI::Launcher`; the Gemfile takes it from kigster/dry-cli until it is released.
|
|
15
|
+
|
|
1
16
|
## [0.5.1]
|
|
2
17
|
|
|
3
18
|
- `ui.stoppable { |stop| ... }` makes Ctrl-C ask for a stop instead of interrupting, and `ui.multi_spinner` and `ui.multi_progress` take `stop:`. Once it is set, the jobs running finish, the rest are skipped, and the headline says `stopping`, then ends skipped. A second Ctrl-C interrupts. `Dry::CLI::UI::Stop` is the object behind it.
|
data/README.md
CHANGED
|
@@ -86,7 +86,7 @@ class Import < ApplicationCommand
|
|
|
86
86
|
end
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
`ui` writes to the command's `
|
|
89
|
+
`ui` writes to the command's `stdout` and `stderr`, and reads prompt answers from its `stdin`: the streams dry-cli was called with. Outside a dry-cli command it uses `$stdout`, `$stderr` and `$stdin`. The console is built again when those streams change, so a command registered as an instance writes each call to that call's streams.
|
|
90
90
|
|
|
91
91
|
### Without dry-cli
|
|
92
92
|
|
|
@@ -399,6 +399,55 @@ Downloading...
|
|
|
399
399
|
|
|
400
400
|
Any other `count:`, or a `total:` that is not a non-negative Integer, raises `ArgumentError`.
|
|
401
401
|
|
|
402
|
+
A phase whose size is never known goes on a row of its own with `m.spinner(label)`, beside the bars. Its row turns and shows the detail its `Line` is given, as in `multi_spinner`, with no bar, and it ends `[✓] label (0.1s)`, or `[𝘅] label: reason` after `line.fail`. It counts as a job and as no units, so `count: :jobs` suits a headline over phases run one at a time:
|
|
403
|
+
|
|
404
|
+
```ruby
|
|
405
|
+
ui.multi_progress("Generating text", concurrent: false, count: :jobs) do |m|
|
|
406
|
+
m.spinner("Finding PDFs") { |line| pdfs = find_pdfs { |dir| line.detail = dir } }
|
|
407
|
+
m.progress("Extracting", total: nil) do |bar|
|
|
408
|
+
bar.total = pdfs.size
|
|
409
|
+
pdfs.each { |pdf| extract(pdf) && bar.advance }
|
|
410
|
+
end
|
|
411
|
+
m.spinner("Indexing") { index }
|
|
412
|
+
end
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
Piped:
|
|
416
|
+
|
|
417
|
+
```text
|
|
418
|
+
Generating text...
|
|
419
|
+
[✓] Finding PDFs (0.0s)
|
|
420
|
+
[✓] Extracting 3/3 (0.0s)
|
|
421
|
+
[✓] Indexing (0.0s)
|
|
422
|
+
✓ Generating text 3/3 (0.0s)
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
`m.spinner` without a block raises `ArgumentError`.
|
|
426
|
+
|
|
427
|
+
A job that carries on after some of its units failed ends its row with `bar.fail(reason)` rather than raising, so the jobs after it still run. Its row ends `[𝘅] label 3/3: reason`, the headline ends `𝘅`, and the call returns as usual. `ui.progress` takes the same `bar.fail`.
|
|
428
|
+
|
|
429
|
+
```ruby
|
|
430
|
+
ui.multi_progress("Generating text", concurrent: false, count: :jobs) do |m|
|
|
431
|
+
m.spinner("Finding PDFs") { pdfs = find_pdfs }
|
|
432
|
+
m.progress("Extracting", total: nil) do |bar|
|
|
433
|
+
bar.total = pdfs.size
|
|
434
|
+
failed = pdfs.count { |pdf| !extract(pdf).tap { bar.advance } }
|
|
435
|
+
bar.fail("#{failed} failed") if failed.positive?
|
|
436
|
+
end
|
|
437
|
+
m.spinner("Indexing") { index }
|
|
438
|
+
end
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
Piped, with one PDF that would not extract:
|
|
442
|
+
|
|
443
|
+
```text
|
|
444
|
+
Generating text...
|
|
445
|
+
[✓] Finding PDFs (0.0s)
|
|
446
|
+
[𝘅] Extracting 3/3: 1 failed (0.0s)
|
|
447
|
+
[✓] Indexing (0.0s)
|
|
448
|
+
𝘅 Generating text 3/3 (0.0s)
|
|
449
|
+
```
|
|
450
|
+
|
|
402
451
|
Piped:
|
|
403
452
|
|
|
404
453
|
```text
|
|
@@ -725,7 +774,7 @@ Errors raised inside a block are never swallowed: the widget marks itself failed
|
|
|
725
774
|
| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
726
775
|
| `info`, `success`, `box`, `table`, `status` at those levels | `debug`, `warn`, `error`, `fatal`, `popup`, spinners, progress bars, their multi forms, task trees, the status bar, prompts |
|
|
727
776
|
|
|
728
|
-
`mycli export > rules.csv` therefore writes only the command's results to the file, while its progress stays on the screen. `ui` writes to the streams dry-cli was called with, so `Dry::CLI.new(registry).call(
|
|
777
|
+
`mycli export > rules.csv` therefore writes only the command's results to the file, while its progress stays on the screen. `ui` writes to the streams dry-cli was called with, so `Dry::CLI.new(registry).call(stdout: io, stderr: io)` captures everything.
|
|
729
778
|
|
|
730
779
|
A stream that is not a terminal, or runs under `TERM=dumb`, gets no animation, no cursor movement and no escape codes. [`NO_COLOR`](https://no-color.org) turns colour off and leaves animation on.
|
|
731
780
|
|
|
@@ -780,20 +829,18 @@ end
|
|
|
780
829
|
|
|
781
830
|
### Console options
|
|
782
831
|
|
|
783
|
-
Override `
|
|
832
|
+
Override `ui_options` to configure the console `ui` builds. The streams come from the command:
|
|
784
833
|
|
|
785
834
|
```ruby
|
|
786
835
|
class ApplicationCommand < Dry::CLI::Command
|
|
787
836
|
include Dry::CLI::UI
|
|
788
837
|
|
|
789
|
-
def
|
|
790
|
-
|
|
791
|
-
out: out || $stdout,
|
|
792
|
-
err: err || $stderr,
|
|
838
|
+
private def ui_options
|
|
839
|
+
{
|
|
793
840
|
box_width: 72, # boxes are 72 columns rather than the whole terminal
|
|
794
841
|
color: nil, # true or false to override detection
|
|
795
842
|
animate: nil # true or false to override detection
|
|
796
|
-
|
|
843
|
+
}
|
|
797
844
|
end
|
|
798
845
|
end
|
|
799
846
|
```
|
|
@@ -837,7 +884,15 @@ err.string # => "Loading...\n✓ Loading (0.0s)\nContinue? (y/N) "
|
|
|
837
884
|
out.string # => the Success box
|
|
838
885
|
```
|
|
839
886
|
|
|
840
|
-
Through dry-cli, `Dry::CLI.new(registry).call(arguments: %w[import],
|
|
887
|
+
Through dry-cli, `Dry::CLI.new(registry).call(arguments: %w[import], stdin: input, stdout: out, stderr: err)` gives every command's `ui` those streams.
|
|
888
|
+
|
|
889
|
+
To run the whole CLI in the same process as its specs, as Aruba's in-process launcher does, bind a `Dry::CLI::Launcher` to it. Each run gets its own streams, and exits are recorded rather than ending the process:
|
|
890
|
+
|
|
891
|
+
```ruby
|
|
892
|
+
Launcher = Dry::CLI::Launcher[MyCLI::Commands]
|
|
893
|
+
|
|
894
|
+
Launcher.new(%w[import], StringIO.new("y\n"), out, err, kernel).execute!
|
|
895
|
+
```
|
|
841
896
|
|
|
842
897
|
## Relationship to dry-cli-help
|
|
843
898
|
|
data/examples/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
dry-cli-ui (0.
|
|
4
|
+
dry-cli-ui (0.6.1)
|
|
5
5
|
concurrent-ruby (~> 1.3)
|
|
6
6
|
dry-cli (>= 1.0)
|
|
7
7
|
pastel (~> 0.8)
|
|
@@ -84,7 +84,7 @@ CHECKSUMS
|
|
|
84
84
|
dry-cli (1.4.1) sha256=b8015bb76c708aa8705a36faf694973e75eeeffca39b89c8e172dc6f66a7d874
|
|
85
85
|
dry-cli-autocomplete (0.1.3) sha256=14f76447bda0000c71739b585c827dc0a0a763e30a68a8b4b2dff91f640768e4
|
|
86
86
|
dry-cli-help (0.2.1) sha256=eaaaf6edb787ffe810425b4e4bb1a675d89397ccc759102d70b5b26e7bc692da
|
|
87
|
-
dry-cli-ui (0.
|
|
87
|
+
dry-cli-ui (0.6.1)
|
|
88
88
|
dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc
|
|
89
89
|
forwardable (1.4.0) sha256=f1cd40cc9812937980e1c76f1aa053660990a7c9b6a98fc37d945468afcce838
|
|
90
90
|
pastel (0.8.0) sha256=481da9fb7d2f6e6b1a08faf11fa10363172dc40fd47848f096ae21209f805a75
|
data/lib/dry/cli/ui/version.rb
CHANGED
|
@@ -11,6 +11,12 @@ module Dry
|
|
|
11
11
|
# runs, and is replaced by `✓ label 120/120 (1.1s)` when it ends. The
|
|
12
12
|
# bar's characters come from {Configuration#bar_format}.
|
|
13
13
|
#
|
|
14
|
+
# A job declared with `spinner` instead has no bar: its row turns and
|
|
15
|
+
# shows its {Line}'s detail, as in {MultiSpinner}, and ends
|
|
16
|
+
# `✓ label (0.4s)`. It suits a phase whose size is never known, among
|
|
17
|
+
# phases whose size is. It counts as a job and as no units, so a
|
|
18
|
+
# headline over such rows reads best with `count: :jobs`.
|
|
19
|
+
#
|
|
14
20
|
# @example
|
|
15
21
|
# ui.multi_progress("Downloading") do |m|
|
|
16
22
|
# files.each do |file|
|
|
@@ -20,6 +26,13 @@ module Dry
|
|
|
20
26
|
# end
|
|
21
27
|
# end
|
|
22
28
|
#
|
|
29
|
+
# @example Phases, one at a time, some of known size
|
|
30
|
+
# ui.multi_progress("Generating", concurrent: false, count: :jobs) do |m|
|
|
31
|
+
# m.spinner("Finding") { |line| found = find { |dir| line.detail = dir } }
|
|
32
|
+
# m.progress("Extracting", total: nil) { |bar| bar.total = found.size; found.each { extract(it) && bar.advance } }
|
|
33
|
+
# m.spinner("Indexing") { index }
|
|
34
|
+
# end
|
|
35
|
+
#
|
|
23
36
|
# See {Multi} for how the jobs run and how the rows are drawn.
|
|
24
37
|
class MultiProgress < Multi
|
|
25
38
|
# What the declaration block is given.
|
|
@@ -48,6 +61,20 @@ module Dry
|
|
|
48
61
|
@jobs << Multi::Job.new(label, work, Progress::Handle.new(total, nil, color: Progress.color(color)))
|
|
49
62
|
self
|
|
50
63
|
end
|
|
64
|
+
|
|
65
|
+
# Declares a job with a spinner in place of a bar, for work whose
|
|
66
|
+
# size is never known.
|
|
67
|
+
#
|
|
68
|
+
# @param label [String]
|
|
69
|
+
# @yieldparam line [Line] reports on the work while it runs
|
|
70
|
+
# @return [self]
|
|
71
|
+
# @raise [ArgumentError] without a block
|
|
72
|
+
def spinner(label, &work)
|
|
73
|
+
raise ArgumentError, "spinner #{label.inspect} needs a block" unless work
|
|
74
|
+
|
|
75
|
+
@jobs << Multi::Job.new(label, work, Line.new)
|
|
76
|
+
self
|
|
77
|
+
end
|
|
51
78
|
end
|
|
52
79
|
|
|
53
80
|
# What the headline bar can count.
|
|
@@ -78,19 +105,33 @@ module Dry
|
|
|
78
105
|
private
|
|
79
106
|
|
|
80
107
|
# @param job [Job]
|
|
81
|
-
# @return [
|
|
82
|
-
def
|
|
108
|
+
# @return [Boolean] whether the job was declared with `spinner`
|
|
109
|
+
def spinner?(job) = job.handle.is_a?(Line)
|
|
110
|
+
|
|
111
|
+
# @param job [Job]
|
|
112
|
+
# @return [Object]
|
|
113
|
+
def call(job) = spinner?(job) ? Line.call(job.work, job.handle) : super
|
|
114
|
+
|
|
115
|
+
# @param job [Job]
|
|
116
|
+
# @return [Boolean] whether its line or its bar was told to fail
|
|
117
|
+
def reported_failure?(job) = job.handle.failed?
|
|
118
|
+
|
|
119
|
+
# @param job [Job]
|
|
120
|
+
# @return [Progress::Handle, nil] nil for a spinner, which has no progress
|
|
121
|
+
def progress_of(job) = spinner?(job) ? nil : job.handle
|
|
83
122
|
|
|
84
123
|
# @param job [Job]
|
|
85
124
|
# @param width [Integer]
|
|
86
125
|
# @return [String]
|
|
87
126
|
def running(job, width)
|
|
127
|
+
return [job.label, job.handle.detail].reject(&:empty?).join(" ") if spinner?(job)
|
|
128
|
+
|
|
88
129
|
"#{job.label.ljust(width)} #{meter(job.handle.current, job.handle.total, job.started, job.handle.color)}"
|
|
89
130
|
end
|
|
90
131
|
|
|
91
132
|
# @param job [Job]
|
|
92
133
|
# @return [String]
|
|
93
|
-
def summary(job) =
|
|
134
|
+
def summary(job) = job.handle.summary(job.label)
|
|
94
135
|
|
|
95
136
|
# @param width [Integer]
|
|
96
137
|
# @return [String]
|
|
@@ -105,7 +146,7 @@ module Dry
|
|
|
105
146
|
def current
|
|
106
147
|
return jobs.count(&:seconds) if @count == :jobs
|
|
107
148
|
|
|
108
|
-
|
|
149
|
+
bars.sum { |job| job.handle.current }
|
|
109
150
|
end
|
|
110
151
|
|
|
111
152
|
# @return [Integer] the total given; or units across every job,
|
|
@@ -114,9 +155,12 @@ module Dry
|
|
|
114
155
|
return @total if @total
|
|
115
156
|
return jobs.size if @count == :jobs
|
|
116
157
|
|
|
117
|
-
|
|
158
|
+
bars.sum { |job| job.handle.total || job.handle.current }
|
|
118
159
|
end
|
|
119
160
|
|
|
161
|
+
# @return [Array<Job>] the jobs that have a bar
|
|
162
|
+
def bars = jobs.reject { spinner?(it) }
|
|
163
|
+
|
|
120
164
|
# `[◼◼◼ ] 48% 96/200 ETA 3.1s`, with the count right-aligned to
|
|
121
165
|
# the widest any row can show, so every count ends in one column.
|
|
122
166
|
#
|
|
@@ -56,6 +56,33 @@ module Dry
|
|
|
56
56
|
self
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
+
# Ends the work as a failure when the block returns, without
|
|
60
|
+
# raising: for work that went on after some of its units failed.
|
|
61
|
+
#
|
|
62
|
+
# @param reason [#to_s, nil] said after the count, such as "2 failed"
|
|
63
|
+
# @return [self]
|
|
64
|
+
def fail(reason = nil)
|
|
65
|
+
@failed = true
|
|
66
|
+
@reason = reason&.to_s
|
|
67
|
+
self
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# @return [Boolean] whether {#fail} was called
|
|
71
|
+
def failed? = @failed == true
|
|
72
|
+
|
|
73
|
+
# @return [String, nil] what {#fail} was given
|
|
74
|
+
attr_reader :reason
|
|
75
|
+
|
|
76
|
+
# The label and the count, with the failure's reason after it when
|
|
77
|
+
# there is one: `Extracting 1002/1002: 2 failed`.
|
|
78
|
+
#
|
|
79
|
+
# @param label [String]
|
|
80
|
+
# @return [String]
|
|
81
|
+
def summary(label)
|
|
82
|
+
count = "#{label} #{current}/#{total || '?'}"
|
|
83
|
+
failed? && !reason.to_s.empty? ? "#{count}: #{reason}" : count
|
|
84
|
+
end
|
|
85
|
+
|
|
59
86
|
private
|
|
60
87
|
|
|
61
88
|
# @return [TTY::ProgressBar, nil]
|
|
@@ -150,14 +177,13 @@ module Dry
|
|
|
150
177
|
terminal.started(handle, label, progress: handle)
|
|
151
178
|
ok = false
|
|
152
179
|
result = yield handle
|
|
153
|
-
ok =
|
|
180
|
+
ok = !handle.failed?
|
|
154
181
|
result
|
|
155
182
|
ensure
|
|
156
183
|
if handle
|
|
157
184
|
bar&.stop
|
|
158
185
|
terminal.finished(handle, ok)
|
|
159
|
-
|
|
160
|
-
terminal.puts(Outcome.line(terminal, ok ? :done : :failed, summary, clock.call - started))
|
|
186
|
+
terminal.puts(Outcome.line(terminal, ok ? :done : :failed, handle.summary(label), clock.call - started))
|
|
161
187
|
end
|
|
162
188
|
end
|
|
163
189
|
|
data/lib/dry/cli/ui.rb
CHANGED
|
@@ -69,23 +69,65 @@ module Dry
|
|
|
69
69
|
def reset!
|
|
70
70
|
@config = nil
|
|
71
71
|
end
|
|
72
|
+
|
|
73
|
+
# The IO beneath a dry-cli stream, or the stream itself when it is not one.
|
|
74
|
+
#
|
|
75
|
+
# Asks for the class rather than for `raw`, which `io/console` also defines on every IO, to
|
|
76
|
+
# put a terminal into raw mode.
|
|
77
|
+
#
|
|
78
|
+
# @param stream [IO, Dry::CLI::Stream]
|
|
79
|
+
# @return [IO]
|
|
80
|
+
def raw(stream)
|
|
81
|
+
defined?(Dry::CLI::Stream) && stream.is_a?(Dry::CLI::Stream) ? stream.raw : stream
|
|
82
|
+
end
|
|
72
83
|
end
|
|
73
84
|
|
|
74
|
-
# The console this command presents through.
|
|
75
|
-
# `out` and `err` when dry-cli has set them, and to `$stdout` and
|
|
76
|
-
# `$stderr` otherwise.
|
|
85
|
+
# The console this command presents through.
|
|
77
86
|
#
|
|
78
|
-
#
|
|
87
|
+
# In a dry-cli command it writes to the command's own `stdout` and `stderr`, and reads prompt
|
|
88
|
+
# answers from its `stdin`: the streams the CLI was called with. Anywhere else it uses
|
|
89
|
+
# `$stdout`, `$stderr` and `$stdin`.
|
|
79
90
|
#
|
|
80
|
-
#
|
|
81
|
-
#
|
|
91
|
+
# The console is built again whenever those streams change. A command registered as an
|
|
92
|
+
# instance is used for every call to its CLI, each time with that call's streams, as when a
|
|
93
|
+
# test suite runs the CLI in-process with a StringIO per test.
|
|
94
|
+
#
|
|
95
|
+
# Configure the console by overriding {#ui_options}.
|
|
82
96
|
#
|
|
83
97
|
# @return [Dry::CLI::UI::Console]
|
|
84
98
|
def ui
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
)
|
|
99
|
+
streams = ui_streams
|
|
100
|
+
@ui = nil unless @ui_streams && streams.all? { |name, io| @ui_streams[name].equal?(io) }
|
|
101
|
+
@ui_streams = streams
|
|
102
|
+
@ui ||= Console.new(**streams, **ui_options)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
private
|
|
106
|
+
|
|
107
|
+
# The streams {#ui} presents through, as keywords for {Console#initialize}.
|
|
108
|
+
#
|
|
109
|
+
# A dry-cli command gives its own public `stdout`, `stderr` and `stdin`. Its output streams
|
|
110
|
+
# render dry-cli's own styles; the console writes to the IO beneath them, since it decides
|
|
111
|
+
# colour for itself.
|
|
112
|
+
#
|
|
113
|
+
# @return [Hash{Symbol => IO}] `out:`, `err:` and `input:`
|
|
114
|
+
def ui_streams
|
|
115
|
+
{
|
|
116
|
+
out: UI.raw(respond_to?(:stdout) ? stdout : $stdout),
|
|
117
|
+
err: UI.raw(respond_to?(:stderr) ? stderr : $stderr),
|
|
118
|
+
input: respond_to?(:stdin) ? stdin : $stdin
|
|
119
|
+
}
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Options for {Console#initialize} other than its streams. Override it to configure the
|
|
123
|
+
# console {#ui} builds.
|
|
124
|
+
#
|
|
125
|
+
# @example
|
|
126
|
+
# def ui_options = { box_width: 72 }
|
|
127
|
+
#
|
|
128
|
+
# @return [Hash{Symbol => Object}]
|
|
129
|
+
def ui_options
|
|
130
|
+
{}
|
|
89
131
|
end
|
|
90
132
|
end
|
|
91
133
|
end
|
data/sig/dry/cli/ui.rbs
CHANGED
|
@@ -11,6 +11,11 @@ module Dry
|
|
|
11
11
|
|
|
12
12
|
def ui: () -> Console
|
|
13
13
|
|
|
14
|
+
private def ui_streams: () -> { out: untyped, err: untyped, input: untyped }
|
|
15
|
+
private def ui_options: () -> Hash[Symbol, untyped]
|
|
16
|
+
|
|
17
|
+
def self.raw: (untyped stream) -> untyped
|
|
18
|
+
|
|
14
19
|
def self.configure: () { (Configuration config) -> void } -> Configuration
|
|
15
20
|
def self.config: () -> Configuration
|
|
16
21
|
def self.reset!: () -> void
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dry-cli-ui
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Konstantin Gredeskoul
|
|
@@ -229,7 +229,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
229
229
|
- !ruby/object:Gem::Version
|
|
230
230
|
version: '0'
|
|
231
231
|
requirements: []
|
|
232
|
-
rubygems_version: 4.0.
|
|
232
|
+
rubygems_version: 4.0.22
|
|
233
233
|
specification_version: 4
|
|
234
234
|
summary: 'Runtime terminal UI for dry-cli commands: spinners, progress, boxes, task
|
|
235
235
|
trees, tables, prompts'
|