You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
3.7 KiB
146 lines
3.7 KiB
package ksb::StatusView 0.20; |
|
|
|
# Helper used to handle a generic 'progress update' status for the module |
|
# build, update, install, etc. processes. |
|
# |
|
# Currently supports TTY output only but it's not impossible to visualize |
|
# extending this to a GUI or even web server as options. |
|
|
|
use strict; |
|
use warnings; |
|
use 5.014; |
|
|
|
use ksb::Debug 0.20 qw(colorize); |
|
|
|
use IO::Handle; |
|
|
|
sub new |
|
{ |
|
my $class = shift; |
|
my $defaultOpts = { |
|
cur_progress => -1, |
|
progress_total => -1, |
|
status => '', |
|
|
|
# Records number of modules built stats |
|
mod_total => -1, |
|
mod_failed => 0, |
|
mod_success => 0, |
|
}; |
|
|
|
# Must bless a hash ref since subclasses expect it. |
|
return bless $defaultOpts, $class; |
|
} |
|
|
|
# Sets the 'base' message to show as part of the update. E.g. "Compiling..." |
|
sub setStatus |
|
{ |
|
my ($self, $newStatus) = @_; |
|
$self->{status} = colorize($newStatus); |
|
} |
|
|
|
# Sets the amount of progress made vs. the total progress possible. |
|
sub setProgress |
|
{ |
|
my ($self, $newProgress) = @_; |
|
|
|
my $oldProgress = $self->{cur_progress}; |
|
$self->{cur_progress} = $newProgress; |
|
|
|
$self->update() if ($oldProgress != $newProgress); |
|
} |
|
|
|
# Sets the total amount of progress deemed possible. |
|
sub setProgressTotal |
|
{ |
|
my ($self, $newProgressTotal) = @_; |
|
$self->{progress_total} = $newProgressTotal; |
|
} |
|
|
|
# Gets (or sets, if arg provided) number of modules to be built. |
|
sub numberModulesTotal |
|
{ |
|
my ($self, $newTotal) = @_; |
|
$self->{mod_total} = $newTotal if $newTotal; |
|
return $self->{mod_total}; |
|
} |
|
|
|
# Gets (or sets, if arg provided) number of modules built successfully. |
|
sub numberModulesSucceeded |
|
{ |
|
my ($self, $newTotal) = @_; |
|
$self->{mod_success} = $newTotal if $newTotal; |
|
return $self->{mod_success}; |
|
} |
|
|
|
# Gets (or sets, if arg provided) number of modules not built successfully. |
|
sub numberModulesFailed |
|
{ |
|
my ($self, $newTotal) = @_; |
|
$self->{mod_failed} = $newTotal if $newTotal; |
|
return $self->{mod_failed}; |
|
} |
|
|
|
# Sends out the I/O needed to ensure the latest status is displayed. |
|
# E.g. for TTY it clears the line and redisplays the current stats. |
|
sub update |
|
{ |
|
my $self = shift; |
|
my $progress_total = $self->{progress_total}; |
|
my $msg; |
|
|
|
my ($mod_total, $mod_success, $mod_failed) = |
|
@{$self}{qw(mod_total mod_success mod_failed)}; |
|
|
|
my $fmt_spec = ($mod_total >= 100) ? "%03d" : "%02d"; |
|
my $status_line = $self->{status}; |
|
|
|
if ($mod_total > 1) { |
|
# Build up message in reverse order |
|
$msg = "$mod_total modules"; |
|
$msg = colorize("r[b[$mod_failed] failed, ") . $msg if $mod_failed; |
|
$msg = colorize("g[b[$mod_success] built, ") . $msg if $mod_success; |
|
|
|
$status_line = $self->{status} . " ($msg)"; |
|
} |
|
|
|
if ($progress_total > 0) { |
|
$msg = sprintf ("%0.1f%%", |
|
$self->{cur_progress} * 100 / $progress_total, |
|
) . $status_line; |
|
} |
|
elsif ($self->{cur_progress} < 0) { |
|
$msg = $status_line; |
|
} |
|
else { |
|
my $spinner = '-\\|/'; |
|
$msg = |
|
substr($spinner, $self->{cur_progress} % length($spinner), 1) . |
|
$status_line; |
|
} |
|
|
|
_clearLineAndUpdate($msg); |
|
} |
|
|
|
# For TTY outputs, this clears the line (if we actually had dirtied it) so |
|
# the rest of the program can resume output from where it'd been left off. |
|
sub releaseTTY |
|
{ |
|
my $self = shift; |
|
my $msg = shift // ''; |
|
|
|
_clearLineAndUpdate(colorize($msg)); |
|
} |
|
|
|
sub _clearLineAndUpdate |
|
{ |
|
my $msg = shift; |
|
|
|
# Give escape sequence to return to column 1 and clear the entire line |
|
# Then print message and return to column 1 again in case somewhere else |
|
# uses the tty. |
|
print "\e[1G\e[K$msg\e[1G"; |
|
STDOUT->flush; |
|
} |
|
|
|
1;
|
|
|