ruby-progress 1.3.5 → 1.3.7
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 +26 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/blog-post.md +201 -109
- data/lib/ruby-progress/cli/fill_options.rb +3 -0
- data/lib/ruby-progress/cli/ripple_options.rb +3 -0
- data/lib/ruby-progress/cli/twirl_cli.rb +20 -0
- data/lib/ruby-progress/cli/twirl_options.rb +3 -0
- data/lib/ruby-progress/cli/twirl_runner.rb +29 -0
- data/lib/ruby-progress/cli/worm_cli.rb +33 -0
- data/lib/ruby-progress/cli/worm_options.rb +3 -0
- data/lib/ruby-progress/daemon.rb +42 -0
- data/lib/ruby-progress/fill.rb +51 -9
- data/lib/ruby-progress/fill_cli.rb +4 -0
- data/lib/ruby-progress/output_capture.rb +102 -27
- data/lib/ruby-progress/ripple.rb +52 -0
- data/lib/ruby-progress/utils.rb +92 -11
- data/lib/ruby-progress/version.rb +12 -5
- data/lib/ruby-progress/worm.rb +23 -1
- data/project-page.md +162 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ed28989b5200a0ba018f976c1b7b90b8077916959633a5e2ea576de25bb6ddb5
|
|
4
|
+
data.tar.gz: f5c0ddea618bad931125e8f3195162e3cae7405c583fe27da5759d0febf30fa1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6722478a39177ac8c8618035abbd0b155afc275eb53120c7c89ff9f7a0c2194a02313efb5cf19ec59205d5f8002435edbef41c7cf5590f7e5f30ad00fa10f02d
|
|
7
|
+
data.tar.gz: 861feef40116e9c4a5f1c18e2455032a286c9c38fd7bccca19d24c1438b2554be90db4b5c820421b87301b4f21a3527a9bb17095c35140cf4ddddd0d8551539a
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,32 @@ 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.7] - 2025-10-22
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- PTY command spawning now executes via the user's login shell to support shell aliases/functions and ensure PATH customizations are honored.
|
|
13
|
+
- Uses `ENV['SHELL']` when available (fallback `/bin/sh`).
|
|
14
|
+
- `bash`/`zsh`/`sh`: `-lc` is used; `fish`: `-l -c` is used.
|
|
15
|
+
- Resolves `Errno::ENOENT` when running commands like `-c 'r fast'` under `--stdout-live`.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Refactored output capture internals:
|
|
20
|
+
- Introduced `RubyProgress::ShellExec.build_shell_argv` for shell argv construction.
|
|
21
|
+
- Extracted terminal reservation to `RubyProgress::OutputUI.reserve_space`.
|
|
22
|
+
- Reduced method complexity and addressed linter warnings without behavior changes.
|
|
23
|
+
|
|
24
|
+
## [1.3.6] - 2025-10-15
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **Interrupt handling**: Fixed Twirl and Worm CLIs to exit cleanly on Ctrl+C (SIGINT) without displaying backtraces
|
|
29
|
+
- Added top-level `trap('INT')` handlers to both `twirl_cli.rb` and `worm_cli.rb`
|
|
30
|
+
- Added `rescue Interrupt` clauses to Twirl runner methods for graceful cleanup
|
|
31
|
+
- All four progress indicators (Ripple, Worm, Twirl, Fill) now have consistent interrupt handling
|
|
32
|
+
- Properly clean up (show cursor, clear line) and exit with code 130 on interrupt
|
|
33
|
+
|
|
8
34
|
## [1.3.5] - 2025-10-15
|
|
9
35
|
|
|
10
36
|
### Added
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://www.ruby-lang.org/)
|
|
7
7
|
<!-- [](#) -->
|
|
8
8
|
|
|
9
|
-
This repository contains
|
|
9
|
+
This repository contains a collection of Ruby progress indicator projects: **Ripple**, **Worm**, **Twirl**, and **Fill**. All provide animated terminal progress indicators with different visual styles and features.
|
|
10
10
|
|
|
11
11
|
## Table of Contents
|
|
12
12
|
|
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.
|
|
@@ -8,6 +8,9 @@ module RubyProgress
|
|
|
8
8
|
# rubocop:disable Metrics/AbcSize
|
|
9
9
|
module Options
|
|
10
10
|
# rubocop :disable Metrics/MethodLength
|
|
11
|
+
# Parse CLI options for the fill subcommand.
|
|
12
|
+
#
|
|
13
|
+
# @return [Hash] parsed options keyed by symbols
|
|
11
14
|
def self.parse_cli_options
|
|
12
15
|
options = {
|
|
13
16
|
style: :blocks,
|
|
@@ -6,6 +6,9 @@ require 'json'
|
|
|
6
6
|
module RippleCLI
|
|
7
7
|
# Option parsing extracted to its own file to reduce module size of RippleCLI.
|
|
8
8
|
module Options
|
|
9
|
+
# Parse CLI options for the ripple subcommand.
|
|
10
|
+
#
|
|
11
|
+
# @return [Hash] parsed options keyed by symbols
|
|
9
12
|
def self.parse_cli_options
|
|
10
13
|
options = {
|
|
11
14
|
speed: :medium,
|
|
@@ -7,7 +7,22 @@ require_relative 'twirl_runner'
|
|
|
7
7
|
|
|
8
8
|
# Twirl CLI (extracted from bin/prg)
|
|
9
9
|
module TwirlCLI
|
|
10
|
+
# CLI dispatcher for the Twirl spinner indicator. Parses options and
|
|
11
|
+
# dispatches to runtime helpers in TwirlRunner or controls daemons via
|
|
12
|
+
# RubyProgress::Daemon.
|
|
13
|
+
#
|
|
14
|
+
# Public methods:
|
|
15
|
+
# - .run
|
|
16
|
+
# - .resolve_pid_file
|
|
17
|
+
# - .parse_cli_options
|
|
18
|
+
#
|
|
19
|
+
# @return [void]
|
|
10
20
|
def self.run
|
|
21
|
+
trap('INT') do
|
|
22
|
+
RubyProgress::Utils.show_cursor
|
|
23
|
+
exit
|
|
24
|
+
end
|
|
25
|
+
|
|
11
26
|
options = TwirlCLI::Options.parse_cli_options
|
|
12
27
|
|
|
13
28
|
if options[:status]
|
|
@@ -38,6 +53,11 @@ module TwirlCLI
|
|
|
38
53
|
end
|
|
39
54
|
|
|
40
55
|
# runtime methods moved to TwirlRunner
|
|
56
|
+
# Resolve the pid file path used for named/unnamed daemons.
|
|
57
|
+
#
|
|
58
|
+
# @param options [Hash]
|
|
59
|
+
# @param name_key [Symbol]
|
|
60
|
+
# @return [String]
|
|
41
61
|
def self.resolve_pid_file(options, name_key)
|
|
42
62
|
return options[:pid_file] if options[:pid_file]
|
|
43
63
|
|
|
@@ -9,6 +9,9 @@ module TwirlCLI
|
|
|
9
9
|
# Keeps the CLI option definitions extracted from the main dispatcher
|
|
10
10
|
# so the `TwirlCLI` module stays small and focused on dispatching.
|
|
11
11
|
module Options
|
|
12
|
+
# Parse CLI options for the twirl subcommand.
|
|
13
|
+
#
|
|
14
|
+
# @return [Hash] parsed options keyed by symbols
|
|
12
15
|
def self.parse_cli_options
|
|
13
16
|
options = {
|
|
14
17
|
output_position: :above,
|
|
@@ -12,6 +12,12 @@ require_relative '../output_capture'
|
|
|
12
12
|
# indefinitely, or launching in daemon mode) and were extracted to
|
|
13
13
|
# reduce module size and improve testability.
|
|
14
14
|
module TwirlRunner
|
|
15
|
+
# Runtime helper: run the provided command while showing a twirl spinner.
|
|
16
|
+
# Captures output via RubyProgress::OutputCapture when appropriate and
|
|
17
|
+
# prints final completion messages according to options.
|
|
18
|
+
#
|
|
19
|
+
# @param options [Hash] CLI options parsed from TwirlCLI::Options
|
|
20
|
+
# @return [void] exits with appropriate status code (0 success, 1 failure)
|
|
15
21
|
def self.run_with_command(options)
|
|
16
22
|
message = options[:message]
|
|
17
23
|
captured_output = nil
|
|
@@ -46,6 +52,11 @@ module TwirlRunner
|
|
|
46
52
|
|
|
47
53
|
spinner_thread.kill
|
|
48
54
|
RubyProgress::Utils.clear_line
|
|
55
|
+
rescue Interrupt
|
|
56
|
+
spinner_thread&.kill
|
|
57
|
+
RubyProgress::Utils.clear_line
|
|
58
|
+
RubyProgress::Utils.show_cursor
|
|
59
|
+
exit 130
|
|
49
60
|
ensure
|
|
50
61
|
RubyProgress::Utils.show_cursor
|
|
51
62
|
end
|
|
@@ -67,6 +78,10 @@ module TwirlRunner
|
|
|
67
78
|
exit success ? 0 : 1
|
|
68
79
|
end
|
|
69
80
|
|
|
81
|
+
# Run the spinner indefinitely until interrupted (SIGINT).
|
|
82
|
+
#
|
|
83
|
+
# @param options [Hash] CLI options used to configure the spinner
|
|
84
|
+
# @return [void] exits 130 on interrupt
|
|
70
85
|
def self.run_indefinitely(options)
|
|
71
86
|
message = options[:message]
|
|
72
87
|
spinner = TwirlSpinner.new(message, options)
|
|
@@ -74,6 +89,10 @@ module TwirlRunner
|
|
|
74
89
|
begin
|
|
75
90
|
RubyProgress::Utils.hide_cursor
|
|
76
91
|
loop { spinner.animate }
|
|
92
|
+
rescue Interrupt
|
|
93
|
+
RubyProgress::Utils.clear_line
|
|
94
|
+
RubyProgress::Utils.show_cursor
|
|
95
|
+
exit 130
|
|
77
96
|
ensure
|
|
78
97
|
RubyProgress::Utils.show_cursor
|
|
79
98
|
if options[:success] || options[:checkmark]
|
|
@@ -87,6 +106,11 @@ module TwirlRunner
|
|
|
87
106
|
end
|
|
88
107
|
end
|
|
89
108
|
|
|
109
|
+
# Run the spinner in daemon mode. Writes a pid file and listens for
|
|
110
|
+
# control messages via the daemon control message file.
|
|
111
|
+
#
|
|
112
|
+
# @param options [Hash]
|
|
113
|
+
# @return [void]
|
|
90
114
|
def self.run_daemon_mode(options)
|
|
91
115
|
pid_file = resolve_pid_file(options, :daemon_name)
|
|
92
116
|
FileUtils.mkdir_p(File.dirname(pid_file))
|
|
@@ -141,6 +165,11 @@ module TwirlRunner
|
|
|
141
165
|
end
|
|
142
166
|
end
|
|
143
167
|
|
|
168
|
+
# Resolve pid file helper used by run_daemon_mode and CLI.
|
|
169
|
+
#
|
|
170
|
+
# @param options [Hash]
|
|
171
|
+
# @param name_key [Symbol]
|
|
172
|
+
# @return [String]
|
|
144
173
|
def self.resolve_pid_file(options, name_key)
|
|
145
174
|
return options[:pid_file] if options[:pid_file]
|
|
146
175
|
|
|
@@ -6,6 +6,25 @@ require_relative 'worm_options'
|
|
|
6
6
|
|
|
7
7
|
# Enhanced Worm CLI (extracted from bin/prg)
|
|
8
8
|
module WormCLI
|
|
9
|
+
# CLI dispatcher for the Worm indicator.
|
|
10
|
+
#
|
|
11
|
+
# Responsibilities:
|
|
12
|
+
# - parse CLI options (delegates to WormCLI::Options)
|
|
13
|
+
# - handle daemonization, status, and stop commands via RubyProgress::Daemon
|
|
14
|
+
# - launch the appropriate runtime mode (command-run, indefinite, daemon)
|
|
15
|
+
#
|
|
16
|
+
# Public methods:
|
|
17
|
+
# - .run
|
|
18
|
+
# - .resolve_pid_file
|
|
19
|
+
# - .run_daemon_mode
|
|
20
|
+
|
|
21
|
+
# Determine the pid file path from options. If options specify a custom
|
|
22
|
+
# :pid_file, return it. If a named daemon key is present, use
|
|
23
|
+
# /tmp/ruby-progress/<name>.pid. Otherwise fall back to the default.
|
|
24
|
+
#
|
|
25
|
+
# @param options [Hash] parsed CLI options
|
|
26
|
+
# @param name_key [Symbol] key used for named daemons (default :daemon_name)
|
|
27
|
+
# @return [String] path to the pid file
|
|
9
28
|
def self.resolve_pid_file(options, name_key = :daemon_name)
|
|
10
29
|
return options[:pid_file] if options[:pid_file]
|
|
11
30
|
|
|
@@ -14,7 +33,16 @@ module WormCLI
|
|
|
14
33
|
RubyProgress::Daemon.default_pid_file
|
|
15
34
|
end
|
|
16
35
|
|
|
36
|
+
# Entrypoint for the Worm CLI. Parses options and dispatches to status,
|
|
37
|
+
# stop, daemon, or runtime modes. Ensures the cursor is restored on Ctrl+C.
|
|
38
|
+
#
|
|
39
|
+
# @return [void] exits with appropriate exit codes for status/stop modes.
|
|
17
40
|
def self.run
|
|
41
|
+
trap('INT') do
|
|
42
|
+
RubyProgress::Utils.show_cursor
|
|
43
|
+
exit
|
|
44
|
+
end
|
|
45
|
+
|
|
18
46
|
options = WormCLI::Options.parse_cli_options
|
|
19
47
|
|
|
20
48
|
if options[:status]
|
|
@@ -48,6 +76,11 @@ module WormCLI
|
|
|
48
76
|
end
|
|
49
77
|
end
|
|
50
78
|
|
|
79
|
+
# Launch the worm indicator in daemon mode writing a pid file and
|
|
80
|
+
# monitoring for control messages. Ensures pid file is removed on exit.
|
|
81
|
+
#
|
|
82
|
+
# @param options [Hash] parsed CLI options used to configure the Worm instance
|
|
83
|
+
# @return [void]
|
|
51
84
|
def self.run_daemon_mode(options)
|
|
52
85
|
pid_file = resolve_pid_file(options, :daemon_name)
|
|
53
86
|
FileUtils.mkdir_p(File.dirname(pid_file))
|
|
@@ -8,6 +8,9 @@ module WormCLI
|
|
|
8
8
|
# Keeps the CLI option definitions for `prg worm` extracted from
|
|
9
9
|
# the main dispatcher to keep the CLI module small and focused.
|
|
10
10
|
module Options
|
|
11
|
+
# Parse CLI options for the worm subcommand.
|
|
12
|
+
#
|
|
13
|
+
# @return [Hash] parsed options keyed by symbols
|
|
11
14
|
def self.parse_cli_options
|
|
12
15
|
options = {
|
|
13
16
|
output_position: :above,
|