Skip to content

Commit 425e51e

Browse files
committed
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
2 parents 32dc15d + 545dc34 commit 425e51e

File tree

2 files changed

+54
-22
lines changed

2 files changed

+54
-22
lines changed

progress.c

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
* published by the Free Software Foundation.
99
*/
1010

11-
#include "git-compat-util.h"
11+
#include "cache.h"
1212
#include "gettext.h"
1313
#include "progress.h"
1414
#include "strbuf.h"
1515
#include "trace.h"
16+
#include "utf8.h"
1617

1718
#define TP_IDX_MAX 8
1819

@@ -37,6 +38,9 @@ struct progress {
3738
unsigned sparse;
3839
struct throughput *throughput;
3940
uint64_t start_ns;
41+
struct strbuf counters_sb;
42+
int title_len;
43+
int split;
4044
};
4145

4246
static volatile sig_atomic_t progress_update;
@@ -79,41 +83,64 @@ static int is_foreground_fd(int fd)
7983
return tpgrp < 0 || tpgrp == getpgid(0);
8084
}
8185

82-
static int display(struct progress *progress, uint64_t n, const char *done)
86+
static void display(struct progress *progress, uint64_t n, const char *done)
8387
{
84-
const char *eol, *tp;
88+
const char *tp;
89+
struct strbuf *counters_sb = &progress->counters_sb;
90+
int show_update = 0;
91+
int last_count_len = counters_sb->len;
8592

8693
if (progress->delay && (!progress_update || --progress->delay))
87-
return 0;
94+
return;
8895

8996
progress->last_value = n;
9097
tp = (progress->throughput) ? progress->throughput->display.buf : "";
91-
eol = done ? done : " \r";
9298
if (progress->total) {
9399
unsigned percent = n * 100 / progress->total;
94100
if (percent != progress->last_percent || progress_update) {
95101
progress->last_percent = percent;
96-
if (is_foreground_fd(fileno(stderr)) || done) {
97-
fprintf(stderr, "%s: %3u%% (%"PRIuMAX"/%"PRIuMAX")%s%s",
98-
progress->title, percent,
99-
(uintmax_t)n, (uintmax_t)progress->total,
100-
tp, eol);
101-
fflush(stderr);
102-
}
103-
progress_update = 0;
104-
return 1;
102+
103+
strbuf_reset(counters_sb);
104+
strbuf_addf(counters_sb,
105+
"%3u%% (%"PRIuMAX"/%"PRIuMAX")%s", percent,
106+
(uintmax_t)n, (uintmax_t)progress->total,
107+
tp);
108+
show_update = 1;
105109
}
106110
} else if (progress_update) {
111+
strbuf_reset(counters_sb);
112+
strbuf_addf(counters_sb, "%"PRIuMAX"%s", (uintmax_t)n, tp);
113+
show_update = 1;
114+
}
115+
116+
if (show_update) {
107117
if (is_foreground_fd(fileno(stderr)) || done) {
108-
fprintf(stderr, "%s: %"PRIuMAX"%s%s",
109-
progress->title, (uintmax_t)n, tp, eol);
118+
const char *eol = done ? done : "\r";
119+
size_t clear_len = counters_sb->len < last_count_len ?
120+
last_count_len - counters_sb->len + 1 :
121+
0;
122+
size_t progress_line_len = progress->title_len +
123+
counters_sb->len + 2;
124+
int cols = term_columns();
125+
126+
if (progress->split) {
127+
fprintf(stderr, " %s%*s", counters_sb->buf,
128+
(int) clear_len, eol);
129+
} else if (!done && cols < progress_line_len) {
130+
clear_len = progress->title_len + 1 < cols ?
131+
cols - progress->title_len : 0;
132+
fprintf(stderr, "%s:%*s\n %s%s",
133+
progress->title, (int) clear_len, "",
134+
counters_sb->buf, eol);
135+
progress->split = 1;
136+
} else {
137+
fprintf(stderr, "%s: %s%*s", progress->title,
138+
counters_sb->buf, (int) clear_len, eol);
139+
}
110140
fflush(stderr);
111141
}
112142
progress_update = 0;
113-
return 1;
114143
}
115-
116-
return 0;
117144
}
118145

119146
static void throughput_string(struct strbuf *buf, uint64_t total,
@@ -189,9 +216,10 @@ void display_throughput(struct progress *progress, uint64_t total)
189216
display(progress, progress->last_value, NULL);
190217
}
191218

192-
int display_progress(struct progress *progress, uint64_t n)
219+
void display_progress(struct progress *progress, uint64_t n)
193220
{
194-
return progress ? display(progress, n, NULL) : 0;
221+
if (progress)
222+
display(progress, n, NULL);
195223
}
196224

197225
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,
212240
progress->sparse = sparse;
213241
progress->throughput = NULL;
214242
progress->start_ns = getnanotime();
243+
strbuf_init(&progress->counters_sb, 0);
244+
progress->title_len = utf8_strwidth(title);
245+
progress->split = 0;
215246
set_progress_signal();
216247
return progress;
217248
}
@@ -285,6 +316,7 @@ void stop_progress_msg(struct progress **p_progress, const char *msg)
285316
free(buf);
286317
}
287318
clear_progress_signal();
319+
strbuf_release(&progress->counters_sb);
288320
if (progress->throughput)
289321
strbuf_release(&progress->throughput->display);
290322
free(progress->throughput);

progress.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
struct progress;
55

66
void display_throughput(struct progress *progress, uint64_t total);
7-
int display_progress(struct progress *progress, uint64_t n);
7+
void display_progress(struct progress *progress, uint64_t n);
88
struct progress *start_progress(const char *title, uint64_t total);
99
struct progress *start_sparse_progress(const char *title, uint64_t total);
1010
struct progress *start_delayed_progress(const char *title, uint64_t total);

0 commit comments

Comments
 (0)