philiprehberger-progress 0.1.10 → 0.3.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 +39 -0
- data/README.md +55 -1
- data/lib/philiprehberger/progress/multi.rb +54 -1
- data/lib/philiprehberger/progress/spinner.rb +12 -0
- data/lib/philiprehberger/progress/version.rb +1 -1
- data/lib/philiprehberger/progress.rb +25 -0
- metadata +10 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f8cedfd9240c3ab6dd70848fbc63dca19ca4e3eea6d13ccada9e1663c73ca75d
|
|
4
|
+
data.tar.gz: 3a81c872fc39dc070eaa68e0393c0e65d9878f7d54b01bd3ec9af557a40b92e2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 309c39e3e947e5dc7c9465cd4f1a1feff1fa9ec38221a11325243202c8f9e6326f1e60b458138b9d7fb2ec50ddd5b98cdf7425227d4a913b0dda464a3fd3d137
|
|
7
|
+
data.tar.gz: 985d65af32ab52d1310b2f01e24b7024a1595e1357a1f09c074ad9bc636ffb0445a33b00fc5a943472955cf5c0d663df516905cb67140db80734ed6af218300e
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,31 @@ and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.0] - 2026-04-09
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `Spinner#auto_spin(interval: 0.1)` starts a background thread that animates the spinner until `stop` is called
|
|
14
|
+
- `Progress.map(enumerable) { |item| ... }` transforms items with a progress bar, returning the collected results
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Gemspec `required_ruby_version` format to `'>= 3.1.0'` (was `'>= 3.1'`)
|
|
18
|
+
|
|
19
|
+
## [0.2.0] - 2026-04-04
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- Multi-bar support via `Philiprehberger::Progress::Multi` for tracking concurrent tasks
|
|
23
|
+
- `Progress.multi` convenience method
|
|
24
|
+
- GitHub issue template gem version field
|
|
25
|
+
- Feature request "Alternatives considered" field
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- Gemspec author and email to match standard template
|
|
29
|
+
|
|
30
|
+
## [0.1.11] - 2026-03-31
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
- Add GitHub issue templates, dependabot config, and PR template
|
|
34
|
+
|
|
10
35
|
## [0.1.10] - 2026-03-31
|
|
11
36
|
|
|
12
37
|
### Changed
|
|
@@ -67,3 +92,17 @@ and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
67
92
|
- `Progress.spin` convenience method with block support
|
|
68
93
|
- `Progress.each` for iterating enumerables with progress display
|
|
69
94
|
- TTY detection to auto-disable rendering in non-terminal environments
|
|
95
|
+
|
|
96
|
+
[0.3.0]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.3.0
|
|
97
|
+
[0.2.0]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.2.0
|
|
98
|
+
[0.1.11]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.1.11
|
|
99
|
+
[0.1.10]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.1.10
|
|
100
|
+
[0.1.9]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.1.9
|
|
101
|
+
[0.1.8]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.1.8
|
|
102
|
+
[0.1.7]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.1.7
|
|
103
|
+
[0.1.6]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.1.6
|
|
104
|
+
[0.1.5]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.1.5
|
|
105
|
+
[0.1.4]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.1.4
|
|
106
|
+
[0.1.3]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.1.3
|
|
107
|
+
[0.1.2]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.1.2
|
|
108
|
+
[0.1.0]: https://github.com/philiprehberger/rb-progress/releases/tag/v0.1.0
|
data/README.md
CHANGED
|
@@ -68,6 +68,19 @@ Philiprehberger::Progress.spin('Processing...') do |spinner|
|
|
|
68
68
|
end
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
### Auto-spinning
|
|
72
|
+
|
|
73
|
+
Start a background thread that animates the spinner automatically:
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
Philiprehberger::Progress.spin("Deploying...") do |spinner|
|
|
77
|
+
spinner.auto_spin
|
|
78
|
+
deploy! # spinner animates while you work
|
|
79
|
+
end
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The thread is joined automatically when `stop` is called (or when the block completes).
|
|
83
|
+
|
|
71
84
|
### Enumerable Integration
|
|
72
85
|
|
|
73
86
|
```ruby
|
|
@@ -77,6 +90,31 @@ Philiprehberger::Progress.each(items) do |item|
|
|
|
77
90
|
end
|
|
78
91
|
```
|
|
79
92
|
|
|
93
|
+
### Mapping with Progress
|
|
94
|
+
|
|
95
|
+
Transform items while displaying progress:
|
|
96
|
+
|
|
97
|
+
```ruby
|
|
98
|
+
results = Philiprehberger::Progress.map(urls) { |url| fetch(url) }
|
|
99
|
+
# results contains the return values from each block call
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Multi-bar
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
require "philiprehberger/progress"
|
|
106
|
+
|
|
107
|
+
multi = Philiprehberger::Progress.multi do |m|
|
|
108
|
+
downloads = m.add("Downloads", total: 100)
|
|
109
|
+
uploads = m.add("Uploads", total: 50)
|
|
110
|
+
|
|
111
|
+
100.times { downloads.advance }
|
|
112
|
+
50.times { uploads.advance }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
multi.finished? # => true
|
|
116
|
+
```
|
|
117
|
+
|
|
80
118
|
## API
|
|
81
119
|
|
|
82
120
|
### `Philiprehberger::Progress::Bar`
|
|
@@ -99,17 +137,33 @@ end
|
|
|
99
137
|
|--------|-------------|
|
|
100
138
|
| `.new(message:, output: $stderr)` | Create a spinner |
|
|
101
139
|
| `#spin` | Advance to the next frame |
|
|
102
|
-
| `#
|
|
140
|
+
| `#auto_spin(interval: 0.1)` | Start background thread animation |
|
|
141
|
+
| `#stop(final_message = 'done')` | Stop with a message (joins background thread) |
|
|
103
142
|
| `#stopped?` | Whether the spinner is stopped |
|
|
104
143
|
| `#to_s` | Render the current frame with message |
|
|
105
144
|
|
|
145
|
+
### `Philiprehberger::Progress::Multi`
|
|
146
|
+
|
|
147
|
+
| Method | Description |
|
|
148
|
+
|--------|-------------|
|
|
149
|
+
| `Multi.new(output: $stderr)` | Create multi-bar tracker |
|
|
150
|
+
| `Multi#add(label, total:, width: 30)` | Add a named progress bar |
|
|
151
|
+
| `Multi#[](label)` | Retrieve a bar by label |
|
|
152
|
+
| `Multi#labels` | List of bar labels in order |
|
|
153
|
+
| `Multi#bars` | Hash of label to bar |
|
|
154
|
+
| `Multi#finished?` | True when all bars are finished |
|
|
155
|
+
| `Multi#render` | Render all bars to output |
|
|
156
|
+
| `Multi#reset` | Clear all bars |
|
|
157
|
+
|
|
106
158
|
### Module Methods
|
|
107
159
|
|
|
108
160
|
| Method | Description |
|
|
109
161
|
|--------|-------------|
|
|
110
162
|
| `Progress.bar(total:, &block)` | Create bar, auto-finish after block |
|
|
111
163
|
| `Progress.spin(message, &block)` | Create spinner, auto-stop after block |
|
|
164
|
+
| `Progress.multi(output: $stderr, &block)` | Create multi-bar tracker |
|
|
112
165
|
| `Progress.each(enumerable, label: nil) { \|item\| }` | Iterate with progress |
|
|
166
|
+
| `Progress.map(enumerable, label: nil) { \|item\| }` | Transform with progress, returns results |
|
|
113
167
|
|
|
114
168
|
## Development
|
|
115
169
|
|
|
@@ -1,3 +1,56 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
module Philiprehberger
|
|
4
|
+
module Progress
|
|
5
|
+
class Multi
|
|
6
|
+
def initialize(output: $stderr)
|
|
7
|
+
@output = output
|
|
8
|
+
@bars = {}
|
|
9
|
+
@order = []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def add(label, total:, width: 30)
|
|
13
|
+
bar = Bar.new(total: total, width: width, output: @output)
|
|
14
|
+
@bars[label] = bar
|
|
15
|
+
@order << label unless @order.include?(label)
|
|
16
|
+
bar
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def [](label)
|
|
20
|
+
@bars[label]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def bars
|
|
24
|
+
@bars.dup
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def labels
|
|
28
|
+
@order.dup
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def finished?
|
|
32
|
+
return false if @bars.empty?
|
|
33
|
+
|
|
34
|
+
@bars.values.all?(&:finished?)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def render
|
|
38
|
+
return unless @output.respond_to?(:tty?) && @output.tty?
|
|
39
|
+
|
|
40
|
+
lines = @order.map do |label|
|
|
41
|
+
bar = @bars[label]
|
|
42
|
+
"#{label}: #{bar}"
|
|
43
|
+
end
|
|
44
|
+
@output.print("\e[#{lines.size}A") if @rendered_once
|
|
45
|
+
lines.each { |line| @output.puts(line) }
|
|
46
|
+
@rendered_once = true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def reset
|
|
50
|
+
@bars.clear
|
|
51
|
+
@order.clear
|
|
52
|
+
@rendered_once = false
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -23,8 +23,20 @@ module Philiprehberger
|
|
|
23
23
|
self
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def auto_spin(interval: 0.1)
|
|
27
|
+
@auto_thread = Thread.new do
|
|
28
|
+
until @stopped
|
|
29
|
+
spin
|
|
30
|
+
sleep(interval)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
self
|
|
34
|
+
end
|
|
35
|
+
|
|
26
36
|
def stop(final_message = 'done')
|
|
27
37
|
@stopped = true
|
|
38
|
+
@auto_thread&.join
|
|
39
|
+
@auto_thread = nil
|
|
28
40
|
@output.write("\r\e[2K#{final_message}\n") if tty?
|
|
29
41
|
self
|
|
30
42
|
end
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative 'progress/version'
|
|
4
4
|
require_relative 'progress/bar'
|
|
5
5
|
require_relative 'progress/spinner'
|
|
6
|
+
require_relative 'progress/multi'
|
|
6
7
|
|
|
7
8
|
module Philiprehberger
|
|
8
9
|
module Progress
|
|
@@ -30,6 +31,16 @@ module Philiprehberger
|
|
|
30
31
|
end
|
|
31
32
|
end
|
|
32
33
|
|
|
34
|
+
def self.multi(output: $stderr)
|
|
35
|
+
m = Multi.new(output: output)
|
|
36
|
+
if block_given?
|
|
37
|
+
yield m
|
|
38
|
+
m
|
|
39
|
+
else
|
|
40
|
+
m
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
33
44
|
def self.each(enumerable, label: nil, output: $stderr)
|
|
34
45
|
items = enumerable.to_a
|
|
35
46
|
bar = Bar.new(total: items.length, output: output)
|
|
@@ -42,5 +53,19 @@ module Philiprehberger
|
|
|
42
53
|
bar.finish
|
|
43
54
|
items
|
|
44
55
|
end
|
|
56
|
+
|
|
57
|
+
def self.map(enumerable, label: nil, output: $stderr)
|
|
58
|
+
items = enumerable.to_a
|
|
59
|
+
bar = Bar.new(total: items.length, output: output)
|
|
60
|
+
|
|
61
|
+
results = items.map do |item|
|
|
62
|
+
result = yield item
|
|
63
|
+
bar.advance
|
|
64
|
+
result
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
bar.finish
|
|
68
|
+
results
|
|
69
|
+
end
|
|
45
70
|
end
|
|
46
71
|
end
|
metadata
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: philiprehberger-progress
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- Philip Rehberger
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-04-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Display progress bars with percentage, ETA, and throughput, or spinners
|
|
14
|
-
for indeterminate tasks. Supports block-based usage, enumerable iteration
|
|
15
|
-
|
|
14
|
+
for indeterminate tasks. Supports block-based usage, enumerable iteration with each/map,
|
|
15
|
+
background auto-spinning, multi-bar tracking, and auto-disables rendering when not
|
|
16
|
+
connected to a terminal.
|
|
16
17
|
email:
|
|
17
|
-
- philiprehberger
|
|
18
|
+
- me@philiprehberger.com
|
|
18
19
|
executables: []
|
|
19
20
|
extensions: []
|
|
20
21
|
extra_rdoc_files: []
|
|
@@ -27,11 +28,11 @@ files:
|
|
|
27
28
|
- lib/philiprehberger/progress/multi.rb
|
|
28
29
|
- lib/philiprehberger/progress/spinner.rb
|
|
29
30
|
- lib/philiprehberger/progress/version.rb
|
|
30
|
-
homepage: https://
|
|
31
|
+
homepage: https://philiprehberger.com/open-source-packages/ruby/philiprehberger-progress
|
|
31
32
|
licenses:
|
|
32
33
|
- MIT
|
|
33
34
|
metadata:
|
|
34
|
-
homepage_uri: https://
|
|
35
|
+
homepage_uri: https://philiprehberger.com/open-source-packages/ruby/philiprehberger-progress
|
|
35
36
|
source_code_uri: https://github.com/philiprehberger/rb-progress
|
|
36
37
|
changelog_uri: https://github.com/philiprehberger/rb-progress/blob/main/CHANGELOG.md
|
|
37
38
|
bug_tracker_uri: https://github.com/philiprehberger/rb-progress/issues
|
|
@@ -44,7 +45,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
44
45
|
requirements:
|
|
45
46
|
- - ">="
|
|
46
47
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
48
|
+
version: 3.1.0
|
|
48
49
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
50
|
requirements:
|
|
50
51
|
- - ">="
|