From ab4cd1d555115864c6b8fe4a9b443c272a51dcb9 Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Mon, 14 Oct 2024 20:53:29 +0200 Subject: [PATCH] Add Status::Refresh(int64_t cur_time_millis) method. Add a method to the abstract Status interface to refresh the status after some time has passed. Implement it properly in StatusPrinter. + Fix a bug in FormatProgressMessage() which ignored the value pass as argument (time_millis), and was using a member value instead (time_millis_). In practice, they were the same, but this is no longer true after this change. --- src/status.h | 7 +++++++ src/status_printer.cc | 33 ++++++++++++++++++++++----------- src/status_printer.h | 7 +++++++ 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/status.h b/src/status.h index 29db7c203a..40e4754841 100644 --- a/src/status.h +++ b/src/status.h @@ -34,6 +34,13 @@ struct Status { virtual void BuildStarted() = 0; virtual void BuildFinished() = 0; + /// Refresh status display after some time has passed. Useful + /// when printing the status on an interactive terminal. Does + /// nothing by default. \arg cur_time_millis is the current time + /// expressed in milliseconds, using the same epoch than the + /// one used in BuildEdgeStart() and BuildEdgeFinished(). + virtual void Refresh(int64_t cur_time_millis) {} + /// Set the Explanations instance to use to report explanations, /// argument can be nullptr if no explanations need to be printed /// (which is the default). diff --git a/src/status_printer.cc b/src/status_printer.cc index 8db6809561..80149da657 100644 --- a/src/status_printer.cc +++ b/src/status_printer.cc @@ -304,13 +304,13 @@ string StatusPrinter::FormatProgressStatus(const char* progress_status_format, // Overall finished edges per second. case 'o': - SnprintfRate(finished_edges_ / (time_millis_ / 1e3), buf, "%.1f"); + SnprintfRate(finished_edges_ / (time_millis / 1e3), buf, "%.1f"); out += buf; break; // Current rate, average over the last '-j' jobs. case 'c': - current_rate_.UpdateRate(finished_edges_, time_millis_); + current_rate_.UpdateRate(finished_edges_, time_millis); SnprintfRate(current_rate_.rate(), buf, "%.1f"); out += buf; break; @@ -336,15 +336,15 @@ string StatusPrinter::FormatProgressStatus(const char* progress_status_format, case 'E': // ETA, seconds case 'W': // ETA, human-readable { - double elapsed_sec = time_millis_ / 1e3; + double elapsed_sec = time_millis / 1e3; double eta_sec = -1; // To be printed as "?". if (time_predicted_percentage_ != 0.0) { - // So, we know that we've spent time_millis_ wall clock, + // So, we know that we've spent time_millis wall clock, // and that is time_predicted_percentage_ percent. // How much time will we need to complete 100%? - double total_wall_time = time_millis_ / time_predicted_percentage_; + double total_wall_time = time_millis / time_predicted_percentage_; // Naturally, that gives us the time remaining. - eta_sec = (total_wall_time - time_millis_) / 1e3; + eta_sec = (total_wall_time - time_millis) / 1e3; } const bool print_with_hours = @@ -428,17 +428,28 @@ void StatusPrinter::PrintStatus(const Edge* edge, int64_t time_millis) { bool force_full_command = config_.verbosity == BuildConfig::VERBOSE; - string to_print = edge->GetBinding("description"); - if (to_print.empty() || force_full_command) - to_print = edge->GetBinding("command"); + last_description_ = edge->GetBinding("description"); + if (last_description_.empty() || force_full_command) + last_description_ = edge->GetBinding("command"); - to_print = FormatProgressStatus(progress_status_format_, time_millis) - + to_print; + RefreshStatus(time_millis, force_full_command); +} +void StatusPrinter::RefreshStatus(int64_t cur_time_millis, + bool force_full_command) { + std::string to_print = + FormatProgressStatus(progress_status_format_, cur_time_millis) + + last_description_; printer_.Print(to_print, force_full_command ? LinePrinter::FULL : LinePrinter::ELIDE); } +void StatusPrinter::Refresh(int64_t cur_time_millis) { + if (printer_.is_smart_terminal()) { + RefreshStatus(cur_time_millis, false); + } +} + void StatusPrinter::Warning(const char* msg, ...) { va_list ap; va_start(ap, msg); diff --git a/src/status_printer.h b/src/status_printer.h index 08a8d1a93d..b9e601b09f 100644 --- a/src/status_printer.h +++ b/src/status_printer.h @@ -36,6 +36,8 @@ struct StatusPrinter : Status { void BuildStarted() override; void BuildFinished() override; + void Refresh(int64_t cur_time_millis) override; + void Info(const char* msg, ...) override; void Warning(const char* msg, ...) override; void Error(const char* msg, ...) override; @@ -82,6 +84,8 @@ struct StatusPrinter : Status { /// For how many edges we don't know the previous run time? int eta_unpredictable_edges_remaining_ = 0; + void RefreshStatus(int64_t cur_time_millis, bool force_full_command); + void RecalculateProgressPrediction(); /// Prints progress output. @@ -93,6 +97,9 @@ struct StatusPrinter : Status { /// The custom progress status format to use. const char* progress_status_format_; + /// Last command's description or command-line. + std::string last_description_; + template void SnprintfRate(double rate, char (&buf)[S], const char* format) const { if (rate == -1)