dry-cli-ui 0.5.1 → 0.6.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/CHANGELOG.md +4 -0
- data/README.md +25 -0
- data/examples/Gemfile.lock +2 -2
- data/lib/dry/cli/ui/version.rb +1 -1
- data/lib/dry/cli/ui/widgets/multi_progress.rb +53 -5
- 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: 7b4b7ae4869fa6a7623aafc109ef5c26af41436021cc62e4efd5ba87602c64a3
|
|
4
|
+
data.tar.gz: ecbc221a29f2a9be94a4041fd4642ac5367af9bd4b1e7cc4bff828da20e871c5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d46a4ec8716f6aaea3f17d8e2eda6ba29f90272516d812270b77ba604ff372e6327c840cbcc54b9ac7511eabd78dcf709c8c6072932927e6ff72ff6c35a5931d
|
|
7
|
+
data.tar.gz: 0ce772edc045b9deca09aca086de303d7f01cc2ce7ff5ca912077eeb3a5753cd397bc9cdfc8c1b4704d0c125c67f8077176266fc693df6dcbe97a06a9f971850
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
## [0.6.0]
|
|
2
|
+
|
|
3
|
+
- `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.
|
|
4
|
+
|
|
1
5
|
## [0.5.1]
|
|
2
6
|
|
|
3
7
|
- `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
|
@@ -399,6 +399,31 @@ 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
|
+
|
|
402
427
|
Piped:
|
|
403
428
|
|
|
404
429
|
```text
|
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.0)
|
|
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.0)
|
|
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,37 @@ 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]
|
|
117
|
+
def reported_failure?(job) = spinner?(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)
|
|
135
|
+
return job.handle.summary(job.label) if spinner?(job)
|
|
136
|
+
|
|
137
|
+
"#{job.label} #{job.handle.current}/#{job.handle.total || '?'}"
|
|
138
|
+
end
|
|
94
139
|
|
|
95
140
|
# @param width [Integer]
|
|
96
141
|
# @return [String]
|
|
@@ -105,7 +150,7 @@ module Dry
|
|
|
105
150
|
def current
|
|
106
151
|
return jobs.count(&:seconds) if @count == :jobs
|
|
107
152
|
|
|
108
|
-
|
|
153
|
+
bars.sum { |job| job.handle.current }
|
|
109
154
|
end
|
|
110
155
|
|
|
111
156
|
# @return [Integer] the total given; or units across every job,
|
|
@@ -114,9 +159,12 @@ module Dry
|
|
|
114
159
|
return @total if @total
|
|
115
160
|
return jobs.size if @count == :jobs
|
|
116
161
|
|
|
117
|
-
|
|
162
|
+
bars.sum { |job| job.handle.total || job.handle.current }
|
|
118
163
|
end
|
|
119
164
|
|
|
165
|
+
# @return [Array<Job>] the jobs that have a bar
|
|
166
|
+
def bars = jobs.reject { spinner?(it) }
|
|
167
|
+
|
|
120
168
|
# `[◼◼◼ ] 48% 96/200 ETA 3.1s`, with the count right-aligned to
|
|
121
169
|
# the widest any row can show, so every count ends in one column.
|
|
122
170
|
#
|
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.0
|
|
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'
|