-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check progress status format string validity first and fall back to default if it's invalid #2496
base: master
Are you sure you want to change the base?
Conversation
I don't think it's necessary to make a new function for this... there should be a simple way to do it |
I agree that it's a clunky way to do it. Would it make more sense to add a boolean out parameter to progress_status_format_ = getenv("NINJA_STATUS");
bool is_format_valid = true;
FormatProgressStatus(progress_status_format_, 0, &is_format_valid)
if (!progress_status_format_ || !is_format_valid)
progress_status_format_ = "[%f/%t] "; |
virtual void Info(const char* msg, ...) = 0; | ||
virtual void Warning(const char* msg, ...) = 0; | ||
virtual void Error(const char* msg, ...) = 0; | ||
virtual void Info(const char* msg, ...) const = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are unrelated changes, they are useful but please move them to their own commit instead. Thanks.
src/status_printer.h
Outdated
void Warning(const char* msg, ...) const override; | ||
void Error(const char* msg, ...) const override; | ||
|
||
bool IsValidProgressStatus(const char* progress_status_format) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Please make this method static.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, document it properly and make it return an error string, instead of calling Warning(), i.e. let the caller decide what to do, e.g.:
/// Validate the status format string passed as an argument to verify it only contains
/// valid escape sequences. On success return true, on failure, return false and sets \arg error.
static bool IsValidProgressStatusFormat(const char* status_format, std::string* err);
src/build_test.cc
Outdated
EXPECT_FALSE(status_.IsValidProgressStatus("[%f/%X] ")); | ||
EXPECT_EQ("", status_.FormatProgressStatus("[%f/%X] ", 0)); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would make more sense to move this to a new status_printer_test.cc
file.
e75fabb
to
5406a36
Compare
I have not looked deeper into this but at first glance, the goal should be able to be achieved with less than 10 lines changed... I don't understand how we are passing 100 lines... Find the Fatal() call, turn it into a Warning(), and then set the format value. am I wrong? |
@digit-google would it be acceptable to make |
src/status_printer.cc
Outdated
@@ -49,8 +49,14 @@ StatusPrinter::StatusPrinter(const BuildConfig& config) | |||
printer_.set_smart_terminal(false); | |||
|
|||
progress_status_format_ = getenv("NINJA_STATUS"); | |||
if (!progress_status_format_) | |||
|
|||
string error_output; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use std::string
as we are trying to remove using namespace std
from the sources gradually.
progress_status_format_ = "[%f/%t] "; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: For clarity use two conditions and a common variable such as:
std::string error;
if (progress_status_format_ && !IsValidProgressStatus(progress_status_format_, &error)) {
Warning("%s", error.c_str());
progress_status_format_ = nullptr;
}
if (!progress_status_format_) {
// Enforce default value if unspecified or invalid.
progress_status_format_ = kDefaultStatusFormat;
}
@@ -2258,47 +2258,6 @@ TEST_F(BuildTest, DepsGccWithEmptyDepfileErrorsOut) { | |||
ASSERT_EQ(1u, command_runner_.commands_ran_.size()); | |||
} | |||
|
|||
TEST_F(BuildTest, StatusFormatElapsed_e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good, but can you put this commit before the previous one, this will make the addition of BuildTest.StatusFormatValidator
clearer.
@mcprat, to be honest, I don't think it would be a good idea here. A formatting function that changes the state of its object is always confusing for the reader. Also a single validation function that is called once before anything heavy work is done is very simple to understand. |
5406a36
to
7749393
Compare
src/status_printer.h
Outdated
const char* progress_status_format_ = nullptr; | ||
|
||
/// The progress status format to use by default | ||
static constexpr const char* kDefaultProgressStatusFormat = "[%f/%t] "; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: static constexpr
members need a definition in the corresponding .cc file or some compilers will complain that it is missing (especially when compiling with -O0
). In this case you can simply add constexpr const char* StatusPrinter::kDefaultProgressStatusFormat;
(with no value) to status_printer.cc
.
However, we do not need to expose the value publicly, so for simplicity, just define it as a const variable in the constructor that uses it.
Also const char kName[] = "..."
is preferable to static const char* kName = "..."
because the latter introduces an unnecessary relocation in the generated code / data segment.
StatusPrinter::StatusPrinter(...) {
...
const char kDefaultProgressStatusFormat[] = "[%f/%t] ";
...
}
Sorry for the nitpicks, this is a great PR :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's no problem at all, this is great feedback. :)
7749393
to
57f6ed5
Compare
@jhasse @digit-google Any chance that this will get merged? |
The code LGTM as-is, though I would appreciate if you could address the latest review commits. I'll let @jhasse decide on the merge itself :) |
In my opinion it shouldn't be fatal if the progress format string configured with
$NINJA_STATUS
is invalid. Especially now that we have placeholders that have only been available since Ninja 1.12.This PR therefore changes the way the progress status format string is validated, so that it is checked in the
StatusPrinter
constructor, and if it's invalid the default"[%f/%t] "
format is used instead. It also adds a small unit test to ensure this functionality.