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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e560bf8164797ea9cdae72cbc7a49616ed9c8dbad91346fc78c26148b3eb2c97
4
- data.tar.gz: bb204cbe97276cacaf5f75e736096c0ba6d3769413ad1ec732ff99b0ed41ddbd
3
+ metadata.gz: f8cedfd9240c3ab6dd70848fbc63dca19ca4e3eea6d13ccada9e1663c73ca75d
4
+ data.tar.gz: 3a81c872fc39dc070eaa68e0393c0e65d9878f7d54b01bd3ec9af557a40b92e2
5
5
  SHA512:
6
- metadata.gz: '091e1a8fc2e928687b84148b5b90f983ca5c5eb204d65a35978917c4c1ffb95e14e4dc53897ac60af3a7a71b7a08766a2abca3b11a14fa133258b6b464247e13'
7
- data.tar.gz: e35b2ac112952aaeb54327c5db0cc0b2b3132c9859f141440db76159848600744ac83e72974dfb3965c6ae77b81276534361376b2d1a0b9e87d750ed9e95ee81
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
- | `#stop(final_message = 'done')` | Stop with a message |
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
- # This file is kept for backward compatibility but is no longer actively used.
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module Progress
5
- VERSION = '0.1.10'
5
+ VERSION = '0.3.0'
6
6
  end
7
7
  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.1.10
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
- - philiprehberger
7
+ - Philip Rehberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-31 00:00:00.000000000 Z
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, and auto-disables
15
- rendering when not connected to a terminal.
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@users.noreply.github.com
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://github.com/philiprehberger/rb-progress
31
+ homepage: https://philiprehberger.com/open-source-packages/ruby/philiprehberger-progress
31
32
  licenses:
32
33
  - MIT
33
34
  metadata:
34
- homepage_uri: https://github.com/philiprehberger/rb-progress
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: '3.1'
48
+ version: 3.1.0
48
49
  required_rubygems_version: !ruby/object:Gem::Requirement
49
50
  requirements:
50
51
  - - ">="