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
|
@@ -28,6 +28,7 @@ module RubyProgress
|
|
|
28
28
|
report: false
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
# rubocop:disable Metrics/BlockLength
|
|
31
32
|
begin
|
|
32
33
|
OptionParser.new do |opts|
|
|
33
34
|
opts.banner = 'Usage: prg fill [options]'
|
|
@@ -106,6 +107,14 @@ module RubyProgress
|
|
|
106
107
|
options[:success_message] = msg
|
|
107
108
|
end
|
|
108
109
|
|
|
110
|
+
opts.on('--success-icon ICON', 'Custom success icon to show with completion messages') do |ic|
|
|
111
|
+
options[:success_icon] = ic
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
opts.on('--error-icon ICON', 'Custom error icon to show with failure messages') do |ic|
|
|
115
|
+
options[:error_icon] = ic
|
|
116
|
+
end
|
|
117
|
+
|
|
109
118
|
opts.on('--error MESSAGE', 'Error message to display on cancellation') do |msg|
|
|
110
119
|
options[:error_message] = msg
|
|
111
120
|
end
|
|
@@ -121,6 +130,21 @@ module RubyProgress
|
|
|
121
130
|
options[:daemon] = true
|
|
122
131
|
end
|
|
123
132
|
|
|
133
|
+
opts.on('--daemon-as NAME', 'Run in daemon mode with custom name (creates /tmp/ruby-progress/NAME.pid)') do |name|
|
|
134
|
+
options[:daemon] = true
|
|
135
|
+
options[:daemon_name] = name
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Accept --daemon-name as alias for --daemon-as
|
|
139
|
+
opts.on('--daemon-name NAME', 'Alias for --daemon-as (compat)') do |name|
|
|
140
|
+
options[:daemon] = true
|
|
141
|
+
options[:daemon_name] = name
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
opts.on('--no-detach', 'When used with --daemon/--daemon-as: run background child but do not fully detach from the terminal') do
|
|
145
|
+
options[:no_detach] = true
|
|
146
|
+
end
|
|
147
|
+
|
|
124
148
|
opts.on('--pid-file FILE', 'PID file location (default: /tmp/ruby-progress/fill.pid)') do |file|
|
|
125
149
|
options[:pid_file] = file
|
|
126
150
|
end
|
|
@@ -129,10 +153,36 @@ module RubyProgress
|
|
|
129
153
|
options[:stop] = true
|
|
130
154
|
end
|
|
131
155
|
|
|
156
|
+
opts.on('--stop-id NAME', 'Stop daemon by name (implies --stop)') do |name|
|
|
157
|
+
# Backwards-compatible shorthand used in demos: set stop flag
|
|
158
|
+
options[:stop] = true
|
|
159
|
+
# Normalize to canonical keys used by FillCLI (daemon_name/status_name)
|
|
160
|
+
options[:stop_name] = name
|
|
161
|
+
options[:daemon_name] = name
|
|
162
|
+
options[:status_name] = name
|
|
163
|
+
end
|
|
164
|
+
|
|
132
165
|
opts.on('--status', 'Show daemon status') do
|
|
133
166
|
options[:status] = true
|
|
134
167
|
end
|
|
135
168
|
|
|
169
|
+
opts.on('--status-id NAME', 'Show daemon status by name') do |name|
|
|
170
|
+
options[:status] = true
|
|
171
|
+
# Normalize to canonical key
|
|
172
|
+
options[:status_name] = name
|
|
173
|
+
options[:daemon_name] = name
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
opts.on('--stop-success MESSAGE', 'Stop daemon with success message (implies --stop)') do |msg|
|
|
177
|
+
options[:stop] = true
|
|
178
|
+
options[:stop_success] = msg
|
|
179
|
+
end
|
|
180
|
+
opts.on('--stop-error MESSAGE', 'Stop daemon with error message (implies --stop)') do |msg|
|
|
181
|
+
options[:stop] = true
|
|
182
|
+
options[:stop_error] = msg
|
|
183
|
+
end
|
|
184
|
+
opts.on('--stop-checkmark', 'When stopping, include a success checkmark') { options[:stop_checkmark] = true }
|
|
185
|
+
|
|
136
186
|
opts.separator ''
|
|
137
187
|
opts.separator 'General:'
|
|
138
188
|
|
|
@@ -148,6 +198,7 @@ module RubyProgress
|
|
|
148
198
|
options[:help] = true
|
|
149
199
|
end
|
|
150
200
|
end.parse!
|
|
201
|
+
# rubocop:enable Metrics/BlockLength
|
|
151
202
|
rescue OptionParser::InvalidOption => e
|
|
152
203
|
warn "Invalid option: #{e.args.first}"
|
|
153
204
|
warn ''
|
|
@@ -155,7 +206,6 @@ module RubyProgress
|
|
|
155
206
|
warn "Run 'prg fill --help' for more information."
|
|
156
207
|
exit 1
|
|
157
208
|
end
|
|
158
|
-
|
|
159
209
|
options
|
|
160
210
|
end
|
|
161
211
|
|
|
@@ -28,12 +28,43 @@ module JobCLI
|
|
|
28
28
|
options = { wait: false }
|
|
29
29
|
opt = OptionParser.new do |o|
|
|
30
30
|
o.banner = 'Usage: prg job send [options]'
|
|
31
|
-
o.on('--pid-file PATH', 'Path to daemon pid file')
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
o.on('--
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
o.on('--pid-file PATH', 'Path to daemon pid file') do |v|
|
|
32
|
+
options[:pid_file] = v
|
|
33
|
+
end
|
|
34
|
+
o.on('--daemon-name NAME', 'Daemon name (maps to /tmp/ruby-progress/NAME.pid)') do |v|
|
|
35
|
+
options[:daemon_name] = v
|
|
36
|
+
end
|
|
37
|
+
o.on('--command CMD', 'Command to run') do |v|
|
|
38
|
+
options[:command] = v
|
|
39
|
+
end
|
|
40
|
+
o.on('--stdin', 'Read command from stdin (overrides --command)') do
|
|
41
|
+
options[:stdin] = true
|
|
42
|
+
end
|
|
43
|
+
o.on('--advance', 'Send an advance action (no value)') do
|
|
44
|
+
options[:action] = 'advance'
|
|
45
|
+
end
|
|
46
|
+
o.on('--percent N', Integer, 'Send a percent action with value N') do |v|
|
|
47
|
+
options[:action] = 'percent'
|
|
48
|
+
options[:value] = v
|
|
49
|
+
end
|
|
50
|
+
o.on('--complete', 'Send a complete action (no value)') do
|
|
51
|
+
options[:action] = 'complete'
|
|
52
|
+
end
|
|
53
|
+
o.on('--cancel', 'Send a cancel action (no value)') do
|
|
54
|
+
options[:action] = 'cancel'
|
|
55
|
+
end
|
|
56
|
+
o.on('--action ACTION', 'Send a custom action name') do |v|
|
|
57
|
+
options[:action] = v
|
|
58
|
+
end
|
|
59
|
+
o.on('--value VAL', 'Value for the action (string or number)') do |v|
|
|
60
|
+
options[:value] = v
|
|
61
|
+
end
|
|
62
|
+
o.on('--wait', 'Wait for result file and print it') do
|
|
63
|
+
options[:wait] = true
|
|
64
|
+
end
|
|
65
|
+
o.on('--timeout SECONDS', Integer, 'Timeout seconds for wait') do |v|
|
|
66
|
+
options[:timeout] = v
|
|
67
|
+
end
|
|
37
68
|
end
|
|
38
69
|
|
|
39
70
|
rest = opt.parse(argv)
|
|
@@ -63,16 +94,25 @@ module JobCLI
|
|
|
63
94
|
opts[:command]
|
|
64
95
|
end
|
|
65
96
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
97
|
+
is_action = !opts[:action].nil? && opts[:action] != false
|
|
98
|
+
|
|
99
|
+
if is_action
|
|
100
|
+
if cmd && !cmd.strip.empty?
|
|
101
|
+
warn 'Cannot specify both --command/--stdin and an action flag'
|
|
102
|
+
exit 1
|
|
103
|
+
end
|
|
104
|
+
else
|
|
105
|
+
unless cmd && !cmd.strip.empty?
|
|
106
|
+
warn 'No command specified. Use --command, --stdin, or pass an action flag.'
|
|
107
|
+
exit 1
|
|
108
|
+
end
|
|
69
109
|
end
|
|
70
110
|
|
|
71
111
|
job_id = SecureRandom.uuid
|
|
72
112
|
tmp = File.join(job_dir, "#{job_id}.json.tmp")
|
|
73
113
|
final = File.join(job_dir, "#{job_id}.json")
|
|
74
114
|
|
|
75
|
-
payload =
|
|
115
|
+
payload = build_payload(opts, job_id, cmd)
|
|
76
116
|
|
|
77
117
|
File.write(tmp, JSON.dump(payload))
|
|
78
118
|
FileUtils.mv(tmp, final)
|
|
@@ -96,4 +136,24 @@ module JobCLI
|
|
|
96
136
|
puts job_id
|
|
97
137
|
end
|
|
98
138
|
end
|
|
139
|
+
|
|
140
|
+
# Build the JSON payload for a job based on parsed options.
|
|
141
|
+
def self.build_payload(opts, job_id, cmd)
|
|
142
|
+
payload = { 'id' => job_id }
|
|
143
|
+
|
|
144
|
+
is_action = !opts[:action].nil? && opts[:action] != false
|
|
145
|
+
|
|
146
|
+
if is_action
|
|
147
|
+
payload['action'] = opts[:action]
|
|
148
|
+
if opts.key?(:value)
|
|
149
|
+
val = opts[:value]
|
|
150
|
+
payload['value'] = val.to_i if val.is_a?(String) && val =~ /^\d+$/
|
|
151
|
+
payload['value'] ||= val
|
|
152
|
+
end
|
|
153
|
+
else
|
|
154
|
+
payload['command'] = cmd
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
payload
|
|
158
|
+
end
|
|
99
159
|
end
|
|
@@ -33,8 +33,13 @@ module RippleCLI
|
|
|
33
33
|
)
|
|
34
34
|
exit
|
|
35
35
|
elsif options[:daemon]
|
|
36
|
-
# For daemon mode, detach so shell has no tracked job
|
|
37
|
-
|
|
36
|
+
# For daemon mode, detach so shell has no tracked job unless the user
|
|
37
|
+
# requested a non-detaching background child via --no-detach.
|
|
38
|
+
if options[:no_detach]
|
|
39
|
+
PrgCLI.backgroundize
|
|
40
|
+
else
|
|
41
|
+
PrgCLI.daemonize
|
|
42
|
+
end
|
|
38
43
|
|
|
39
44
|
# For daemon mode, default message if none provided
|
|
40
45
|
text = options[:message] || ARGV.join(' ')
|
|
@@ -63,13 +68,17 @@ module RippleCLI
|
|
|
63
68
|
end
|
|
64
69
|
|
|
65
70
|
def self.run_with_command(text, options)
|
|
66
|
-
if $stdout.tty?
|
|
71
|
+
if $stdout.tty?
|
|
72
|
+
# Interactive TTY: use PTY-based capture so the animation can run while the
|
|
73
|
+
# command executes. We only print captured stdout if options[:output] == :stdout.
|
|
67
74
|
oc = RubyProgress::OutputCapture.new(command: options[:command], lines: options[:output_lines] || 3, position: options[:output_position] || :above)
|
|
68
75
|
oc.start
|
|
69
76
|
|
|
70
|
-
# Create rippler
|
|
77
|
+
# Create rippler. Attach output capture only when the user requested
|
|
78
|
+
# live stdout display via --stdout; otherwise start the PTY reader so
|
|
79
|
+
# we can collect the child's exit status but do not call redraw.
|
|
71
80
|
rippler = RubyProgress::Ripple.new(text, options)
|
|
72
|
-
rippler.instance_variable_set(:@output_capture, oc)
|
|
81
|
+
rippler.instance_variable_set(:@output_capture, oc) if options[:output] == :stdout
|
|
73
82
|
|
|
74
83
|
thread = Thread.new { loop { rippler.advance } }
|
|
75
84
|
oc.wait
|
|
@@ -77,17 +86,24 @@ module RippleCLI
|
|
|
77
86
|
|
|
78
87
|
captured_lines = oc.lines
|
|
79
88
|
captured_output = captured_lines.join("\n")
|
|
80
|
-
success =
|
|
89
|
+
success = oc.exit_status.nil? || oc.exit_status.zero?
|
|
81
90
|
else
|
|
82
|
-
#
|
|
91
|
+
# Non-interactive / CI: fallback to legacy synchronous capture
|
|
83
92
|
captured_output = `#{options[:command]} 2>&1`
|
|
84
93
|
success = $CHILD_STATUS.success?
|
|
85
94
|
end
|
|
86
95
|
|
|
87
96
|
puts captured_output if options[:output] == :stdout
|
|
97
|
+
|
|
88
98
|
if options[:success_message] || options[:complete_checkmark]
|
|
89
99
|
message = success ? options[:success_message] : options[:fail_message] || options[:success_message]
|
|
90
|
-
RubyProgress::Ripple.complete(
|
|
100
|
+
RubyProgress::Ripple.complete(
|
|
101
|
+
text,
|
|
102
|
+
message,
|
|
103
|
+
options[:complete_checkmark],
|
|
104
|
+
success,
|
|
105
|
+
icons: { success: options[:success_icon], error: options[:error_icon] }
|
|
106
|
+
)
|
|
91
107
|
end
|
|
92
108
|
exit success ? 0 : 1
|
|
93
109
|
end
|
|
@@ -147,7 +163,8 @@ module RippleCLI
|
|
|
147
163
|
message,
|
|
148
164
|
success: success_val,
|
|
149
165
|
show_checkmark: check,
|
|
150
|
-
output_stream: :stdout
|
|
166
|
+
output_stream: :stdout,
|
|
167
|
+
icons: { success: options[:success_icon], error: options[:error_icon] }
|
|
151
168
|
)
|
|
152
169
|
end
|
|
153
170
|
rescue StandardError
|
|
@@ -196,7 +213,8 @@ module RippleCLI
|
|
|
196
213
|
job['message'],
|
|
197
214
|
success: success,
|
|
198
215
|
show_checkmark: job['checkmark'] || false,
|
|
199
|
-
output_stream: :stdout
|
|
216
|
+
output_stream: :stdout,
|
|
217
|
+
icons: { success: options[:success_icon], error: options[:error_icon] }
|
|
200
218
|
)
|
|
201
219
|
end
|
|
202
220
|
|
|
@@ -71,6 +71,14 @@ module RippleCLI
|
|
|
71
71
|
options[:success_message] = msg
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
+
opts.on('--success-icon ICON', 'Custom success icon to show with completion messages') do |ic|
|
|
75
|
+
options[:success_icon] = ic
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
opts.on('--error-icon ICON', 'Custom error icon to show with failure messages') do |ic|
|
|
79
|
+
options[:error_icon] = ic
|
|
80
|
+
end
|
|
81
|
+
|
|
74
82
|
opts.on('--error MESSAGE', 'Error message to display') do |msg|
|
|
75
83
|
options[:fail_message] = msg
|
|
76
84
|
end
|
|
@@ -94,6 +102,10 @@ module RippleCLI
|
|
|
94
102
|
options[:daemon] = true
|
|
95
103
|
end
|
|
96
104
|
|
|
105
|
+
opts.on('--no-detach', 'When used with --daemon: run background child but do not fully detach from the terminal') do
|
|
106
|
+
options[:no_detach] = true
|
|
107
|
+
end
|
|
108
|
+
|
|
97
109
|
opts.on('--pid-file FILE', 'Write process ID to file (default: /tmp/ruby-progress/progress.pid)') do |file|
|
|
98
110
|
options[:pid_file] = file
|
|
99
111
|
end
|
|
@@ -32,6 +32,12 @@ module TwirlCLI
|
|
|
32
32
|
options[:style] = style
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
+
opts.on('-d', '--direction DIRECTION', 'Animation direction (forward/bidirectional or f/b)') do |direction|
|
|
36
|
+
# Twirl is a spinner and doesn't visibly change with direction, but accept the
|
|
37
|
+
# flag for parity with other subcommands (Worm/Ripple) so scripts can use it.
|
|
38
|
+
options[:direction] = direction =~ /^f/i ? :forward_only : :bidirectional
|
|
39
|
+
end
|
|
40
|
+
|
|
35
41
|
opts.on('--ends CHARS', 'Start/end characters (even number of chars, split in half)') do |chars|
|
|
36
42
|
options[:ends] = chars
|
|
37
43
|
end
|
|
@@ -55,6 +61,14 @@ module TwirlCLI
|
|
|
55
61
|
options[:success] = text
|
|
56
62
|
end
|
|
57
63
|
|
|
64
|
+
opts.on('--success-icon ICON', 'Custom success icon to show with completion messages') do |ic|
|
|
65
|
+
options[:success_icon] = ic
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
opts.on('--error-icon ICON', 'Custom error icon to show with failure messages') do |ic|
|
|
69
|
+
options[:error_icon] = ic
|
|
70
|
+
end
|
|
71
|
+
|
|
58
72
|
opts.on('--error MESSAGE', 'Error message to display') do |text|
|
|
59
73
|
options[:error] = text
|
|
60
74
|
end
|
|
@@ -74,6 +88,10 @@ module TwirlCLI
|
|
|
74
88
|
options[:daemon] = true
|
|
75
89
|
end
|
|
76
90
|
|
|
91
|
+
opts.on('--no-detach', 'When used with --daemon/--daemon-as: run background child but do not fully detach from the terminal') do
|
|
92
|
+
options[:no_detach] = true
|
|
93
|
+
end
|
|
94
|
+
|
|
77
95
|
opts.on('--daemon-as NAME', 'Run in daemon mode with custom name (creates /tmp/ruby-progress/NAME.pid)') do |name|
|
|
78
96
|
options[:daemon] = true
|
|
79
97
|
options[:daemon_name] = name
|
|
@@ -58,7 +58,8 @@ module TwirlRunner
|
|
|
58
58
|
RubyProgress::Utils.display_completion(
|
|
59
59
|
final_msg,
|
|
60
60
|
success: success,
|
|
61
|
-
show_checkmark: options[:checkmark]
|
|
61
|
+
show_checkmark: options[:checkmark],
|
|
62
|
+
icons: { success: options[:success_icon], error: options[:error_icon] }
|
|
62
63
|
)
|
|
63
64
|
end
|
|
64
65
|
|
|
@@ -78,7 +79,8 @@ module TwirlRunner
|
|
|
78
79
|
RubyProgress::Utils.display_completion(
|
|
79
80
|
options[:success] || 'Complete',
|
|
80
81
|
success: true,
|
|
81
|
-
show_checkmark: options[:checkmark]
|
|
82
|
+
show_checkmark: options[:checkmark],
|
|
83
|
+
icons: { success: options[:success_icon], error: options[:error_icon] }
|
|
82
84
|
)
|
|
83
85
|
end
|
|
84
86
|
end
|
|
@@ -124,7 +126,8 @@ module TwirlRunner
|
|
|
124
126
|
job['message'],
|
|
125
127
|
success: success,
|
|
126
128
|
show_checkmark: job['checkmark'] || false,
|
|
127
|
-
output_stream: :stdout
|
|
129
|
+
output_stream: :stdout,
|
|
130
|
+
icons: { success: options[:success_icon], error: options[:error_icon] }
|
|
128
131
|
)
|
|
129
132
|
end
|
|
130
133
|
|
|
@@ -152,7 +155,8 @@ module TwirlRunner
|
|
|
152
155
|
message,
|
|
153
156
|
success: success_val,
|
|
154
157
|
show_checkmark: check,
|
|
155
|
-
output_stream: :stdout
|
|
158
|
+
output_stream: :stdout,
|
|
159
|
+
icons: { success: options[:success_icon], error: options[:error_icon] }
|
|
156
160
|
)
|
|
157
161
|
end
|
|
158
162
|
rescue StandardError
|
|
@@ -10,9 +10,23 @@ require_relative '../utils'
|
|
|
10
10
|
class TwirlSpinner
|
|
11
11
|
def initialize(message, options = {})
|
|
12
12
|
@message = message
|
|
13
|
-
@style = parse_style(options[:style] || 'dots')
|
|
14
13
|
@speed = parse_speed(options[:speed] || 'medium')
|
|
15
|
-
|
|
14
|
+
|
|
15
|
+
style_opt = options[:style].to_s
|
|
16
|
+
if style_opt.start_with?('custom=')
|
|
17
|
+
chars = style_opt.sub('custom=', '')
|
|
18
|
+
@frames = if chars.length >= 3
|
|
19
|
+
chars.chars
|
|
20
|
+
elsif chars.length == 2
|
|
21
|
+
[chars[0], chars[1], chars[1]]
|
|
22
|
+
else
|
|
23
|
+
[chars, chars, chars]
|
|
24
|
+
end
|
|
25
|
+
@style = :custom
|
|
26
|
+
else
|
|
27
|
+
@style = parse_style(style_opt.empty? ? 'dots' : style_opt)
|
|
28
|
+
@frames = RubyProgress::INDICATORS[@style] || RubyProgress::INDICATORS[:dots]
|
|
29
|
+
end
|
|
16
30
|
@start_chars, @end_chars = RubyProgress::Utils.parse_ends(options[:ends])
|
|
17
31
|
@index = 0
|
|
18
32
|
end
|
|
@@ -36,6 +50,8 @@ class TwirlSpinner
|
|
|
36
50
|
|
|
37
51
|
style_lower = style_input.to_s.downcase.strip
|
|
38
52
|
|
|
53
|
+
# parse_style returns a symbol key for RubyProgress::INDICATORS
|
|
54
|
+
|
|
39
55
|
indicator_keys = RubyProgress::INDICATORS.keys.map(&:to_s)
|
|
40
56
|
return style_lower.to_sym if indicator_keys.include?(style_lower)
|
|
41
57
|
|
|
@@ -33,8 +33,14 @@ module WormCLI
|
|
|
33
33
|
)
|
|
34
34
|
exit
|
|
35
35
|
elsif options[:daemon]
|
|
36
|
-
# Detach before starting daemon logic
|
|
37
|
-
|
|
36
|
+
# Detach (or background without detaching) before starting daemon logic
|
|
37
|
+
# so the invoking shell/script continues immediately.
|
|
38
|
+
if options[:no_detach]
|
|
39
|
+
PrgCLI.backgroundize
|
|
40
|
+
else
|
|
41
|
+
PrgCLI.daemonize
|
|
42
|
+
end
|
|
43
|
+
|
|
38
44
|
run_daemon_mode(options)
|
|
39
45
|
else
|
|
40
46
|
progress = RubyProgress::Worm.new(options)
|
|
@@ -86,7 +92,8 @@ module WormCLI
|
|
|
86
92
|
job['message'],
|
|
87
93
|
success: success,
|
|
88
94
|
show_checkmark: job['checkmark'] || false,
|
|
89
|
-
output_stream: :stdout
|
|
95
|
+
output_stream: :stdout,
|
|
96
|
+
icons: { success: options[:success_icon], error: options[:error_icon] }
|
|
90
97
|
)
|
|
91
98
|
end
|
|
92
99
|
|
|
@@ -99,7 +106,8 @@ module WormCLI
|
|
|
99
106
|
progress.run_daemon_mode(
|
|
100
107
|
success_message: options[:success],
|
|
101
108
|
show_checkmark: options[:checkmark],
|
|
102
|
-
control_message_file: RubyProgress::Daemon.control_message_file(pid_file)
|
|
109
|
+
control_message_file: RubyProgress::Daemon.control_message_file(pid_file),
|
|
110
|
+
icons: { success: options[:success_icon], error: options[:error_icon] }
|
|
103
111
|
)
|
|
104
112
|
ensure
|
|
105
113
|
job_thread&.kill
|
|
@@ -63,6 +63,14 @@ module WormCLI
|
|
|
63
63
|
options[:success] = text
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
+
opts.on('--success-icon ICON', 'Custom success icon to show with completion messages') do |ic|
|
|
67
|
+
options[:success_icon] = ic
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
opts.on('--error-icon ICON', 'Custom error icon to show with failure messages') do |ic|
|
|
71
|
+
options[:error_icon] = ic
|
|
72
|
+
end
|
|
73
|
+
|
|
66
74
|
opts.on('--error MESSAGE', 'Error message to display') do |text|
|
|
67
75
|
options[:error] = text
|
|
68
76
|
end
|
|
@@ -93,6 +101,10 @@ module WormCLI
|
|
|
93
101
|
options[:daemon_name] = name
|
|
94
102
|
end
|
|
95
103
|
|
|
104
|
+
opts.on('--no-detach', 'When used with --daemon/--daemon-as: run background child but do not fully detach from the terminal') do
|
|
105
|
+
options[:no_detach] = true
|
|
106
|
+
end
|
|
107
|
+
|
|
96
108
|
opts.on('--pid-file FILE', 'Write process ID to file (default: /tmp/ruby-progress/progress.pid)') do |file|
|
|
97
109
|
options[:pid_file] = file
|
|
98
110
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
# rubocop:disable Metrics/ModuleLength
|
|
5
4
|
require 'open3'
|
|
6
5
|
require 'json'
|
|
7
6
|
require_relative '../utils'
|
|
@@ -120,7 +119,7 @@ module WormRunner
|
|
|
120
119
|
@running = false
|
|
121
120
|
end
|
|
122
121
|
|
|
123
|
-
def run_daemon_mode(success_message: nil, show_checkmark: false, control_message_file: nil)
|
|
122
|
+
def run_daemon_mode(success_message: nil, show_checkmark: false, control_message_file: nil, icons: {})
|
|
124
123
|
@running = true
|
|
125
124
|
stop_requested = false
|
|
126
125
|
|
|
@@ -163,7 +162,8 @@ module WormRunner
|
|
|
163
162
|
final_message,
|
|
164
163
|
success: final_success,
|
|
165
164
|
show_checkmark: final_checkmark,
|
|
166
|
-
output_stream: :stdout
|
|
165
|
+
output_stream: :stdout,
|
|
166
|
+
icons: icons
|
|
167
167
|
)
|
|
168
168
|
end
|
|
169
169
|
|
|
@@ -278,5 +278,3 @@ module WormRunner
|
|
|
278
278
|
dots.join
|
|
279
279
|
end
|
|
280
280
|
end
|
|
281
|
-
|
|
282
|
-
# rubocop:enable Metrics/ModuleLength
|
data/lib/ruby-progress/fill.rb
CHANGED
|
@@ -95,7 +95,7 @@ module RubyProgress
|
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
# Complete the progress bar and show success message
|
|
98
|
-
def complete(message = nil)
|
|
98
|
+
def complete(message = nil, icons: {})
|
|
99
99
|
@current_progress = @length
|
|
100
100
|
render
|
|
101
101
|
|
|
@@ -105,7 +105,8 @@ module RubyProgress
|
|
|
105
105
|
completion_message,
|
|
106
106
|
success: true,
|
|
107
107
|
show_checkmark: true,
|
|
108
|
-
output_stream: :warn
|
|
108
|
+
output_stream: :warn,
|
|
109
|
+
icons: icons
|
|
109
110
|
)
|
|
110
111
|
else
|
|
111
112
|
$stderr.puts # Just add a newline if no message
|
|
@@ -124,7 +125,8 @@ module RubyProgress
|
|
|
124
125
|
error_msg,
|
|
125
126
|
success: false,
|
|
126
127
|
show_checkmark: true,
|
|
127
|
-
output_stream: :warn
|
|
128
|
+
output_stream: :warn,
|
|
129
|
+
icons: {}
|
|
128
130
|
)
|
|
129
131
|
end
|
|
130
132
|
|