ruby-progress 1.3.1 → 1.3.2
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/.rubocop_todo.yml +26 -45
- data/CHANGELOG.md +6 -1
- data/Gemfile.lock +1 -1
- data/README.md +48 -0
- data/Rakefile +0 -3
- data/bin/prg +15 -0
- data/demo_screencast.rb +180 -36
- data/lib/ruby-progress/cli/fill_options.rb +51 -1
- data/lib/ruby-progress/cli/job_cli.rb +70 -10
- data/lib/ruby-progress/cli/ripple_cli.rb +28 -10
- data/lib/ruby-progress/cli/ripple_options.rb +12 -0
- data/lib/ruby-progress/cli/twirl_options.rb +18 -0
- data/lib/ruby-progress/cli/twirl_runner.rb +8 -4
- data/lib/ruby-progress/cli/twirl_spinner.rb +18 -2
- data/lib/ruby-progress/cli/worm_cli.rb +12 -4
- data/lib/ruby-progress/cli/worm_options.rb +12 -0
- data/lib/ruby-progress/cli/worm_runner.rb +3 -5
- data/lib/ruby-progress/fill.rb +5 -3
- data/lib/ruby-progress/fill_cli.rb +172 -51
- data/lib/ruby-progress/ripple.rb +3 -2
- data/lib/ruby-progress/utils.rb +47 -26
- data/lib/ruby-progress/version.rb +5 -5
- data/lib/ruby-progress/worm.rb +8 -7
- data/screencast +26 -0
- metadata +2 -2
- data/ruby-progress.gemspec +0 -40
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
require 'optparse'
|
|
4
4
|
require 'fileutils'
|
|
5
|
+
require 'json'
|
|
6
|
+
require 'securerandom'
|
|
5
7
|
require_relative 'cli/fill_options'
|
|
6
8
|
require_relative 'output_capture'
|
|
7
9
|
|
|
8
10
|
module RubyProgress
|
|
9
11
|
# CLI module for Fill command
|
|
12
|
+
# rubocop:disable Metrics/ClassLength
|
|
10
13
|
module FillCLI
|
|
11
14
|
class << self
|
|
12
15
|
def run
|
|
@@ -35,11 +38,14 @@ module RubyProgress
|
|
|
35
38
|
|
|
36
39
|
# Handle daemon control first
|
|
37
40
|
if options[:status] || options[:stop]
|
|
38
|
-
pid_file = options
|
|
41
|
+
pid_file = resolve_pid_file(options, :status_name)
|
|
39
42
|
if options[:status]
|
|
40
43
|
Daemon.show_status(pid_file)
|
|
41
44
|
else
|
|
42
|
-
Daemon.stop_daemon_by_pid_file(pid_file
|
|
45
|
+
Daemon.stop_daemon_by_pid_file(pid_file,
|
|
46
|
+
message: options[:stop_success],
|
|
47
|
+
checkmark: options[:stop_checkmark],
|
|
48
|
+
error: !options[:stop_error].nil?)
|
|
43
49
|
end
|
|
44
50
|
exit
|
|
45
51
|
end
|
|
@@ -48,6 +54,17 @@ module RubyProgress
|
|
|
48
54
|
parsed_style = parse_fill_style(options[:style])
|
|
49
55
|
|
|
50
56
|
if options[:daemon]
|
|
57
|
+
# Resolve pid file and honor daemon-as/name
|
|
58
|
+
pid_file = resolve_pid_file(options, :daemon_name)
|
|
59
|
+
options[:pid_file] = pid_file
|
|
60
|
+
|
|
61
|
+
# Detach or background without detaching based on --no-detach
|
|
62
|
+
if options[:no_detach]
|
|
63
|
+
PrgCLI.backgroundize
|
|
64
|
+
else
|
|
65
|
+
PrgCLI.daemonize
|
|
66
|
+
end
|
|
67
|
+
|
|
51
68
|
run_daemon_mode(options, parsed_style)
|
|
52
69
|
elsif options[:current]
|
|
53
70
|
show_current_percentage(options, parsed_style)
|
|
@@ -62,6 +79,14 @@ module RubyProgress
|
|
|
62
79
|
|
|
63
80
|
private
|
|
64
81
|
|
|
82
|
+
def resolve_pid_file(options, name_key = :daemon_name)
|
|
83
|
+
return options[:pid_file] if options[:pid_file]
|
|
84
|
+
|
|
85
|
+
return "/tmp/ruby-progress/#{options[name_key]}.pid" if options[name_key]
|
|
86
|
+
|
|
87
|
+
'/tmp/ruby-progress/fill.pid'
|
|
88
|
+
end
|
|
89
|
+
|
|
65
90
|
def parse_fill_style(style_option)
|
|
66
91
|
case style_option
|
|
67
92
|
when String
|
|
@@ -76,9 +101,6 @@ module RubyProgress
|
|
|
76
101
|
end
|
|
77
102
|
|
|
78
103
|
def run_daemon_mode(options, parsed_style)
|
|
79
|
-
# For daemon mode, detach the process
|
|
80
|
-
PrgCLI.daemonize
|
|
81
|
-
|
|
82
104
|
pid_file = options[:pid_file] || '/tmp/ruby-progress/fill.pid'
|
|
83
105
|
FileUtils.mkdir_p(File.dirname(pid_file))
|
|
84
106
|
File.write(pid_file, Process.pid.to_s)
|
|
@@ -98,6 +120,71 @@ module RubyProgress
|
|
|
98
120
|
begin
|
|
99
121
|
fill_bar.render # Show initial empty bar
|
|
100
122
|
|
|
123
|
+
# Start job processor thread for fill (so daemon can accept jobs)
|
|
124
|
+
job_dir = RubyProgress::Daemon.job_dir_for_pid(pid_file)
|
|
125
|
+
Thread.new do
|
|
126
|
+
RubyProgress::Daemon.process_jobs(job_dir) do |job|
|
|
127
|
+
jid = job['id'] || SecureRandom.uuid
|
|
128
|
+
log_path = begin
|
|
129
|
+
File.join(File.dirname(job_dir), "#{jid}.log")
|
|
130
|
+
rescue StandardError
|
|
131
|
+
nil
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
if job['command']
|
|
135
|
+
oc = RubyProgress::OutputCapture.new(
|
|
136
|
+
command: job['command'],
|
|
137
|
+
lines: options[:output_lines] || 3,
|
|
138
|
+
position: options[:output_position] || :above,
|
|
139
|
+
log_path: log_path
|
|
140
|
+
)
|
|
141
|
+
oc.start
|
|
142
|
+
|
|
143
|
+
fill_bar.instance_variable_set(:@output_capture, oc)
|
|
144
|
+
oc.wait
|
|
145
|
+
captured = oc.lines.join("\n")
|
|
146
|
+
exit_status = oc.exit_status
|
|
147
|
+
fill_bar.instance_variable_set(:@output_capture, nil)
|
|
148
|
+
|
|
149
|
+
success = exit_status.to_i.zero?
|
|
150
|
+
if job['message']
|
|
151
|
+
RubyProgress::Utils.display_completion(
|
|
152
|
+
job['message'],
|
|
153
|
+
success: success,
|
|
154
|
+
show_checkmark: job['checkmark'] || false,
|
|
155
|
+
output_stream: :stdout,
|
|
156
|
+
icons: { success: options[:success_icon], error: options[:error_icon] }
|
|
157
|
+
)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
{ 'exit_status' => exit_status, 'output' => captured, 'log_path' => log_path }
|
|
161
|
+
|
|
162
|
+
elsif job['action']
|
|
163
|
+
case job['action']
|
|
164
|
+
when 'advance'
|
|
165
|
+
fill_bar.advance
|
|
166
|
+
{ 'status' => 'done', 'action' => 'advance' }
|
|
167
|
+
when 'percent'
|
|
168
|
+
val = job['value'] || job['percent'] || 0
|
|
169
|
+
fill_bar.percent = val.to_f
|
|
170
|
+
{ 'status' => 'done', 'action' => 'percent', 'value' => val }
|
|
171
|
+
when 'complete'
|
|
172
|
+
fill_bar.complete
|
|
173
|
+
{ 'status' => 'done', 'action' => 'complete' }
|
|
174
|
+
when 'cancel'
|
|
175
|
+
fill_bar.cancel
|
|
176
|
+
{ 'status' => 'done', 'action' => 'cancel' }
|
|
177
|
+
else
|
|
178
|
+
{ 'status' => 'error', 'error' => 'unknown action' }
|
|
179
|
+
end
|
|
180
|
+
else
|
|
181
|
+
{ 'status' => 'error', 'error' => 'no command or action provided' }
|
|
182
|
+
end
|
|
183
|
+
rescue StandardError
|
|
184
|
+
nil
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
101
188
|
# Set up signal handlers for daemon control
|
|
102
189
|
stop_requested = false
|
|
103
190
|
Signal.trap('INT') { stop_requested = true }
|
|
@@ -107,51 +194,82 @@ module RubyProgress
|
|
|
107
194
|
# Keep daemon alive until stop requested
|
|
108
195
|
sleep(0.1) until stop_requested
|
|
109
196
|
ensure
|
|
197
|
+
# If a control message file exists, print its contents like other CLIs
|
|
198
|
+
cmf = RubyProgress::Daemon.control_message_file(pid_file)
|
|
199
|
+
if File.exist?(cmf)
|
|
200
|
+
begin
|
|
201
|
+
data = JSON.parse(File.read(cmf))
|
|
202
|
+
message = data['message']
|
|
203
|
+
check = if data.key?('checkmark')
|
|
204
|
+
data['checkmark'] ? true : false
|
|
205
|
+
else
|
|
206
|
+
false
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
success_val = if data.key?('success')
|
|
210
|
+
data['success'] ? true : false
|
|
211
|
+
else
|
|
212
|
+
true
|
|
213
|
+
end
|
|
214
|
+
if message
|
|
215
|
+
RubyProgress::Utils.display_completion(
|
|
216
|
+
message,
|
|
217
|
+
success: success_val,
|
|
218
|
+
show_checkmark: check,
|
|
219
|
+
output_stream: :stdout,
|
|
220
|
+
icons: { success: options[:success_icon], error: options[:error_icon] }
|
|
221
|
+
)
|
|
222
|
+
end
|
|
223
|
+
rescue StandardError
|
|
224
|
+
# ignore
|
|
225
|
+
ensure
|
|
226
|
+
begin
|
|
227
|
+
File.delete(cmf)
|
|
228
|
+
rescue StandardError
|
|
229
|
+
nil
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
110
234
|
Fill.show_cursor
|
|
111
235
|
FileUtils.rm_f(pid_file)
|
|
112
236
|
end
|
|
113
237
|
end
|
|
114
238
|
|
|
115
|
-
def show_current_percentage(options, _parsed_style)
|
|
116
|
-
# Just output the percentage for scripting (default to 50% for demonstration)
|
|
117
|
-
percentage = options[:percent] || 50
|
|
118
|
-
puts percentage.to_f
|
|
119
|
-
end
|
|
120
|
-
|
|
121
239
|
def show_progress_report(options, parsed_style)
|
|
122
|
-
#
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
#
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
# Display the current progress bar and detailed status
|
|
138
|
-
fill_bar.render
|
|
139
|
-
puts "\nProgress Report:"
|
|
140
|
-
puts " Progress: #{report[:progress][0]}/#{report[:progress][1]}"
|
|
141
|
-
puts " Percent: #{report[:percent]}%"
|
|
142
|
-
puts " Completed: #{report[:completed] ? 'Yes' : 'No'}"
|
|
143
|
-
puts " Style: #{report[:style]}"
|
|
240
|
+
# Produce a simple scripting-friendly report to stdout
|
|
241
|
+
length = options[:length] || 20
|
|
242
|
+
percent = (options[:percent] || 50.0).to_f
|
|
243
|
+
style = parsed_style
|
|
244
|
+
|
|
245
|
+
fill = Fill.new(style: style, length: length)
|
|
246
|
+
fill.percent = percent
|
|
247
|
+
|
|
248
|
+
report = fill.report
|
|
249
|
+
puts 'Progress Report:'
|
|
250
|
+
puts "Progress: #{report[:progress][0]}/#{report[:progress][1]}"
|
|
251
|
+
puts "Percent: #{report[:percent]}%"
|
|
252
|
+
puts "Completed: #{report[:completed] ? 'Yes' : 'No'}"
|
|
253
|
+
puts "Style: #{report[:style].inspect}"
|
|
254
|
+
exit(0)
|
|
144
255
|
end
|
|
145
256
|
|
|
146
257
|
def handle_progress_commands(_options, _parsed_style)
|
|
147
|
-
# For progress commands
|
|
148
|
-
#
|
|
149
|
-
# we'd need IPC to communicate with the daemon
|
|
258
|
+
# For now the progress commands are only supported in daemon mode.
|
|
259
|
+
# Return a clear error to the caller (specs assert this message exists).
|
|
150
260
|
warn 'Progress commands require daemon mode implementation'
|
|
151
|
-
|
|
152
|
-
|
|
261
|
+
exit(1)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def show_current_percentage(options, _parsed_style)
|
|
265
|
+
# For scripting and tests: print the current percentage to stdout and exit.
|
|
266
|
+
# If no explicit percent was provided, default to 50.0
|
|
267
|
+
percent = (options[:percent] || 50.0).to_f
|
|
268
|
+
$stdout.print("#{percent}\n")
|
|
269
|
+
exit(0)
|
|
153
270
|
end
|
|
154
271
|
|
|
272
|
+
# Foreground / auto-advance / command mode when not daemonizing
|
|
155
273
|
def run_auto_advance_mode(options, parsed_style)
|
|
156
274
|
fill_options = {
|
|
157
275
|
style: parsed_style,
|
|
@@ -161,20 +279,10 @@ module RubyProgress
|
|
|
161
279
|
error: options[:error_message]
|
|
162
280
|
}
|
|
163
281
|
|
|
164
|
-
# If a command is provided, capture its output and pass an OutputCapture
|
|
165
|
-
if options[:command]
|
|
166
|
-
oc = RubyProgress::OutputCapture.new(
|
|
167
|
-
command: options[:command],
|
|
168
|
-
lines: options[:output_lines] || 3,
|
|
169
|
-
position: options[:output_position] || :above
|
|
170
|
-
)
|
|
171
|
-
oc.start
|
|
172
|
-
fill_options[:output_capture] = oc
|
|
173
|
-
end
|
|
174
|
-
|
|
175
282
|
fill_bar = Fill.new(fill_options)
|
|
176
283
|
Fill.hide_cursor
|
|
177
284
|
|
|
285
|
+
oc = nil
|
|
178
286
|
begin
|
|
179
287
|
if options[:percent]
|
|
180
288
|
# Set to specific percentage
|
|
@@ -185,7 +293,19 @@ module RubyProgress
|
|
|
185
293
|
sleep(0.1)
|
|
186
294
|
end
|
|
187
295
|
elsif options[:command]
|
|
188
|
-
#
|
|
296
|
+
# Run the command with OutputCapture
|
|
297
|
+
oc = RubyProgress::OutputCapture.new(
|
|
298
|
+
command: options[:command],
|
|
299
|
+
lines: options[:output_lines] || 3,
|
|
300
|
+
position: options[:output_position] || :above,
|
|
301
|
+
log_path: nil
|
|
302
|
+
)
|
|
303
|
+
oc.start
|
|
304
|
+
|
|
305
|
+
# Attach capture to the live fill instance so it can render output
|
|
306
|
+
fill_bar.instance_variable_set(:@output_capture, oc)
|
|
307
|
+
|
|
308
|
+
# While the command runs, keep redrawing the bar
|
|
189
309
|
sleep_time = case options[:speed]
|
|
190
310
|
when :fast then 0.1
|
|
191
311
|
when :medium, nil then 0.2
|
|
@@ -195,11 +315,11 @@ module RubyProgress
|
|
|
195
315
|
end
|
|
196
316
|
|
|
197
317
|
fill_bar.render
|
|
198
|
-
# Loop until the OutputCapture reader has finished
|
|
199
318
|
while oc.alive?
|
|
200
319
|
sleep(sleep_time)
|
|
201
320
|
fill_bar.render
|
|
202
321
|
end
|
|
322
|
+
fill_bar.instance_variable_set(:@output_capture, nil)
|
|
203
323
|
else
|
|
204
324
|
# Auto-advance mode
|
|
205
325
|
sleep_time = case options[:speed]
|
|
@@ -216,6 +336,7 @@ module RubyProgress
|
|
|
216
336
|
fill_bar.advance
|
|
217
337
|
end
|
|
218
338
|
end
|
|
339
|
+
|
|
219
340
|
fill_bar.complete
|
|
220
341
|
rescue Interrupt
|
|
221
342
|
fill_bar.cancel
|
data/lib/ruby-progress/ripple.rb
CHANGED
|
@@ -154,7 +154,7 @@ module RubyProgress
|
|
|
154
154
|
RubyProgress::Utils.show_cursor
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
-
def self.complete(string, message, checkmark, success)
|
|
157
|
+
def self.complete(string, message, checkmark, success, icons: {})
|
|
158
158
|
display_message = message || (checkmark ? string : nil)
|
|
159
159
|
return unless display_message
|
|
160
160
|
|
|
@@ -162,7 +162,8 @@ module RubyProgress
|
|
|
162
162
|
display_message,
|
|
163
163
|
success: success,
|
|
164
164
|
show_checkmark: checkmark,
|
|
165
|
-
output_stream: :warn
|
|
165
|
+
output_stream: :warn,
|
|
166
|
+
icons: icons
|
|
166
167
|
)
|
|
167
168
|
end
|
|
168
169
|
|
data/lib/ruby-progress/utils.rb
CHANGED
|
@@ -13,12 +13,17 @@ module RubyProgress
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def self.clear_line(output_stream = :stderr)
|
|
16
|
-
case output_stream
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
io = case output_stream
|
|
17
|
+
when :stdout
|
|
18
|
+
$stdout
|
|
19
|
+
when :stderr
|
|
20
|
+
$stderr
|
|
21
|
+
else
|
|
22
|
+
# allow passing an IO-like object (e.g. StringIO) directly
|
|
23
|
+
output_stream.respond_to?(:print) ? output_stream : $stderr
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
io.print "\r\e[K"
|
|
22
27
|
end
|
|
23
28
|
|
|
24
29
|
# Enhanced line clearing for daemon mode that handles output interruption
|
|
@@ -33,39 +38,55 @@ module RubyProgress
|
|
|
33
38
|
# @param success [Boolean] Whether this represents success or failure
|
|
34
39
|
# @param show_checkmark [Boolean] Whether to show checkmark/X symbols
|
|
35
40
|
# @param output_stream [Symbol] Where to output (:stdout, :stderr, :warn)
|
|
36
|
-
def self.display_completion(message, success: true, show_checkmark: false, output_stream: :warn)
|
|
41
|
+
def self.display_completion(message, success: true, show_checkmark: false, output_stream: :warn, icons: {})
|
|
37
42
|
return unless message
|
|
38
43
|
|
|
39
|
-
mark =
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
mark = if show_checkmark
|
|
45
|
+
icon = success ? (icons[:success] || '✅') : (icons[:error] || '🛑')
|
|
46
|
+
"#{icon} "
|
|
47
|
+
else
|
|
48
|
+
''
|
|
49
|
+
end
|
|
43
50
|
|
|
44
51
|
formatted_message = "#{mark}#{message}"
|
|
45
52
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
# Resolve destination IO: support symbols (:stdout/:stderr/:warn) or an IO-like object
|
|
54
|
+
dest_io = case output_stream
|
|
55
|
+
when :stdout
|
|
56
|
+
$stdout
|
|
57
|
+
when :stderr
|
|
58
|
+
$stderr
|
|
59
|
+
when :warn
|
|
60
|
+
$stderr
|
|
61
|
+
else
|
|
62
|
+
output_stream.respond_to?(:print) ? output_stream : $stderr
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Only treat explicit :stdout and :stderr as non-clearing requests.
|
|
66
|
+
# For :warn and any other/custom stream, clear the current line first.
|
|
67
|
+
unless %i[stdout stderr].include?(output_stream)
|
|
68
|
+
# Always include a leading carriage return when clearing to match
|
|
69
|
+
# terminal behavior expected by the test-suite.
|
|
70
|
+
dest_io.print "\r\e[2K"
|
|
71
|
+
dest_io.flush if dest_io.respond_to?(:flush)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Emit the message to the resolved destination IO. Use warn/puts when targeting
|
|
75
|
+
# the standard streams to preserve familiar behavior (warn writes to $stderr).
|
|
76
|
+
if dest_io == $stdout
|
|
77
|
+
$stdout.puts formatted_message
|
|
78
|
+
elsif dest_io == $stderr
|
|
55
79
|
warn formatted_message
|
|
56
80
|
else
|
|
57
|
-
|
|
58
|
-
$stderr.print "\r\e[2K"
|
|
59
|
-
$stderr.flush
|
|
60
|
-
warn formatted_message
|
|
81
|
+
dest_io.puts formatted_message
|
|
61
82
|
end
|
|
62
83
|
end
|
|
63
84
|
|
|
64
85
|
# Clear current line and display completion message
|
|
65
86
|
# Convenience method that combines line clearing with message display
|
|
66
|
-
def self.complete_with_clear(message, success: true, show_checkmark: false, output_stream: :warn)
|
|
87
|
+
def self.complete_with_clear(message, success: true, show_checkmark: false, output_stream: :warn, icons: {})
|
|
67
88
|
clear_line(output_stream) if output_stream != :warn # warn already includes clear in display_completion
|
|
68
|
-
display_completion(message, success: success, show_checkmark: show_checkmark, output_stream: output_stream)
|
|
89
|
+
display_completion(message, success: success, show_checkmark: show_checkmark, output_stream: output_stream, icons: icons)
|
|
69
90
|
end
|
|
70
91
|
|
|
71
92
|
# Parse start/end characters for animation wrapping
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
module RubyProgress
|
|
4
4
|
# Main gem version
|
|
5
|
-
VERSION = '1.3.
|
|
5
|
+
VERSION = '1.3.2'
|
|
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.4'
|
|
9
|
+
TWIRL_VERSION = '1.1.4'
|
|
10
|
+
RIPPLE_VERSION = '1.1.4'
|
|
11
|
+
FILL_VERSION = '1.0.4'
|
|
12
12
|
end
|
data/lib/ruby-progress/worm.rb
CHANGED
|
@@ -76,13 +76,14 @@ module RubyProgress
|
|
|
76
76
|
def display_completion_message(message, success)
|
|
77
77
|
return unless message
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
# Delegate to Utils.display_completion so carriage-return and clearing
|
|
80
|
+
# behavior is consistent across all indicators and respects TTY state.
|
|
81
|
+
RubyProgress::Utils.display_completion(
|
|
82
|
+
message,
|
|
83
|
+
success: success,
|
|
84
|
+
show_checkmark: @show_checkmark,
|
|
85
|
+
output_stream: :warn
|
|
86
|
+
)
|
|
86
87
|
end
|
|
87
88
|
|
|
88
89
|
def parse_speed(speed_input)
|
data/screencast
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{"version":2,"width":146,"height":24,"timestamp":1760358387,"duration":4.124379,"env":{"SHELL":"/opt/homebrew/bin/fish","TERM":"xterm-256color"}}
|
|
2
|
+
[0.002162,"o","$ bin/prg worm --command \"sleep 4\"\r\n"]
|
|
3
|
+
[0.052412,"o","\u001b[?25l"]
|
|
4
|
+
[0.054304,"o","\r\u001b[2K⬤··"]
|
|
5
|
+
[0.260053,"o","\r\u001b[2K●⬤·"]
|
|
6
|
+
[0.462807,"o","\r\u001b[2K··⬤"]
|
|
7
|
+
[0.667558,"o","\r\u001b[2K·⬤●"]
|
|
8
|
+
[0.86773,"o","\r\u001b[2K⬤··"]
|
|
9
|
+
[1.06914,"o","\r\u001b[2K●⬤·"]
|
|
10
|
+
[1.273207,"o","\r\u001b[2K··⬤"]
|
|
11
|
+
[1.477782,"o","\r\u001b[2K·⬤●"]
|
|
12
|
+
[1.682846,"o","\r\u001b[2K⬤··"]
|
|
13
|
+
[1.885136,"o","\r\u001b[2K●⬤·"]
|
|
14
|
+
[2.087746,"o","\r\u001b[2K··⬤"]
|
|
15
|
+
[2.290181,"o","\r\u001b[2K·⬤●"]
|
|
16
|
+
[2.494656,"o","\r\u001b[2K⬤··"]
|
|
17
|
+
[2.69979,"o","\r\u001b[2K●⬤·"]
|
|
18
|
+
[2.900129,"o","\r\u001b[2K··⬤"]
|
|
19
|
+
[3.102774,"o","\r\u001b[2K·⬤●"]
|
|
20
|
+
[3.303982,"o","\r\u001b[2K⬤··"]
|
|
21
|
+
[3.507771,"o","\r\u001b[2K●⬤·"]
|
|
22
|
+
[3.711678,"o","\r\u001b[2K··⬤"]
|
|
23
|
+
[3.915598,"o","\r\u001b[2K·⬤●"]
|
|
24
|
+
[4.120702,"o","\r\u001b[2K"]
|
|
25
|
+
[4.121323,"o","\u001b[?25h"]
|
|
26
|
+
[4.124379,"o",""]
|
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.
|
|
4
|
+
version: 1.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brett Terpstra
|
|
@@ -126,7 +126,7 @@ files:
|
|
|
126
126
|
- lib/ruby-progress/worm.rb
|
|
127
127
|
- quick_demo.rb
|
|
128
128
|
- readme_demo.rb
|
|
129
|
-
-
|
|
129
|
+
- screencast
|
|
130
130
|
- scripts/run_matrix_mise.fish
|
|
131
131
|
- test_daemon_interruption.rb
|
|
132
132
|
- test_daemon_orphan.rb
|
data/ruby-progress.gemspec
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'lib/ruby-progress/version'
|
|
4
|
-
|
|
5
|
-
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name = 'ruby-progress'
|
|
7
|
-
spec.version = RubyProgress::VERSION
|
|
8
|
-
spec.authors = ['Brett Terpstra']
|
|
9
|
-
spec.email = ['me@brettterpstra.com']
|
|
10
|
-
|
|
11
|
-
spec.summary = 'Animated terminal progress indicators'
|
|
12
|
-
spec.description = 'Animated progress indicators for Ruby: Ripple (text ripple effects), Worm (Unicode wave animations), and Twirl (spinner indicators)'
|
|
13
|
-
spec.homepage = 'https://github.com/ttscoff/ruby-progress'
|
|
14
|
-
spec.license = 'MIT'
|
|
15
|
-
spec.required_ruby_version = '>= 2.5.0'
|
|
16
|
-
|
|
17
|
-
spec.metadata['homepage_uri'] = spec.homepage
|
|
18
|
-
spec.metadata['source_code_uri'] = spec.homepage
|
|
19
|
-
spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
|
20
|
-
|
|
21
|
-
# Specify which files should be added to the gem when it is released.
|
|
22
|
-
spec.files = Dir.chdir(__dir__) do
|
|
23
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
|
24
|
-
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
spec.bindir = 'bin'
|
|
28
|
-
spec.executables = %w[prg ripple worm twirl fill]
|
|
29
|
-
spec.require_paths = ['lib']
|
|
30
|
-
|
|
31
|
-
# Runtime dependencies
|
|
32
|
-
# None required - uses only standard library
|
|
33
|
-
|
|
34
|
-
# Development dependencies
|
|
35
|
-
spec.add_development_dependency 'rake', '~> 13.0'
|
|
36
|
-
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
37
|
-
spec.add_development_dependency 'rubocop', '~> 1.21'
|
|
38
|
-
spec.add_development_dependency 'simplecov', '~> 0.21'
|
|
39
|
-
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
40
|
-
end
|