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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a22fcfc5ae8ffc222ac1f19f4d7b5295f9205c8ae95bce7ec8be8884e076f578
4
- data.tar.gz: f96675ec9f6bcc1e6dd905763b45ea776bbf3f78f57629fc50a2cac4a13d22b2
3
+ metadata.gz: '028f7d94178db61fa5e6fc4353b977b1279504486e83dd540ea63fa9bc7bd6ee'
4
+ data.tar.gz: 135e0f649c449fccb49de440e1b4ff33782bb4d1e44e340d818a2c989628d098
5
5
  SHA512:
6
- metadata.gz: 4a61a58643c367f94645d5f3fded92473c44f72ee17553f47f89e27403780cbb3c7bb0fb3a3b36876be8928162434cd28aa847ef6e2ec488ec115c64f06bee2e
7
- data.tar.gz: 9a7eda5a91f80ea1be162bb6bd250da3134f0567fa1c47f6c9e782f6aa80e16ed379e60da48a1ebd59f44dcb80a50cc92467ed9ec42be7196ceb973be66113fb
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby-progress (1.3.5)
4
+ ruby-progress (1.3.6)
5
5
  tty-cursor (~> 0.7)
6
6
  tty-screen (~> 0.8)
7
7
 
data/blog-post.md CHANGED
@@ -1,39 +1,154 @@
1
1
  ---
2
- title: "More CLI Progress Indicators: The ruby-progress Gem"
3
- date: 2025-10-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
- [ripple]: https://brettterpstra.com/2025/06/30/ripple-an-indeterminate-progress-indicator/
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
- # More CLI Progress Indicators: The ruby-progress Gem
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
- The `ruby-progress` gem expands my previous work on [Ripple], adding 2 more indicator types and a new daemon mode to make it more useful in non-Ruby shell scripts.
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
- ## What is ruby-progress?
25
+ {% gif /uploads/2025/10/ruby-progress.mp4 %}
15
26
 
16
- Ruby-progress provides animated progress indicators for command-line applications. Unlike traditional progress bars showing completion percentage, this gem focuses on continuous animations (indeterminate) that indicate activity - perfect for tasks with unpredictable completion times.
27
+ ## The Four Progress Indicators
17
28
 
18
- Three animation styles are available:
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
- - **Ripple**: Wave-like effect across text
21
- - **Worm**: Moving dot pattern that crawls across the screen
22
- - **Twirl**: Classic spinning indicators with various symbols
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
- ## Quick Start
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..." --speed fast
33
- twirl --spinner dots
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
- ## Ruby Integration
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 { heavy_computation }
55
- ```
169
+ worm.animate do
170
+ heavy_computation
171
+ more_work
172
+ end
56
173
 
57
- ## Daemon Mode - The Killer Feature
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
- Run progress indicators in the background while your scripts execute:
184
+ ## Advanced Features Worth Knowing
60
185
 
61
- ```bash
62
- # Start background indicator
63
- worm --daemon --pid-file /tmp/progress.pid --message "Deploying..."
186
+ ### Custom Styling and Icons
64
187
 
65
- # Run your actual work
66
- ./deploy.sh
67
- kubectl apply -f manifests/
188
+ All indicators support custom success and error icons:
68
189
 
69
- # Stop with success message
70
- worm --stop /tmp/progress.pid --message "Deploy complete!" --checkmark
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
- This is incredibly useful for complex deployment scripts where you want continuous visual feedback without interrupting the main process.
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
- ## Advanced Features
202
+ Ripple supports rainbow colors and multiple composable styles:
78
203
 
79
- ### Error Handling
80
- ```ruby
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
- ### Command Integration
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
- ### Visual Customization
100
- ```ruby
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
- ## Real-World Examples
214
+ ### Start/End Character Decoration
112
215
 
113
- ### Deployment Script
216
+ The `--ends` flag lets you wrap your progress indicator with decorative characters:
114
217
 
115
218
  ```bash
116
- #!/bin/bash
117
- worm --daemon-as deploy --message "Deploying..." &
219
+ prg worm --message "Magic" --ends "🎯🎪" --style blocks
220
+ prg ripple "Loading data" --ends "[]" --style rainbow
221
+ ```
118
222
 
119
- git push production main
120
- kubectl rollout status deployment/app
223
+ ### Output Capture
121
224
 
122
- worm --stop-id deploy --stop-success "Success!" --checkmark
123
- ```
225
+ When running commands, you can capture and display output:
124
226
 
125
- ### Data Processing
126
- ```ruby
127
- def import_large_csv(file)
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
- ### Rake Tasks
135
- ```ruby
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
- ## Why ruby-progress?
244
+ **Build Systems**: Integrate into Rake or Make tasks to show progress during compilation.
145
245
 
146
- - **Simple API**: Works in Ruby code and shell scripts
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
- ## Installation & First Steps
248
+ **System Administration**: Show progress during backups, database dumps, or file
249
+ synchronization.
154
250
 
155
- 1. **Install**: `gem install ruby-progress`
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
- ## Conclusion
253
+ The easiest way to get started:
164
254
 
165
- Ruby-progress transforms boring CLI applications into engaging user experiences. Whether building deployment scripts, data processing tools, or utility commands, it provides the visual feedback users expect from modern command-line tools.
255
+ {% iterm "gem install ruby-progress" %}
166
256
 
167
- The daemon mode alone makes it worth trying - no other progress library offers this level of flexibility for complex workflows.
257
+ {% iterm "prg ripple 'Hello, World!'" %}
168
258
 
169
- **Links:**
170
- - [GitHub](https://github.com/ttscoff/ruby-progress)
171
- - [RubyGems](https://rubygems.org/gems/ruby-progress)
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
- *Make your CLI tools feel alive with ruby-progress!*
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.
@@ -8,6 +8,11 @@ require_relative 'twirl_runner'
8
8
  # Twirl CLI (extracted from bin/prg)
9
9
  module TwirlCLI
10
10
  def self.run
11
+ trap('INT') do
12
+ RubyProgress::Utils.show_cursor
13
+ exit
14
+ end
15
+
11
16
  options = TwirlCLI::Options.parse_cli_options
12
17
 
13
18
  if options[:status]
@@ -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]
@@ -15,6 +15,11 @@ module WormCLI
15
15
  end
16
16
 
17
17
  def self.run
18
+ trap('INT') do
19
+ RubyProgress::Utils.show_cursor
20
+ exit
21
+ end
22
+
18
23
  options = WormCLI::Options.parse_cli_options
19
24
 
20
25
  if options[:status]
@@ -2,11 +2,11 @@
2
2
 
3
3
  module RubyProgress
4
4
  # Main gem version
5
- VERSION = '1.3.5'
5
+ VERSION = '1.3.6'
6
6
 
7
7
  # Component-specific versions (patch bumps)
8
- WORM_VERSION = '1.1.5'
9
- TWIRL_VERSION = '1.1.5'
10
- RIPPLE_VERSION = '1.1.5'
11
- FILL_VERSION = '1.0.5'
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-progress
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5
4
+ version: 1.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra