ruby-progress 1.3.5 → 1.3.6
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 +10 -0
- data/Gemfile.lock +1 -1
- data/blog-post.md +201 -109
- data/lib/ruby-progress/cli/twirl_cli.rb +5 -0
- data/lib/ruby-progress/cli/twirl_runner.rb +9 -0
- data/lib/ruby-progress/cli/worm_cli.rb +5 -0
- data/lib/ruby-progress/version.rb +5 -5
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '028f7d94178db61fa5e6fc4353b977b1279504486e83dd540ea63fa9bc7bd6ee'
|
4
|
+
data.tar.gz: 135e0f649c449fccb49de440e1b4ff33782bb4d1e44e340d818a2c989628d098
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 721f3ca96efffadf06b20079ad931f9f47c1580506c7fb4e174323353fafed08f855594561fa77b4af2cbc99ba1d23347662a4363363b5364f41908a936b8cf1
|
7
|
+
data.tar.gz: 262fc8c721794e2f9a13474d00619577c918b70c6af55b30cad2e92d7382af36d3b2d743e3cc3ff0b2159c6498b40ae40f8a057e224f75a12bc385045f23df4e
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [1.3.6] - 2025-10-15
|
9
|
+
|
10
|
+
### Fixed
|
11
|
+
|
12
|
+
- **Interrupt handling**: Fixed Twirl and Worm CLIs to exit cleanly on Ctrl+C (SIGINT) without displaying backtraces
|
13
|
+
- Added top-level `trap('INT')` handlers to both `twirl_cli.rb` and `worm_cli.rb`
|
14
|
+
- Added `rescue Interrupt` clauses to Twirl runner methods for graceful cleanup
|
15
|
+
- All four progress indicators (Ripple, Worm, Twirl, Fill) now have consistent interrupt handling
|
16
|
+
- Properly clean up (show cursor, clear line) and exit with code 130 on interrupt
|
17
|
+
|
8
18
|
## [1.3.5] - 2025-10-15
|
9
19
|
|
10
20
|
### Added
|
data/Gemfile.lock
CHANGED
data/blog-post.md
CHANGED
@@ -1,39 +1,154 @@
|
|
1
1
|
---
|
2
|
-
title: "
|
3
|
-
date: 2025-10-
|
2
|
+
title: "Ruby Progress Indicators for Modern CLI Tools"
|
3
|
+
date: 2025-10-15 11:00
|
4
4
|
categories: [Ruby, CLI, Development Tools]
|
5
|
-
tags: [ruby, cli, progress, animation, terminal]
|
5
|
+
tags: [ruby, cli, progress, animation, terminal, daemon]
|
6
6
|
---
|
7
|
+
I've been playing around with progress bars in the terminal, and I think I've
|
8
|
+
created something genuinely useful.
|
7
9
|
|
8
|
-
|
10
|
+
Yes, I know there are multiple options
|
11
|
+
already available for this, but I wanted something specific: a Ruby library that
|
12
|
+
could be used for command-line scripting, with CLI executables that made it easy
|
13
|
+
to use when scripting in *any* language --- not just Ruby.
|
9
14
|
|
10
|
-
|
15
|
+
The result is `ruby-progress`, a gem that provides four different animated
|
16
|
+
progress indicators, each with its own visual style and use cases.
|
11
17
|
|
12
|
-
|
18
|
+
> If you're scripting in Ruby, I do highly recommend the TTY tools from [Piotr Murach](piotrmurach),
|
19
|
+
such as [tty-progress](https://github.com/piotrmurach/tty-progressbar/). Piotr's
|
20
|
+
TTY tools are much more elegant with a better Ruby API. `ruby-progress` is
|
21
|
+
designed more for use in other shell scripts than it is for detailed Ruby
|
22
|
+
scripting.
|
23
|
+
{:.tip}
|
13
24
|
|
14
|
-
|
25
|
+
{% gif /uploads/2025/10/ruby-progress.mp4 %}
|
15
26
|
|
16
|
-
|
27
|
+
## The Four Progress Indicators
|
17
28
|
|
18
|
-
|
29
|
+
Ripple
|
30
|
+
: creates a wave-like effect across text, with the characters rippling
|
31
|
+
through different visual states. It supports rainbow colors, inverse
|
32
|
+
highlighting, and case transformations. Perfect for text-heavy operations where
|
33
|
+
you want something more dynamic than a simple spinner.
|
19
34
|
|
20
|
-
|
21
|
-
|
22
|
-
|
35
|
+
Worm
|
36
|
+
: displays a moving dot pattern that crawls across the screen using
|
37
|
+
Unicode characters. It includes multiple styles (circles, blocks, geometric
|
38
|
+
shapes) and can move in any direction. Great for file operations, network
|
39
|
+
transfers, or any continuous background task.
|
23
40
|
|
24
|
-
|
41
|
+
Twirl
|
42
|
+
: provides classic spinning indicators with over 35 different spinner
|
43
|
+
styles --- from simple dots to complex geometric patterns. It's the most
|
44
|
+
traditional of the four, but with way more visual variety than typical spinners.
|
45
|
+
|
46
|
+
Fill : is the only determinate indicator in the bunch --- an actual progress bar
|
47
|
+
that shows completion percentage. It can be controlled via command execution or
|
48
|
+
updated programmatically through daemon control messages.
|
49
|
+
|
50
|
+
## Installation and Quick Start
|
51
|
+
|
52
|
+
Installation is straightforward:
|
25
53
|
|
26
54
|
```bash
|
27
|
-
# Install
|
28
55
|
gem install ruby-progress
|
56
|
+
```
|
57
|
+
|
58
|
+
All four indicators are available through a unified `prg` command:
|
29
59
|
|
60
|
+
```bash
|
30
61
|
# Basic usage
|
31
|
-
ripple "Processing files..."
|
32
|
-
worm --message "Loading..." --
|
33
|
-
twirl --
|
62
|
+
prg ripple "Processing files..."
|
63
|
+
prg worm --message "Loading..." --style blocks
|
64
|
+
prg twirl --message "Working..." --style dots --speed fast
|
65
|
+
prg fill --total 100 --report
|
66
|
+
|
67
|
+
# With command execution
|
68
|
+
prg ripple "Building..." --command "make build" --success "Build complete!" --checkmark
|
69
|
+
```
|
70
|
+
|
71
|
+
You can also use the individual commands directly: `ripple`, `worm`, `twirl`, and `fill`.
|
72
|
+
|
73
|
+
## The Killer Feature: Daemon Mode
|
74
|
+
|
75
|
+
Here's where things get interesting. All four indicators support daemon mode,
|
76
|
+
which lets you run a progress indicator in the background while your scripts
|
77
|
+
execute other commands. This is useful for complex workflows.
|
78
|
+
|
79
|
+
```bash
|
80
|
+
# Start a background spinner
|
81
|
+
prg worm --daemon-as deployment --message "Deploying application..."
|
82
|
+
|
83
|
+
# Execute your actual deployment steps
|
84
|
+
git push production main
|
85
|
+
kubectl apply -f manifests/
|
86
|
+
./run-migrations.sh
|
87
|
+
|
88
|
+
# Stop the spinner with a success message
|
89
|
+
prg job stop --daemon-name deployment --message "Deployment complete!" --checkmark
|
90
|
+
```
|
91
|
+
|
92
|
+
The daemon mode uses `Process.fork` and `Process.detach`, so there are no shell
|
93
|
+
job notifications cluttering your output. The progress indicator runs cleanly in
|
94
|
+
the background, providing visual feedback without interfering with your script's
|
95
|
+
execution.
|
96
|
+
|
97
|
+
### Keeping Output Clean
|
98
|
+
|
99
|
+
One of the challenges with daemon mode is preventing command output from
|
100
|
+
disrupting the animation. By default, when you run a progress indicator in
|
101
|
+
daemon mode, any STDOUT or STDERR output from commands executed in your script
|
102
|
+
will appear on the terminal and potentially mess up the animation display.
|
103
|
+
|
104
|
+
Ruby-progress handles this intelligently. When running in daemon mode, the
|
105
|
+
animation continues on its dedicated line while your commands execute. However,
|
106
|
+
if you want to see the output from those commands, you have options:
|
107
|
+
|
108
|
+
```bash
|
109
|
+
# Run command with animation, show output after completion
|
110
|
+
prg ripple "Building..." --command "make build" --stdout
|
111
|
+
|
112
|
+
# Stream output live while animation runs (reserves terminal rows)
|
113
|
+
prg worm "Installing..." --command "npm install" --stdout-live --output-lines 5
|
114
|
+
|
115
|
+
# Run daemon and manually capture output from your script commands
|
116
|
+
prg worm --daemon-as build --message "Building..."
|
117
|
+
make build > /tmp/build.log 2>&1
|
118
|
+
prg job stop --daemon-name build --message "Build complete!" --checkmark
|
119
|
+
cat /tmp/build.log
|
120
|
+
```
|
121
|
+
|
122
|
+
The `--stdout-live` flag is particularly useful --- it reserves a section of the
|
123
|
+
terminal to display live command output while the animation continues above or
|
124
|
+
below it. You control how many lines to reserve with `--output-lines` and where
|
125
|
+
they appear with `--output-position` (above or below the animation).
|
126
|
+
|
127
|
+
### Job Control Commands
|
128
|
+
|
129
|
+
The `prg job` command provides subcommands for controlling background indicators:
|
130
|
+
|
131
|
+
- `prg job stop` --- Stop a running daemon with an optional message
|
132
|
+
- `prg job status` --- Check if a daemon is running and show its PID
|
133
|
+
- `prg job advance` --- Update a fill progress bar by a specific amount
|
134
|
+
|
135
|
+
```bash
|
136
|
+
# Check if a daemon is running
|
137
|
+
prg job status --daemon-name mytask
|
138
|
+
|
139
|
+
# Advance a progress bar remotely
|
140
|
+
prg fill --daemon-as progress --total 100
|
141
|
+
prg job advance --daemon-name progress --amount 10
|
142
|
+
|
143
|
+
# Stop with error state
|
144
|
+
prg job stop --daemon-name mytask --message "Build failed!" --error
|
34
145
|
```
|
35
146
|
|
36
|
-
|
147
|
+
{% paywall "Library and advanced usage" %}
|
148
|
+
|
149
|
+
## Ruby Library Usage
|
150
|
+
|
151
|
+
While the CLI is great for shell scripting, the Ruby API is just as elegant:
|
37
152
|
|
38
153
|
```ruby
|
39
154
|
require 'ruby-progress'
|
@@ -44,131 +159,108 @@ RubyProgress::Ripple.progress("Processing files...") do
|
|
44
159
|
upload_results
|
45
160
|
end
|
46
161
|
|
47
|
-
# Manual control
|
162
|
+
# Manual control for complex scenarios
|
48
163
|
worm = RubyProgress::Worm.new(
|
49
164
|
message: "Custom task",
|
50
165
|
style: 'blocks',
|
51
166
|
speed: 'medium'
|
52
167
|
)
|
53
168
|
|
54
|
-
worm.animate
|
55
|
-
|
169
|
+
worm.animate do
|
170
|
+
heavy_computation
|
171
|
+
more_work
|
172
|
+
end
|
56
173
|
|
57
|
-
|
174
|
+
# Command execution with error handling
|
175
|
+
RubyProgress::Twirl.new(
|
176
|
+
command: "bundle install",
|
177
|
+
message: "Installing gems...",
|
178
|
+
success: "Dependencies installed!",
|
179
|
+
error: "Installation failed",
|
180
|
+
checkmark: true
|
181
|
+
).run_with_command
|
182
|
+
```
|
58
183
|
|
59
|
-
|
184
|
+
## Advanced Features Worth Knowing
|
60
185
|
|
61
|
-
|
62
|
-
# Start background indicator
|
63
|
-
worm --daemon --pid-file /tmp/progress.pid --message "Deploying..."
|
186
|
+
### Custom Styling and Icons
|
64
187
|
|
65
|
-
|
66
|
-
./deploy.sh
|
67
|
-
kubectl apply -f manifests/
|
188
|
+
All indicators support custom success and error icons:
|
68
189
|
|
69
|
-
|
70
|
-
|
190
|
+
```bash
|
191
|
+
prg ripple "Deploying..." \
|
192
|
+
--command "./deploy.sh" \
|
193
|
+
--success "All systems go!" \
|
194
|
+
--error "Houston, we have a problem" \
|
195
|
+
--success-icon "🚀" \
|
196
|
+
--error-icon "💥" \
|
197
|
+
--checkmark
|
71
198
|
```
|
72
199
|
|
73
|
-
|
74
|
-
|
75
|
-
There's a unified binary called `prg` that takes the three types as subcommands, e.g. `prg twirl --checkmark`. You can use any of them either way.
|
200
|
+
### Visual Customization
|
76
201
|
|
77
|
-
|
202
|
+
Ripple supports rainbow colors and multiple composable styles:
|
78
203
|
|
79
|
-
|
80
|
-
|
81
|
-
RubyProgress::Ripple.progress("Risky operation") do
|
82
|
-
might_fail_operation
|
83
|
-
rescue StandardError => e
|
84
|
-
# Automatically stops and shows error state
|
85
|
-
puts "Failed: #{e.message}"
|
86
|
-
end
|
204
|
+
```bash
|
205
|
+
prg ripple "Processing" --style rainbow,inverse,caps
|
87
206
|
```
|
88
207
|
|
89
|
-
|
90
|
-
```ruby
|
91
|
-
# Execute shell commands with progress
|
92
|
-
RubyProgress::Worm.new(
|
93
|
-
command: "pg_dump mydb > backup.sql",
|
94
|
-
success: "Backup complete!",
|
95
|
-
error: "Backup failed"
|
96
|
-
).run_with_command
|
97
|
-
```
|
208
|
+
Worm has directional control and custom character sets:
|
98
209
|
|
99
|
-
|
100
|
-
|
101
|
-
# Rainbow colors and custom styling
|
102
|
-
RubyProgress::Ripple.progress("Colorful task",
|
103
|
-
rainbow: true,
|
104
|
-
speed: :fast,
|
105
|
-
format: :forward_only
|
106
|
-
) do
|
107
|
-
process_with_style
|
108
|
-
end
|
210
|
+
```bash
|
211
|
+
prg worm --direction rtl --style "custom=🟦🟨🟥"
|
109
212
|
```
|
110
213
|
|
111
|
-
|
214
|
+
### Start/End Character Decoration
|
112
215
|
|
113
|
-
|
216
|
+
The `--ends` flag lets you wrap your progress indicator with decorative characters:
|
114
217
|
|
115
218
|
```bash
|
116
|
-
|
117
|
-
|
219
|
+
prg worm --message "Magic" --ends "🎯🎪" --style blocks
|
220
|
+
prg ripple "Loading data" --ends "[]" --style rainbow
|
221
|
+
```
|
118
222
|
|
119
|
-
|
120
|
-
kubectl rollout status deployment/app
|
223
|
+
### Output Capture
|
121
224
|
|
122
|
-
|
123
|
-
```
|
225
|
+
When running commands, you can capture and display output:
|
124
226
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
RubyProgress::Ripple.progress("Importing #{File.basename(file)}...") do
|
129
|
-
CSV.foreach(file, headers: true) { |row| User.create!(row.to_h) }
|
130
|
-
end
|
131
|
-
end
|
132
|
-
```
|
227
|
+
```bash
|
228
|
+
# Show command output after completion
|
229
|
+
prg ripple "Building..." --command "make build" --stdout
|
133
230
|
|
134
|
-
|
135
|
-
|
136
|
-
task :backup do
|
137
|
-
RubyProgress::Worm.new(
|
138
|
-
command: "tar -czf backup.tar.gz app/",
|
139
|
-
success: "Backup created successfully!"
|
140
|
-
).run_with_command
|
141
|
-
end
|
231
|
+
# Display live output with reserved terminal rows
|
232
|
+
prg worm --command "npm install" --output-lines 5 --output-position above
|
142
233
|
```
|
234
|
+
{% endpaywall %}
|
235
|
+
|
236
|
+
## Real-World Use Cases
|
237
|
+
|
238
|
+
**Deployment Scripts**: Show continuous progress during multi-step deployments
|
239
|
+
without blocking command output.
|
240
|
+
|
241
|
+
**Data Processing**: Provide visual feedback during long-running data imports or
|
242
|
+
transformations.
|
143
243
|
|
144
|
-
|
244
|
+
**Build Systems**: Integrate into Rake or Make tasks to show progress during compilation.
|
145
245
|
|
146
|
-
|
147
|
-
- **Visual Appeal**: Engaging animations beyond basic spinners
|
148
|
-
- **Unique Daemon Mode**: Background progress indicators
|
149
|
-
- **Production Ready**: 84.55% test coverage, 113 test examples, zero failures
|
150
|
-
- **Cross-Platform**: Linux, macOS, Windows support
|
151
|
-
- **Reliable**: Comprehensive error handling and edge case coverage
|
246
|
+
**CI/CD Pipelines**: Add visual indicators to pipeline scripts for better monitoring.
|
152
247
|
|
153
|
-
|
248
|
+
**System Administration**: Show progress during backups, database dumps, or file
|
249
|
+
synchronization.
|
154
250
|
|
155
|
-
|
156
|
-
2. **Test CLI**: `ripple "Hello World!"`
|
157
|
-
3. **Try in Ruby**:
|
158
|
-
```ruby
|
159
|
-
require 'ruby-progress'
|
160
|
-
RubyProgress::Ripple.progress("Testing...") { sleep 2 }
|
161
|
-
```
|
251
|
+
## Try It Out
|
162
252
|
|
163
|
-
|
253
|
+
The easiest way to get started:
|
164
254
|
|
165
|
-
|
255
|
+
{% iterm "gem install ruby-progress" %}
|
166
256
|
|
167
|
-
|
257
|
+
{% iterm "prg ripple 'Hello, World!'" %}
|
168
258
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
- [Latest Release](https://github.com/ttscoff/ruby-progress/releases/latest)
|
259
|
+
Or check out the [GitHub repository](https://github.com/ttscoff/ruby-progress)
|
260
|
+
for full documentation, examples, and the complete API reference. The README
|
261
|
+
includes detailed guides for each indicator type and advanced usage patterns.
|
173
262
|
|
174
|
-
|
263
|
+
The gem is also available on
|
264
|
+
[RubyGems](https://rubygems.org/gems/ruby-progress), and the latest release
|
265
|
+
includes significant improvements to daemon mode handling and job control
|
266
|
+
commands.
|
@@ -46,6 +46,11 @@ module TwirlRunner
|
|
46
46
|
|
47
47
|
spinner_thread.kill
|
48
48
|
RubyProgress::Utils.clear_line
|
49
|
+
rescue Interrupt
|
50
|
+
spinner_thread&.kill
|
51
|
+
RubyProgress::Utils.clear_line
|
52
|
+
RubyProgress::Utils.show_cursor
|
53
|
+
exit 130
|
49
54
|
ensure
|
50
55
|
RubyProgress::Utils.show_cursor
|
51
56
|
end
|
@@ -74,6 +79,10 @@ module TwirlRunner
|
|
74
79
|
begin
|
75
80
|
RubyProgress::Utils.hide_cursor
|
76
81
|
loop { spinner.animate }
|
82
|
+
rescue Interrupt
|
83
|
+
RubyProgress::Utils.clear_line
|
84
|
+
RubyProgress::Utils.show_cursor
|
85
|
+
exit 130
|
77
86
|
ensure
|
78
87
|
RubyProgress::Utils.show_cursor
|
79
88
|
if options[:success] || options[:checkmark]
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
module RubyProgress
|
4
4
|
# Main gem version
|
5
|
-
VERSION = '1.3.
|
5
|
+
VERSION = '1.3.6'
|
6
6
|
|
7
7
|
# Component-specific versions (patch bumps)
|
8
|
-
WORM_VERSION = '1.1.
|
9
|
-
TWIRL_VERSION = '1.1.
|
10
|
-
RIPPLE_VERSION = '1.1.
|
11
|
-
FILL_VERSION = '1.0.
|
8
|
+
WORM_VERSION = '1.1.6'
|
9
|
+
TWIRL_VERSION = '1.1.6'
|
10
|
+
RIPPLE_VERSION = '1.1.6'
|
11
|
+
FILL_VERSION = '1.0.6'
|
12
12
|
end
|