ruby-progress 1.3.1 → 1.3.4
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 +32 -45
- data/CHANGELOG.md +67 -96
- data/Gemfile +2 -0
- data/Gemfile.lock +7 -1
- data/README.md +48 -0
- data/Rakefile +0 -3
- data/bin/prg +15 -0
- data/demo_screencast.rb +223 -71
- data/lib/ruby-progress/cli/fill_options.rb +57 -1
- data/lib/ruby-progress/cli/job_cli.rb +70 -10
- data/lib/ruby-progress/cli/ripple_cli.rb +34 -11
- data/lib/ruby-progress/cli/ripple_options.rb +16 -0
- data/lib/ruby-progress/cli/twirl_options.rb +22 -0
- data/lib/ruby-progress/cli/twirl_runner.rb +13 -7
- data/lib/ruby-progress/cli/twirl_spinner.rb +18 -2
- data/lib/ruby-progress/cli/worm_cli.rb +14 -5
- data/lib/ruby-progress/cli/worm_options.rb +16 -0
- data/lib/ruby-progress/cli/worm_runner.rb +12 -9
- data/lib/ruby-progress/fill.rb +5 -3
- data/lib/ruby-progress/fill_cli.rb +174 -51
- data/lib/ruby-progress/output_capture.rb +169 -37
- 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 +16 -68
- data/screencast +2497 -0
- data/screencast.svg +1 -0
- metadata +31 -2
- data/ruby-progress.gemspec +0 -40
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.4'
|
|
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
|
@@ -65,6 +65,9 @@ module RubyProgress
|
|
|
65
65
|
@error_text = options[:error]
|
|
66
66
|
@show_checkmark = options[:checkmark] || false
|
|
67
67
|
@output_stdout = options[:stdout] || false
|
|
68
|
+
@output_lines = options[:output_lines]
|
|
69
|
+
@output_position = options[:output_position]
|
|
70
|
+
@output_live = options[:stdout_live] || false
|
|
68
71
|
@direction_mode = options[:direction] || :bidirectional
|
|
69
72
|
@start_chars, @end_chars = RubyProgress::Utils.parse_ends(options[:ends])
|
|
70
73
|
@running = false
|
|
@@ -76,13 +79,14 @@ module RubyProgress
|
|
|
76
79
|
def display_completion_message(message, success)
|
|
77
80
|
return unless message
|
|
78
81
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
# Delegate to Utils.display_completion so carriage-return and clearing
|
|
83
|
+
# behavior is consistent across all indicators and respects TTY state.
|
|
84
|
+
RubyProgress::Utils.display_completion(
|
|
85
|
+
message,
|
|
86
|
+
success: success,
|
|
87
|
+
show_checkmark: @show_checkmark,
|
|
88
|
+
output_stream: :warn
|
|
89
|
+
)
|
|
86
90
|
end
|
|
87
91
|
|
|
88
92
|
def parse_speed(speed_input)
|
|
@@ -196,67 +200,11 @@ module RubyProgress
|
|
|
196
200
|
}
|
|
197
201
|
end
|
|
198
202
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
message_part = @message && !@message.empty? ? "#{@message} " : ''
|
|
205
|
-
# Enhanced line clearing for better daemon mode behavior
|
|
206
|
-
$stderr.print "\r\e[2K#{@start_chars}#{message_part}#{generate_dots(position, direction)}#{@end_chars}"
|
|
207
|
-
$stderr.flush
|
|
208
|
-
|
|
209
|
-
sleep @speed
|
|
210
|
-
|
|
211
|
-
position += direction
|
|
212
|
-
if position >= @length - 1
|
|
213
|
-
if @direction_mode == :forward_only
|
|
214
|
-
position = 0
|
|
215
|
-
else
|
|
216
|
-
direction = -1
|
|
217
|
-
end
|
|
218
|
-
elsif position <= 0
|
|
219
|
-
direction = 1
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
# Enhanced animation loop for daemon mode with aggressive line clearing
|
|
225
|
-
def animation_loop_daemon_mode(stop_requested_proc: -> { false })
|
|
226
|
-
position = 0
|
|
227
|
-
direction = 1
|
|
228
|
-
frame_count = 0
|
|
229
|
-
|
|
230
|
-
while @running && !stop_requested_proc.call
|
|
231
|
-
message_part = @message && !@message.empty? ? "#{@message} " : ''
|
|
232
|
-
|
|
233
|
-
# Always clear current line
|
|
234
|
-
$stderr.print "\r\e[2K"
|
|
235
|
-
|
|
236
|
-
# Every few frames, use aggressive clearing to handle interruptions
|
|
237
|
-
if (frame_count % 10).zero?
|
|
238
|
-
$stderr.print "\e[1A\e[2K" # Move up and clear that line too (in case of interruption)
|
|
239
|
-
$stderr.print "\r" # Return to start
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
$stderr.print "#{message_part}#{generate_dots(position, direction)}"
|
|
243
|
-
$stderr.flush
|
|
244
|
-
|
|
245
|
-
sleep @speed
|
|
246
|
-
frame_count += 1
|
|
247
|
-
|
|
248
|
-
position += direction
|
|
249
|
-
if position >= @length - 1
|
|
250
|
-
if @direction_mode == :forward_only
|
|
251
|
-
position = 0
|
|
252
|
-
else
|
|
253
|
-
direction = -1
|
|
254
|
-
end
|
|
255
|
-
elsif position <= 0
|
|
256
|
-
direction = 1
|
|
257
|
-
end
|
|
258
|
-
end
|
|
259
|
-
end
|
|
203
|
+
# animation_loop and animation_loop_daemon_mode are implemented in
|
|
204
|
+
# the WormRunner module so they can share the redraw behavior that
|
|
205
|
+
# integrates with RubyProgress::OutputCapture. Do not redefine them
|
|
206
|
+
# here, otherwise the module implementations (which call
|
|
207
|
+
# @output_capture&.redraw) will be overridden.
|
|
260
208
|
|
|
261
209
|
def generate_dots(ripple_position, direction)
|
|
262
210
|
dots = Array.new(@length) { @style[:baseline] }
|