Skip to content

Commit e7a9b4b

Browse files
committed
ui: one line per download -- the completion line only, with its size and time, in both modes (#734)
Output that is not a terminal printed a start line and a completion line for every item; it now prints the completion line (or the line saying the item did not complete). A terminal redraws the bar in place, as before, and ends it with the same completion line, which now states the size and the time.
1 parent 2420a1f commit e7a9b4b

3 files changed

Lines changed: 26 additions & 19 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ SPEC-007 §9 与新的 SPEC-008。配套的 mcpp-plugins 0.17.0 以本版本为
3131
- **快路径看见 path 依赖的整棵源码树。** 此前只扫描依赖的 `src/`;依赖在别处的 host module
3232
(例如 mcpp-plugins 的 `deps/vcpkg.cppm`)编入消费方的构建程序,不在任何 ninja 边上,被编辑后
3333
构建报告"无事可做"。现在扫描依赖的整棵树,跳过隐藏目录、`target` 与嵌套的包(e2e 831)。
34+
- **每个下载只占一行。** 非终端输出此前在开始时写一行 `Downloading <item> (<size>)`,完成时再写一行
35+
`... done, <size> in <time>`;现在只写完成的一行,失败时写 `did not complete` 的一行。终端上进度条
36+
原地刷新,结束时换成同样带大小与耗时的完成行。
3437
- **MSVC ABI 上的 clang 找不到工具集时说明原因。** 默认的 `msvc@system` 在没有带 C++ 工具的
3538
Visual Studio 实例时,此前静默继续,随后在预编译 `mcpp` 模块时以 `'cstdio' file not found` 失败;
3639
现在解析时给出警告,写出安装与指定托管工具集的命令(在屏蔽 Visual Studio 的 runner 上测得)。

‎src/ui.cppm‎

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,12 @@ private:
149149
void render_line(std::size_t percent, const std::string& info_text);
150150
void render_line_swept(std::size_t frame, const std::string& info_text);
151151

152-
// Not a terminal: one start line, then one finish line.
152+
// One line per item in both modes (#734): a terminal redraws it in place
153+
// and ends it with the completion line; elsewhere only the completion
154+
// line is printed. `announce` records the size without printing.
153155
void announce(std::size_t total_bytes);
154156
void finish_plain(std::string_view final_message);
157+
std::string completion(std::string_view final_message) const;
155158

156159
std::string verb_;
157160
std::string label_;
@@ -608,20 +611,19 @@ ProgressBar::ProgressBar(std::string_view verb, std::string_view label)
608611
void ProgressBar::announce(std::size_t total_bytes) {
609612
if (announced_) return;
610613
announced_ = true;
611-
if (total_bytes > 0)
612-
info(verb_, std::format("{} ({})", label_, fmt_bytes(total_bytes)));
613-
else
614-
info(verb_, label_);
614+
if (total_bytes > lastBytes_) lastBytes_ = total_bytes;
615615
}
616616

617-
void ProgressBar::finish_plain(std::string_view final_message) {
617+
std::string ProgressBar::completion(std::string_view final_message) const {
618618
const auto secs = std::chrono::duration<double>(
619619
std::chrono::steady_clock::now() - start_).count();
620620
if (lastBytes_ > 0)
621-
info(verb_, std::format("{} done, {} in {:.1f}s", final_message,
622-
fmt_bytes(lastBytes_), secs));
623-
else
624-
info(verb_, std::format("{} done in {:.1f}s", final_message, secs));
621+
return std::format("{} done, {} in {:.1f}s", final_message, fmt_bytes(lastBytes_), secs);
622+
return std::format("{} done in {:.1f}s", final_message, secs);
623+
}
624+
625+
void ProgressBar::finish_plain(std::string_view final_message) {
626+
info(verb_, completion(final_message));
625627
}
626628

627629
ProgressBar::~ProgressBar() {
@@ -672,7 +674,8 @@ void ProgressBar::update(std::size_t percent) {
672674
void ProgressBar::update_bytes(std::size_t current, std::size_t total,
673675
double elapsed_sec) {
674676
if (g_quiet || finished_) return;
675-
if (!live_progress()) { announce(total); lastBytes_ = current; return; }
677+
if (!live_progress()) { announce(total); if (current > lastBytes_) lastBytes_ = current; return; }
678+
if (current > lastBytes_) lastBytes_ = current;
676679
auto now = std::chrono::steady_clock::now();
677680
auto pct = total ? (current * 100 / total) : 0;
678681
if (pct > 100) pct = 100;
@@ -696,6 +699,7 @@ void ProgressBar::update_indeterminate(std::size_t current_bytes,
696699
double elapsed_sec) {
697700
if (g_quiet || finished_) return;
698701
if (!live_progress()) { announce(0); lastBytes_ = current_bytes; return; }
702+
lastBytes_ = current_bytes;
699703
auto now = std::chrono::steady_clock::now();
700704
// Same ~80ms throttle as update_bytes(); there is no "100%" early-out here
701705
// because there is no known total.
@@ -723,9 +727,9 @@ void ProgressBar::finish() {
723727
finish_plain(label_);
724728
return;
725729
}
726-
// Clear the line and re-emit as a static info line.
730+
// Clear the line and re-emit it as the completion line.
727731
std::print("\r\033[2K");
728-
info(verb_, label_);
732+
info(verb_, completion(label_));
729733
}
730734

731735
void ProgressBar::finish_with(std::string_view final_message) {
@@ -738,7 +742,7 @@ void ProgressBar::finish_with(std::string_view final_message) {
738742
return;
739743
}
740744
std::print("\r\033[2K");
741-
info(verb_, final_message);
745+
info(verb_, completion(final_message));
742746
}
743747

744748
void ProgressBar::finish_failed(std::string_view final_message) {

‎tests/unit/test_progress_render.cpp‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import mcpp.fetcher.progress;
66
import mcpp.platform.process;
77

88
// W11: one renderer for every acquisition, with a terminal mode (redrawn in
9-
// place) and a plain mode (one start line and one finish line per item).
9+
// place) and a plain mode; either prints one line per item (#734).
1010

1111
TEST(GitProgress, ParsesThePhaseAndThePercentage) {
1212
auto r = mcpp::fetcher::parse_git_progress(
@@ -25,7 +25,7 @@ TEST(GitProgress, ParsesThePhaseAndThePercentage) {
2525
EXPECT_FALSE(mcpp::fetcher::parse_git_progress("").has_value());
2626
}
2727

28-
TEST(ProgressBarPlain, OneStartLineAndOneFinishLineWithoutRepaints) {
28+
TEST(ProgressBarPlain, OneCompletionLineWithoutRepaints) {
2929
mcpp::ui::disable_color();
3030
mcpp::ui::set_live_progress(false);
3131
testing::internal::CaptureStdout();
@@ -39,9 +39,9 @@ TEST(ProgressBarPlain, OneStartLineAndOneFinishLineWithoutRepaints) {
3939
auto out = testing::internal::GetCapturedStdout();
4040
EXPECT_EQ(out.find('\r'), std::string::npos) << out;
4141
EXPECT_EQ(out.find('\x1b'), std::string::npos) << out;
42-
EXPECT_EQ(std::ranges::count(out, '\n'), 2) << out;
43-
EXPECT_NE(out.find("Fetching example ("), std::string::npos) << out;
44-
EXPECT_NE(out.find("done"), std::string::npos) << out;
42+
// #734: one line per item, stating the size and the time.
43+
EXPECT_EQ(std::ranges::count(out, '\n'), 1) << out;
44+
EXPECT_NE(out.find("Fetching example done, 100 B in"), std::string::npos) << out;
4545
}
4646

4747
TEST(ProgressBarPlain, AFailedItemIsNotReportedDone) {

0 commit comments

Comments
 (0)