зеркало из https://github.com/microsoft/git.git
Merge branch 'sg/overlong-progress-fix'
Updating the display with progress message has been cleaned up to deal better with overlong messages. * sg/overlong-progress-fix: progress: break too long progress bar lines progress: clear previous progress update dynamically progress: assemble percentage and counters in a strbuf before printing progress: make display_progress() return void
This commit is contained in:
Коммит
425e51e54d
74
progress.c
74
progress.c
|
@ -8,11 +8,12 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "git-compat-util.h"
|
||||
#include "cache.h"
|
||||
#include "gettext.h"
|
||||
#include "progress.h"
|
||||
#include "strbuf.h"
|
||||
#include "trace.h"
|
||||
#include "utf8.h"
|
||||
|
||||
#define TP_IDX_MAX 8
|
||||
|
||||
|
@ -37,6 +38,9 @@ struct progress {
|
|||
unsigned sparse;
|
||||
struct throughput *throughput;
|
||||
uint64_t start_ns;
|
||||
struct strbuf counters_sb;
|
||||
int title_len;
|
||||
int split;
|
||||
};
|
||||
|
||||
static volatile sig_atomic_t progress_update;
|
||||
|
@ -79,41 +83,64 @@ static int is_foreground_fd(int fd)
|
|||
return tpgrp < 0 || tpgrp == getpgid(0);
|
||||
}
|
||||
|
||||
static int display(struct progress *progress, uint64_t n, const char *done)
|
||||
static void display(struct progress *progress, uint64_t n, const char *done)
|
||||
{
|
||||
const char *eol, *tp;
|
||||
const char *tp;
|
||||
struct strbuf *counters_sb = &progress->counters_sb;
|
||||
int show_update = 0;
|
||||
int last_count_len = counters_sb->len;
|
||||
|
||||
if (progress->delay && (!progress_update || --progress->delay))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
progress->last_value = n;
|
||||
tp = (progress->throughput) ? progress->throughput->display.buf : "";
|
||||
eol = done ? done : " \r";
|
||||
if (progress->total) {
|
||||
unsigned percent = n * 100 / progress->total;
|
||||
if (percent != progress->last_percent || progress_update) {
|
||||
progress->last_percent = percent;
|
||||
if (is_foreground_fd(fileno(stderr)) || done) {
|
||||
fprintf(stderr, "%s: %3u%% (%"PRIuMAX"/%"PRIuMAX")%s%s",
|
||||
progress->title, percent,
|
||||
(uintmax_t)n, (uintmax_t)progress->total,
|
||||
tp, eol);
|
||||
fflush(stderr);
|
||||
}
|
||||
progress_update = 0;
|
||||
return 1;
|
||||
|
||||
strbuf_reset(counters_sb);
|
||||
strbuf_addf(counters_sb,
|
||||
"%3u%% (%"PRIuMAX"/%"PRIuMAX")%s", percent,
|
||||
(uintmax_t)n, (uintmax_t)progress->total,
|
||||
tp);
|
||||
show_update = 1;
|
||||
}
|
||||
} else if (progress_update) {
|
||||
strbuf_reset(counters_sb);
|
||||
strbuf_addf(counters_sb, "%"PRIuMAX"%s", (uintmax_t)n, tp);
|
||||
show_update = 1;
|
||||
}
|
||||
|
||||
if (show_update) {
|
||||
if (is_foreground_fd(fileno(stderr)) || done) {
|
||||
fprintf(stderr, "%s: %"PRIuMAX"%s%s",
|
||||
progress->title, (uintmax_t)n, tp, eol);
|
||||
const char *eol = done ? done : "\r";
|
||||
size_t clear_len = counters_sb->len < last_count_len ?
|
||||
last_count_len - counters_sb->len + 1 :
|
||||
0;
|
||||
size_t progress_line_len = progress->title_len +
|
||||
counters_sb->len + 2;
|
||||
int cols = term_columns();
|
||||
|
||||
if (progress->split) {
|
||||
fprintf(stderr, " %s%*s", counters_sb->buf,
|
||||
(int) clear_len, eol);
|
||||
} else if (!done && cols < progress_line_len) {
|
||||
clear_len = progress->title_len + 1 < cols ?
|
||||
cols - progress->title_len : 0;
|
||||
fprintf(stderr, "%s:%*s\n %s%s",
|
||||
progress->title, (int) clear_len, "",
|
||||
counters_sb->buf, eol);
|
||||
progress->split = 1;
|
||||
} else {
|
||||
fprintf(stderr, "%s: %s%*s", progress->title,
|
||||
counters_sb->buf, (int) clear_len, eol);
|
||||
}
|
||||
fflush(stderr);
|
||||
}
|
||||
progress_update = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void throughput_string(struct strbuf *buf, uint64_t total,
|
||||
|
@ -189,9 +216,10 @@ void display_throughput(struct progress *progress, uint64_t total)
|
|||
display(progress, progress->last_value, NULL);
|
||||
}
|
||||
|
||||
int display_progress(struct progress *progress, uint64_t n)
|
||||
void display_progress(struct progress *progress, uint64_t n)
|
||||
{
|
||||
return progress ? display(progress, n, NULL) : 0;
|
||||
if (progress)
|
||||
display(progress, n, NULL);
|
||||
}
|
||||
|
||||
static struct progress *start_progress_delay(const char *title, uint64_t total,
|
||||
|
@ -212,6 +240,9 @@ static struct progress *start_progress_delay(const char *title, uint64_t total,
|
|||
progress->sparse = sparse;
|
||||
progress->throughput = NULL;
|
||||
progress->start_ns = getnanotime();
|
||||
strbuf_init(&progress->counters_sb, 0);
|
||||
progress->title_len = utf8_strwidth(title);
|
||||
progress->split = 0;
|
||||
set_progress_signal();
|
||||
return progress;
|
||||
}
|
||||
|
@ -285,6 +316,7 @@ void stop_progress_msg(struct progress **p_progress, const char *msg)
|
|||
free(buf);
|
||||
}
|
||||
clear_progress_signal();
|
||||
strbuf_release(&progress->counters_sb);
|
||||
if (progress->throughput)
|
||||
strbuf_release(&progress->throughput->display);
|
||||
free(progress->throughput);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
struct progress;
|
||||
|
||||
void display_throughput(struct progress *progress, uint64_t total);
|
||||
int display_progress(struct progress *progress, uint64_t n);
|
||||
void display_progress(struct progress *progress, uint64_t n);
|
||||
struct progress *start_progress(const char *title, uint64_t total);
|
||||
struct progress *start_sparse_progress(const char *title, uint64_t total);
|
||||
struct progress *start_delayed_progress(const char *title, uint64_t total);
|
||||
|
|
Загрузка…
Ссылка в новой задаче