philiprehberger-progress 0.2.0 → 0.4.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: c6f9be35e1424be64489b24f5d9b63bbf9a9b202b154c6c5c2139a8845a94f75
4
- data.tar.gz: 0d8fedddb6f6a594f7ad766d996d2c98fb5a974ee4893942ce6be419eaaa653a
3
+ metadata.gz: 9d1ecb051d55213a818343c3133c067129bf55e65b6677a2efb9be49c249ab5b
4
+ data.tar.gz: '0039452f607ef4f9fe1f1a1098b31039c6ea7ecbc9c0618c8f8fba78b5464763'
5
5
  SHA512:
6
- metadata.gz: cefbeb2571f5812ffbacc35d5dbf1df5b36523d7a51809b7030e945c7a3081e24934066a8cf3b8d4a261d87104da492d4d75637657da485c70ad48506688ddd7
7
- data.tar.gz: fff6cb774a53a996ec6c757c8d5c3123656691d5cf7fe91dc21169ff4ac37819070427980784b852ce908b240cc18394c7bb584a8fffe74352e6dab01343f25b
6
+ metadata.gz: da6edc69bcc8dc77d091ba848dae89fb8f8e5054ceb1f9c6991537e85554b8a3bbde4cef23b94089d0c6194827ae6c13e3a7cb02f875d9d7ca9e3960519d7023
7
+ data.tar.gz: 5692a7b42fb906e3234117a3a96ca0ad2c1af88d558bc41e7a787cd8c1cc954a5c317613b91ff8d913b27b87263ea279d8bf497b19f17886cf57c8141578b6f8
data/CHANGELOG.md CHANGED
@@ -2,11 +2,30 @@
2
2
 
3
3
  All notable changes to this gem will be documented in this file.
4
4
 
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
- and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.0] - 2026-04-09
11
+
12
+ ### Added
13
+ - `Bar#set(n)` to set absolute progress position
14
+ - `Bar#reset` to restart the bar from 0, preserving configuration
15
+ - `Spinner#message=` to update the spinner message dynamically
16
+
17
+ ### Changed
18
+ - Standardize CHANGELOG header format to match template
19
+
20
+ ## [0.3.0] - 2026-04-09
21
+
22
+ ### Added
23
+ - `Spinner#auto_spin(interval: 0.1)` starts a background thread that animates the spinner until `stop` is called
24
+ - `Progress.map(enumerable) { |item| ... }` transforms items with a progress bar, returning the collected results
25
+
26
+ ### Fixed
27
+ - Gemspec `required_ruby_version` format to `'>= 3.1.0'` (was `'>= 3.1'`)
28
+
10
29
  ## [0.2.0] - 2026-04-04
11
30
 
12
31
  ### Added
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,15 @@ 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
+
80
102
  ### Multi-bar
81
103
 
82
104
  ```ruby
@@ -101,6 +123,8 @@ multi.finished? # => true
101
123
  |--------|-------------|
102
124
  | `.new(total:, width: 30, output: $stderr)` | Create a progress bar |
103
125
  | `#advance(n = 1)` | Advance by `n` items |
126
+ | `#set(n)` | Set absolute progress position (clamped to 0..total) |
127
+ | `#reset` | Reset to 0, clear finished state, restart timer |
104
128
  | `#finish` | Mark as complete |
105
129
  | `#finished?` | Whether the bar is finished |
106
130
  | `#percentage` | Current percentage (0.0 to 100.0) |
@@ -114,8 +138,10 @@ multi.finished? # => true
114
138
  | Method | Description |
115
139
  |--------|-------------|
116
140
  | `.new(message:, output: $stderr)` | Create a spinner |
141
+ | `#message=` | Update the spinner message dynamically |
117
142
  | `#spin` | Advance to the next frame |
118
- | `#stop(final_message = 'done')` | Stop with a message |
143
+ | `#auto_spin(interval: 0.1)` | Start background thread animation |
144
+ | `#stop(final_message = 'done')` | Stop with a message (joins background thread) |
119
145
  | `#stopped?` | Whether the spinner is stopped |
120
146
  | `#to_s` | Render the current frame with message |
121
147
 
@@ -140,6 +166,7 @@ multi.finished? # => true
140
166
  | `Progress.spin(message, &block)` | Create spinner, auto-stop after block |
141
167
  | `Progress.multi(output: $stderr, &block)` | Create multi-bar tracker |
142
168
  | `Progress.each(enumerable, label: nil) { \|item\| }` | Iterate with progress |
169
+ | `Progress.map(enumerable, label: nil) { \|item\| }` | Transform with progress, returns results |
143
170
 
144
171
  ## Development
145
172
 
@@ -25,6 +25,28 @@ module Philiprehberger
25
25
  self
26
26
  end
27
27
 
28
+ # Set absolute progress position.
29
+ #
30
+ # @param n [Integer] the new current value (clamped to 0..total)
31
+ # @return [self]
32
+ def set(n)
33
+ return self if @finished
34
+
35
+ @current = [[n, 0].max, @total].min
36
+ render_to_output
37
+ self
38
+ end
39
+
40
+ # Reset the bar to 0, preserving total and width. Restarts the timer.
41
+ #
42
+ # @return [self]
43
+ def reset
44
+ @current = 0
45
+ @finished = false
46
+ @start_time = now
47
+ self
48
+ end
49
+
28
50
  def finish
29
51
  @current = @total
30
52
  @finished = true
@@ -6,7 +6,7 @@ module Philiprehberger
6
6
  FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807",
7
7
  "\u280F"].freeze
8
8
 
9
- attr_reader :message
9
+ attr_accessor :message
10
10
 
11
11
  def initialize(message:, output: $stderr)
12
12
  @message = message
@@ -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.2.0'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
@@ -53,5 +53,19 @@ module Philiprehberger
53
53
  bar.finish
54
54
  items
55
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
56
70
  end
57
71
  end
metadata CHANGED
@@ -1,18 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-progress
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.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-04-05 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
18
  - me@philiprehberger.com
18
19
  executables: []
@@ -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
  - - ">="