ruby-progress 1.0.1
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 +7 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +39 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +74 -0
- data/LICENSE +21 -0
- data/README.md +353 -0
- data/Rakefile +84 -0
- data/bin/prg +311 -0
- data/bin/ripple +147 -0
- data/bin/worm +80 -0
- data/demo_gem.rb +56 -0
- data/demo_worm_infinite.rb +21 -0
- data/examples/utils_demo.rb +52 -0
- data/lib/ruby-progress/ripple.rb +265 -0
- data/lib/ruby-progress/utils.rb +53 -0
- data/lib/ruby-progress/version.rb +5 -0
- data/lib/ruby-progress/worm.rb +253 -0
- data/lib/ruby-progress.rb +11 -0
- data/ruby-progress.gemspec +39 -0
- data/test_worm_flags.rb +24 -0
- metadata +123 -0
data/bin/prg
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../lib/ruby-progress'
|
|
5
|
+
require 'optparse'
|
|
6
|
+
|
|
7
|
+
# Unified progress indicator CLI
|
|
8
|
+
module PrgCLI
|
|
9
|
+
def self.run
|
|
10
|
+
if ARGV.empty?
|
|
11
|
+
show_help
|
|
12
|
+
exit 1
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
subcommand = ARGV.shift.downcase
|
|
16
|
+
|
|
17
|
+
case subcommand
|
|
18
|
+
when 'ripple'
|
|
19
|
+
RippleCLI.run
|
|
20
|
+
when 'worm'
|
|
21
|
+
WormCLI.run
|
|
22
|
+
when '-v', '--version'
|
|
23
|
+
puts "prg version #{RubyProgress::VERSION}"
|
|
24
|
+
puts " ripple - Text ripple animation with spinners and effects"
|
|
25
|
+
puts " worm - Unicode wave animation with customizable styles"
|
|
26
|
+
exit
|
|
27
|
+
when '-h', '--help', 'help'
|
|
28
|
+
show_help
|
|
29
|
+
exit
|
|
30
|
+
else
|
|
31
|
+
puts "Error: Unknown subcommand '#{subcommand}'"
|
|
32
|
+
puts "Run 'prg --help' for usage information."
|
|
33
|
+
exit 1
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.show_help
|
|
38
|
+
puts <<~HELP
|
|
39
|
+
prg - Unified Ruby Progress Indicators
|
|
40
|
+
|
|
41
|
+
USAGE:
|
|
42
|
+
prg <subcommand> [options]
|
|
43
|
+
|
|
44
|
+
SUBCOMMANDS:
|
|
45
|
+
ripple Text ripple animation with spinners and color effects
|
|
46
|
+
worm Unicode wave animation with customizable dot styles
|
|
47
|
+
|
|
48
|
+
GLOBAL OPTIONS:
|
|
49
|
+
-v, --version Show version information
|
|
50
|
+
-h, --help Show this help message
|
|
51
|
+
|
|
52
|
+
EXAMPLES:
|
|
53
|
+
prg ripple "Loading..." --rainbow --speed fast
|
|
54
|
+
prg worm --message "Processing" --style blocks --checkmark
|
|
55
|
+
prg ripple --command "sleep 3" --success "Done!" --checkmark
|
|
56
|
+
|
|
57
|
+
Run 'prg <subcommand> --help' for specific subcommand options.
|
|
58
|
+
HELP
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Enhanced Ripple CLI with unified flags
|
|
63
|
+
module RippleCLI
|
|
64
|
+
def self.run
|
|
65
|
+
trap('INT') do
|
|
66
|
+
RubyProgress::Utils.show_cursor
|
|
67
|
+
exit
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
options = {
|
|
71
|
+
speed: :medium,
|
|
72
|
+
direction: :bidirectional,
|
|
73
|
+
rainbow: false,
|
|
74
|
+
spinner: false,
|
|
75
|
+
spinner_position: :before,
|
|
76
|
+
caps: false,
|
|
77
|
+
inverse: false,
|
|
78
|
+
command: nil,
|
|
79
|
+
success_message: nil,
|
|
80
|
+
fail_message: nil,
|
|
81
|
+
complete_checkmark: false,
|
|
82
|
+
output: :error,
|
|
83
|
+
message: nil # For unified interface
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
OptionParser.new do |opts|
|
|
87
|
+
opts.banner = 'Usage: prg ripple [options] [STRING]'
|
|
88
|
+
opts.separator ''
|
|
89
|
+
opts.separator 'Animation Options:'
|
|
90
|
+
|
|
91
|
+
opts.on('-s', '--speed SPEED', 'Animation speed (fast/medium/slow or f/m/s)') do |s|
|
|
92
|
+
options[:speed] = case s.downcase
|
|
93
|
+
when /^f/ then :fast
|
|
94
|
+
when /^m/ then :medium
|
|
95
|
+
when /^s/ then :slow
|
|
96
|
+
else :medium
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
opts.on('-m', '--message MESSAGE', 'Message to display (alternative to positional argument)') do |msg|
|
|
101
|
+
options[:message] = msg
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
opts.on('-r', '--rainbow', 'Enable rainbow color mode') do
|
|
105
|
+
options[:rainbow] = true
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
opts.on('-d', '--direction DIRECTION', 'Animation direction (forward/bidirectional or f/b)') do |f|
|
|
109
|
+
options[:format] = f =~ /^f/i ? :forward_only : :bidirectional
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
opts.on('-i', '--inverse', 'Enable inverse highlighting mode') do
|
|
113
|
+
options[:inverse] = true
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
opts.separator ''
|
|
117
|
+
opts.separator 'Spinner Options:'
|
|
118
|
+
|
|
119
|
+
opts.on('--spinner TYPE', 'Use spinner animation instead of text ripple') do |type|
|
|
120
|
+
options[:spinner] = type.normalize_type
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
opts.on('--spinner-pos POSITION', 'Spinner position (before/after or b/a)') do |pos|
|
|
124
|
+
options[:spinner_position] = pos =~ /^a/i ? :after : :before
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
opts.on('--caps', 'Enable case transformation mode') do
|
|
128
|
+
options[:caps] = true
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
opts.on('--list-spinners', 'List all available spinner types') do
|
|
132
|
+
show_spinners
|
|
133
|
+
exit
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
opts.separator ''
|
|
137
|
+
opts.separator 'Command Execution:'
|
|
138
|
+
|
|
139
|
+
opts.on('-c', '--command COMMAND', 'Run command during animation (optional)') do |command|
|
|
140
|
+
options[:command] = command
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
opts.on('--success MESSAGE', 'Success message to display') do |msg|
|
|
144
|
+
options[:success_message] = msg
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
opts.on('--error MESSAGE', 'Error message to display') do |msg|
|
|
148
|
+
options[:fail_message] = msg
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
opts.on('--checkmark', 'Show checkmarks (✅ success, 🛑 failure)') do
|
|
152
|
+
options[:complete_checkmark] = true
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
opts.on('--stdout', 'Output captured command result to STDOUT') do
|
|
156
|
+
options[:output] = :stdout
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
opts.on('--quiet', 'Suppress all output') do
|
|
160
|
+
options[:output] = :quiet
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
opts.separator ''
|
|
164
|
+
opts.separator 'General:'
|
|
165
|
+
|
|
166
|
+
opts.on('-v', '--version', 'Show version') do
|
|
167
|
+
puts "Ripple version #{RubyProgress::VERSION}"
|
|
168
|
+
exit
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
opts.on('-h', '--help', 'Show this help') do
|
|
172
|
+
puts opts
|
|
173
|
+
exit
|
|
174
|
+
end
|
|
175
|
+
end.parse!
|
|
176
|
+
|
|
177
|
+
# Get text from positional argument or --message flag
|
|
178
|
+
text = options[:message] || ARGV.join(' ')
|
|
179
|
+
|
|
180
|
+
if text.empty?
|
|
181
|
+
puts 'Error: Please provide text to animate via argument or --message flag'
|
|
182
|
+
puts "Example: prg ripple 'Loading...' or prg ripple --message 'Loading...'"
|
|
183
|
+
exit 1
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
if options[:command]
|
|
187
|
+
run_with_command(text, options)
|
|
188
|
+
else
|
|
189
|
+
run_indefinitely(text, options)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def self.show_spinners
|
|
194
|
+
puts "Available spinners:"
|
|
195
|
+
RubyProgress::INDICATORS.each do |name, chars|
|
|
196
|
+
puts " #{name.to_s.ljust(15)} #{chars[0..2].join(' ')}"
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def self.run_with_command(text, options)
|
|
201
|
+
captured_output = nil
|
|
202
|
+
RubyProgress::Ripple.progress(text, options) do
|
|
203
|
+
captured_output = `#{options[:command]} 2>&1`
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
success = $?.success?
|
|
207
|
+
|
|
208
|
+
if options[:output] == :stdout
|
|
209
|
+
puts captured_output
|
|
210
|
+
end
|
|
211
|
+
if options[:success_message] || options[:complete_checkmark]
|
|
212
|
+
message = success ? options[:success_message] : options[:fail_message] || options[:success_message]
|
|
213
|
+
RubyProgress::Ripple.complete(text, message, options[:complete_checkmark], success)
|
|
214
|
+
end
|
|
215
|
+
exit success ? 0 : 1
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def self.run_indefinitely(text, options)
|
|
219
|
+
rippler = RubyProgress::Ripple.new(text, options)
|
|
220
|
+
RubyProgress::Utils.hide_cursor
|
|
221
|
+
begin
|
|
222
|
+
while true
|
|
223
|
+
rippler.advance
|
|
224
|
+
end
|
|
225
|
+
ensure
|
|
226
|
+
RubyProgress::Utils.show_cursor
|
|
227
|
+
RubyProgress::Ripple.complete(text, options[:success_message], options[:complete_checkmark], true)
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Enhanced Worm CLI with unified flags
|
|
233
|
+
module WormCLI
|
|
234
|
+
def self.run
|
|
235
|
+
options = parse_cli_options
|
|
236
|
+
|
|
237
|
+
progress = RubyProgress::Worm.new(options)
|
|
238
|
+
|
|
239
|
+
if options[:command]
|
|
240
|
+
progress.run_with_command
|
|
241
|
+
else
|
|
242
|
+
progress.run_indefinitely
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def self.parse_cli_options
|
|
247
|
+
options = {}
|
|
248
|
+
|
|
249
|
+
OptionParser.new do |opts|
|
|
250
|
+
opts.banner = 'Usage: prg worm [options]'
|
|
251
|
+
opts.separator ''
|
|
252
|
+
opts.separator 'Animation Options:'
|
|
253
|
+
|
|
254
|
+
opts.on('-s', '--speed SPEED', 'Animation speed (1-10, fast/medium/slow, or f/m/s)') do |speed|
|
|
255
|
+
options[:speed] = speed
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
opts.on('-m', '--message MESSAGE', 'Message to display before animation') do |message|
|
|
259
|
+
options[:message] = message
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
opts.on('-l', '--length LENGTH', Integer, 'Number of dots to display') do |length|
|
|
263
|
+
options[:length] = length
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
opts.on('--style STYLE', 'Animation style (circles/blocks/geometric or c/b/g)') do |style|
|
|
267
|
+
options[:style] = style
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
opts.separator ''
|
|
271
|
+
opts.separator 'Command Execution:'
|
|
272
|
+
|
|
273
|
+
opts.on('-c', '--command COMMAND', 'Command to run (optional - runs indefinitely without)') do |command|
|
|
274
|
+
options[:command] = command
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
opts.on('--success MESSAGE', 'Success message to display') do |text|
|
|
278
|
+
options[:success] = text
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
opts.on('--error MESSAGE', 'Error message to display') do |text|
|
|
282
|
+
options[:error] = text
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
opts.on('--checkmark', 'Show checkmarks (✅ success, 🛑 failure)') do
|
|
286
|
+
options[:checkmark] = true
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
opts.on('--stdout', 'Output captured command result to STDOUT') do
|
|
290
|
+
options[:stdout] = true
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
opts.separator ''
|
|
294
|
+
opts.separator 'General:'
|
|
295
|
+
|
|
296
|
+
opts.on('-v', '--version', 'Show version') do
|
|
297
|
+
puts "Worm version #{RubyProgress::VERSION}"
|
|
298
|
+
exit
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
opts.on('-h', '--help', 'Show this help') do
|
|
302
|
+
puts opts
|
|
303
|
+
exit
|
|
304
|
+
end
|
|
305
|
+
end.parse!
|
|
306
|
+
|
|
307
|
+
options
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
PrgCLI.run if __FILE__ == $PROGRAM_NAME
|
data/bin/ripple
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../lib/ruby-progress'
|
|
5
|
+
require 'optparse'
|
|
6
|
+
|
|
7
|
+
# Ripple CLI implementation
|
|
8
|
+
module RippleCLI
|
|
9
|
+
def self.run
|
|
10
|
+
trap('INT') do
|
|
11
|
+
RubyProgress::Utils.show_cursor
|
|
12
|
+
exit
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
options = {
|
|
16
|
+
speed: :medium,
|
|
17
|
+
direction: :bidirectional,
|
|
18
|
+
rainbow: false,
|
|
19
|
+
spinner: false,
|
|
20
|
+
spinner_position: :before,
|
|
21
|
+
caps: false,
|
|
22
|
+
inverse: false,
|
|
23
|
+
command: nil,
|
|
24
|
+
success_message: nil,
|
|
25
|
+
fail_message: nil,
|
|
26
|
+
complete_checkmark: false
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
OptionParser.new do |opts|
|
|
30
|
+
opts.banner = 'Usage: ripple [options] STRING'
|
|
31
|
+
|
|
32
|
+
opts.on('-s', '--speed SPEED', %i[fast medium slow], 'Set animation speed ((f)ast/(m)edium/(s)low)') do |s|
|
|
33
|
+
options[:speed] = case s
|
|
34
|
+
when /^f/ then :fast
|
|
35
|
+
when /^m/ then :medium
|
|
36
|
+
when /^s/ then :slow
|
|
37
|
+
else :slow
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
opts.on('-r', '--rainbow', 'Enable rainbow mode') do
|
|
42
|
+
options[:rainbow] = true
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
opts.on('-d', '--direction DIRECTION', 'Set animation format ((f)orward/(b)ack-and-forth)') do |f|
|
|
46
|
+
options[:format] = f =~ /^f/ ? :forward_only : :bidirectional
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
opts.on('-i', '--inverse', 'Enable inverse mode') do
|
|
50
|
+
options[:inverse] = true
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
opts.on('-c', '--command COMMAND', 'Run a command during the animation') do |command|
|
|
54
|
+
options[:command] = command
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
opts.on('--success MESSAGE', 'Message to display on success') do |msg|
|
|
58
|
+
options[:success_message] = msg
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
opts.on('--fail MESSAGE', 'Message to display on error') do |msg|
|
|
62
|
+
options[:fail_message] = msg
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
opts.on('--checkmark') do
|
|
66
|
+
options[:complete_checkmark] = true
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
opts.on('--spinner TYPE', 'Display a rippling spinner with the message') do |type|
|
|
70
|
+
options[:spinner] = type.normalize_type
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
opts.on('--spinner-pos POSITION', 'Display spinner [b]efore or [a]fter message') do |pos|
|
|
74
|
+
options[:spinner_position] = pos =~ /^a/ ? :after : :before
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
opts.on('--list-spinners', 'List available spinners') do
|
|
78
|
+
out = "Spinners:\n"
|
|
79
|
+
RubyProgress::INDICATORS.each do |k, v|
|
|
80
|
+
out += "- #{k}: #{v[2]}\n"
|
|
81
|
+
end
|
|
82
|
+
puts out
|
|
83
|
+
exit
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
opts.on('--caps') do
|
|
87
|
+
options[:caps] = true
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
opts.on('--stdout', 'Output captured command result to STDOUT') do |_output|
|
|
91
|
+
options[:output] = :stdout
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
opts.on('--quiet', 'Suppress all output') do |_quiet|
|
|
95
|
+
options[:output] = :quiet
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
opts.on('-v', '--version', 'Display the version') do
|
|
99
|
+
puts "Ripple version #{RubyProgress::VERSION}"
|
|
100
|
+
exit
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
opts.on('-h', '--help', 'Display this help message') do
|
|
104
|
+
puts opts
|
|
105
|
+
exit
|
|
106
|
+
end
|
|
107
|
+
end.parse!
|
|
108
|
+
|
|
109
|
+
if ARGV.empty?
|
|
110
|
+
puts 'Please provide a string to animate as an argument.'
|
|
111
|
+
exit 1
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
if options[:command]
|
|
115
|
+
captured_output = nil
|
|
116
|
+
res = RubyProgress::Ripple.progress(ARGV.join(' '), options) do
|
|
117
|
+
captured_output = `#{options[:command]} 2>&1`
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
res = $?.success?
|
|
121
|
+
|
|
122
|
+
puts captured_output if options[:output] == :stdout
|
|
123
|
+
if options[:success_message]
|
|
124
|
+
message = if res
|
|
125
|
+
options[:success_message]
|
|
126
|
+
else
|
|
127
|
+
options[:fail_message] || options[:success_message]
|
|
128
|
+
end
|
|
129
|
+
RubyProgress::Ripple.complete(ARGV.join(' '), message, options[:complete_checkmark], res)
|
|
130
|
+
end
|
|
131
|
+
exit res ? 0 : 1
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
rippler = RubyProgress::Ripple.new(ARGV.join(' '), {
|
|
135
|
+
speed: options[:speed],
|
|
136
|
+
format: options[:format],
|
|
137
|
+
rainbow: options[:rainbow],
|
|
138
|
+
inverse: options[:inverse]
|
|
139
|
+
})
|
|
140
|
+
RubyProgress::Utils.hide_cursor
|
|
141
|
+
rippler.advance while true
|
|
142
|
+
RubyProgress::Utils.show_cursor
|
|
143
|
+
RubyProgress::Ripple.complete(ARGV.join(' '), options[:success_message], options[:complete_checkmark], true)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
RippleCLI.run if __FILE__ == $PROGRAM_NAME
|
data/bin/worm
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../lib/ruby-progress'
|
|
5
|
+
require 'optparse'
|
|
6
|
+
|
|
7
|
+
# Worm CLI implementation
|
|
8
|
+
module WormCLI
|
|
9
|
+
def self.run
|
|
10
|
+
options = parse_cli_options
|
|
11
|
+
progress = RubyProgress::Worm.new(options)
|
|
12
|
+
|
|
13
|
+
if options[:command]
|
|
14
|
+
progress.run_with_command
|
|
15
|
+
else
|
|
16
|
+
# Run indefinitely like ripple does when no command is specified
|
|
17
|
+
progress.run_indefinitely
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.parse_cli_options
|
|
22
|
+
options = {}
|
|
23
|
+
|
|
24
|
+
OptionParser.new do |opts|
|
|
25
|
+
opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
|
|
26
|
+
opts.separator ''
|
|
27
|
+
opts.separator 'Options:'
|
|
28
|
+
|
|
29
|
+
opts.on('-s', '--speed SPEED', 'Animation speed (1-10, fast, medium, slow, or f/m/s)') do |speed|
|
|
30
|
+
options[:speed] = speed
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
opts.on('-l', '--length LENGTH', Integer, 'Number of dots to display') do |length|
|
|
34
|
+
options[:length] = length
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
opts.on('-m', '--message MESSAGE', 'Message to display before dots') do |message|
|
|
38
|
+
options[:message] = message
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
opts.on('--style STYLE', 'Animation style (blocks, geometric, circles, or b/g/c)') do |style|
|
|
42
|
+
options[:style] = style
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
opts.on('-c', '--command COMMAND', 'Command to run (optional - runs indefinitely without command)') do |command|
|
|
46
|
+
options[:command] = command
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
opts.on('--success TEXT', 'Text to display on successful completion') do |text|
|
|
50
|
+
options[:success] = text
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
opts.on('--error TEXT', 'Text to display on error') do |text|
|
|
54
|
+
options[:error] = text
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
opts.on('--checkmark', 'Show checkmarks (✅/🛑) in completion messages') do
|
|
58
|
+
options[:checkmark] = true
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
opts.on('--stdout', 'Output captured command result to STDOUT') do
|
|
62
|
+
options[:stdout] = true
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
opts.on('-h', '--help', 'Show this help message') do
|
|
66
|
+
puts opts
|
|
67
|
+
exit
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
opts.on('-v', '--version', 'Display the version') do
|
|
71
|
+
puts "Worm version #{RubyProgress::VERSION}"
|
|
72
|
+
exit
|
|
73
|
+
end
|
|
74
|
+
end.parse!
|
|
75
|
+
|
|
76
|
+
options
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
WormCLI.run if __FILE__ == $PROGRAM_NAME
|
data/demo_gem.rb
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Demo script showing gem functionality for CI/CD validation
|
|
5
|
+
|
|
6
|
+
puts '🚀 Ruby Progress Gem Demo'
|
|
7
|
+
puts '========================='
|
|
8
|
+
puts
|
|
9
|
+
|
|
10
|
+
# Test library loading
|
|
11
|
+
begin
|
|
12
|
+
require 'ruby-progress'
|
|
13
|
+
puts '✅ Library loaded successfully'
|
|
14
|
+
puts "📦 Version: #{RubyProgress::VERSION}"
|
|
15
|
+
rescue LoadError => e
|
|
16
|
+
puts "❌ Failed to load library: #{e.message}"
|
|
17
|
+
exit 1
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
puts
|
|
21
|
+
|
|
22
|
+
# Test Ripple class
|
|
23
|
+
begin
|
|
24
|
+
puts '🌊 Testing Ripple class...'
|
|
25
|
+
ripple = RubyProgress::Ripple.new('Demo Test')
|
|
26
|
+
puts '✅ Ripple class instantiated successfully'
|
|
27
|
+
rescue StandardError => e
|
|
28
|
+
puts "❌ Ripple test failed: #{e.message}"
|
|
29
|
+
exit 1
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Test Worm class
|
|
33
|
+
begin
|
|
34
|
+
puts '🐛 Testing Worm class...'
|
|
35
|
+
worm = RubyProgress::Worm.new(message: 'Demo Test')
|
|
36
|
+
puts '✅ Worm class instantiated successfully'
|
|
37
|
+
rescue StandardError => e
|
|
38
|
+
puts "❌ Worm test failed: #{e.message}"
|
|
39
|
+
exit 1
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
puts
|
|
43
|
+
puts '🎉 All tests passed! The gem is working correctly.'
|
|
44
|
+
puts
|
|
45
|
+
puts '📊 Key Features Verified:'
|
|
46
|
+
puts ' • Library structure and loading'
|
|
47
|
+
puts ' • Version management'
|
|
48
|
+
puts ' • Ripple and Worm class instantiation'
|
|
49
|
+
puts ' • Module namespacing'
|
|
50
|
+
puts
|
|
51
|
+
puts '🔗 Ready for badge display:'
|
|
52
|
+
puts ' • RubyGems version badge'
|
|
53
|
+
puts ' • MIT license badge'
|
|
54
|
+
puts ' • GitHub Actions test badge'
|
|
55
|
+
puts ' • Ruby version compatibility badge'
|
|
56
|
+
puts ' • Test coverage badge'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Demo script showing worm.rb's new infinite mode
|
|
5
|
+
|
|
6
|
+
puts '=== Worm.rb Infinite Mode Demo ==='
|
|
7
|
+
puts
|
|
8
|
+
|
|
9
|
+
puts '1. Running indefinitely for 3 seconds (like ripple):'
|
|
10
|
+
system("timeout 3s ruby worm.rb --message 'Loading...' --speed fast --style circles || echo")
|
|
11
|
+
puts
|
|
12
|
+
|
|
13
|
+
puts '2. Running with command and checkmarks:'
|
|
14
|
+
system("ruby worm.rb --command 'sleep 1 && echo Success' --message 'Processing' --success 'Done!' --checkmark --stdout")
|
|
15
|
+
puts
|
|
16
|
+
|
|
17
|
+
puts '3. Running indefinitely with blocks style:'
|
|
18
|
+
system("timeout 2s ruby worm.rb --message 'Working' --style blocks --length 6 --speed medium || echo")
|
|
19
|
+
puts
|
|
20
|
+
|
|
21
|
+
puts 'Demo complete! Worm.rb now works like ripple when no command is specified.'
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Demo of RubyProgress::Utils universal utilities
|
|
5
|
+
require_relative '../lib/ruby-progress'
|
|
6
|
+
|
|
7
|
+
puts "=== RubyProgress::Utils Demo ==="
|
|
8
|
+
puts
|
|
9
|
+
|
|
10
|
+
# Test cursor control
|
|
11
|
+
puts "Testing cursor control..."
|
|
12
|
+
print "Hiding cursor for 2 seconds..."
|
|
13
|
+
RubyProgress::Utils.hide_cursor
|
|
14
|
+
sleep 2
|
|
15
|
+
print " showing cursor again."
|
|
16
|
+
RubyProgress::Utils.show_cursor
|
|
17
|
+
puts
|
|
18
|
+
puts
|
|
19
|
+
|
|
20
|
+
# Test line clearing
|
|
21
|
+
puts "Testing line clearing..."
|
|
22
|
+
print "This line will be cleared..."
|
|
23
|
+
sleep 1
|
|
24
|
+
RubyProgress::Utils.clear_line
|
|
25
|
+
print "New content on the same line!"
|
|
26
|
+
puts
|
|
27
|
+
puts
|
|
28
|
+
|
|
29
|
+
# Test completion messages
|
|
30
|
+
puts "Testing completion messages..."
|
|
31
|
+
|
|
32
|
+
RubyProgress::Utils.display_completion("Basic success message", success: true)
|
|
33
|
+
RubyProgress::Utils.display_completion("Basic failure message", success: false)
|
|
34
|
+
|
|
35
|
+
puts
|
|
36
|
+
puts "With checkmarks:"
|
|
37
|
+
RubyProgress::Utils.display_completion("Success with checkmark", success: true, show_checkmark: true)
|
|
38
|
+
RubyProgress::Utils.display_completion("Failure with checkmark", success: false, show_checkmark: true)
|
|
39
|
+
|
|
40
|
+
puts
|
|
41
|
+
puts "Different output streams:"
|
|
42
|
+
RubyProgress::Utils.display_completion("To STDOUT", success: true, show_checkmark: true, output_stream: :stdout)
|
|
43
|
+
RubyProgress::Utils.display_completion("To STDERR", success: false, show_checkmark: true, output_stream: :stderr)
|
|
44
|
+
|
|
45
|
+
puts
|
|
46
|
+
puts "Complete with clear:"
|
|
47
|
+
print "Content to be cleared and replaced..."
|
|
48
|
+
sleep 1
|
|
49
|
+
RubyProgress::Utils.complete_with_clear("Cleared and completed!", success: true, show_checkmark: true, output_stream: :stdout)
|
|
50
|
+
|
|
51
|
+
puts
|
|
52
|
+
puts "=== Demo Complete ==="
|