apk: improve progress bar

* make it as wide as the screen
 * make sure it's drawn after package change
 * and draw it using ansi escapes in line buffered stderr
cute-signatures
Timo Teräs 2011-03-19 15:20:47 +02:00
parent 7b6e44b11b
commit 116d9a0ea7
3 changed files with 29 additions and 12 deletions

View File

@ -19,6 +19,7 @@
#include <getopt.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <openssl/crypto.h>
#ifndef OPENSSL_NO_ENGINE
@ -32,6 +33,7 @@
#include "apk_print.h"
char **apk_argv;
int apk_screen_width;
static struct apk_option generic_options[] = {
{ 'h', "help", "Show generic help or applet specific help" },
@ -238,6 +240,20 @@ static void init_openssl(void)
#endif
}
static void setup_terminal(void)
{
struct winsize w;
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
if (ioctl(STDERR_FILENO,TIOCGWINSZ, &w) == 0)
apk_screen_width = w.ws_col;
else
apk_screen_width = 70;
if (isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) && isatty(STDIN_FILENO))
apk_flags |= APK_PROGRESS;
}
int main(int argc, char **argv)
{
struct apk_applet *applet;
@ -257,9 +273,7 @@ int main(int argc, char **argv)
list_init(&dbopts.repository_list);
apk_atom_init();
umask(0);
if (isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) && isatty(STDIN_FILENO))
apk_flags |= APK_PROGRESS;
setup_terminal();
applet = deduce_applet(argc, argv);
num_options = ARRAY_SIZE(generic_options) + 1;

View File

@ -51,6 +51,7 @@ extern int apk_verbosity;
extern unsigned int apk_flags;
extern const char *apk_arch;
extern char **apk_argv;
extern int apk_screen_width;
#define APK_FORCE 0x0001
#define APK_SIMULATE 0x0002

View File

@ -668,19 +668,19 @@ static void apk_count_change(struct apk_change *change, struct apk_stats *stats)
stats->packages ++;
}
static inline void apk_draw_progress(int percent)
static void apk_draw_progress(int percent)
{
char tmp[128];
char reset[128];
const int bar_width = (apk_screen_width - 15);
int i;
snprintf(tmp, sizeof(tmp), "-[ ]- %3i%%", percent);
for (i = 0; (i < (percent/5)) && (i < (sizeof(tmp)-2)); i++)
tmp[2+i] = '#';
memset(reset, '\b', strlen(tmp));
fwrite(tmp, strlen(tmp), 1, stderr);
fwrite(reset, strlen(tmp), 1, stderr);
fputs("\e7-[", stderr);
for (i = 0; i < bar_width * percent / 100; i++)
fputc('#', stderr);
for (; i < bar_width; i++)
fputc(' ', stderr);
fprintf(stderr, "]- %3i%%", percent);
fflush(stderr);
fputs("\e8\e[0K", stderr);
}
struct progress {
@ -950,6 +950,8 @@ int apk_state_commit(struct apk_state *state,
list_for_each_entry(change, &state->change_list_head, change_list) {
n++;
apk_print_change(db, change->oldpkg, change->newpkg, n, state->num_changes);
if (apk_flags & APK_PROGRESS)
apk_draw_progress(prog.count);
prog.pkg = change->newpkg;
if (!(apk_flags & APK_SIMULATE)) {