Skip to content

Commit

Permalink
Convert --log-format CLI argument to setting
Browse files Browse the repository at this point in the history
  • Loading branch information
9999years committed Feb 9, 2024
1 parent 21d7203 commit 4c35ede
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 21 deletions.
8 changes: 0 additions & 8 deletions src/libmain/common-args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,6 @@ MixCommonArgs::MixCommonArgs(const std::string & programName)
}
});

addFlag({
.longName = "log-format",
.description = "Set the format of log output; one of `raw`, `internal-json`, `bar` or `bar-with-logs`.",
.category = loggingCategory,
.labels = {"format"},
.handler = {[](std::string format) { setLogFormat(format); }},
});

addFlag({
.longName = "max-jobs",
.shortName = 'j',
Expand Down
2 changes: 1 addition & 1 deletion src/libmain/shared.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ LegacyArgs::LegacyArgs(const std::string & programName,
.longName = "no-build-output",
.shortName = 'Q',
.description = "Do not show build output.",
.handler = {[&]() {setLogFormat(LogFormat::raw); }},
.handler = {[&]() {loggerSettings.logFormat.assign(LogFormat::raw); }},
});

addFlag({
Expand Down
56 changes: 56 additions & 0 deletions src/libutil/config-impl.hh
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,60 @@ std::string Setting<T>::to_string() const
return std::to_string(value);
}

template<>
LogFormat Setting<LogFormat>::parse(const std::string & str) const
{
auto format = parseLogFormat(str);
if (format.has_value()) {
return format.value();
} else {
throw UsageError("setting '%s' has invalid value '%s'", name, str);
}
}

template<>
std::string Setting<LogFormat>::to_string() const
{
return logFormatToString(value);
}

template<>
void Setting<LogFormat>::convertToArg(Args &args, const std::string &category)
{
args.addFlag({
.longName = name,
.description = fmt("Set the `%s` setting.", name),
.category = category,
.labels = {"format"},
.handler = {[this](std::string format) { override(parse(format)); }},
.experimentalFeature = experimentalFeature,
});
}

template<>
std::optional<LogFormat> Setting<std::optional<LogFormat>>::parse(const std::string & str) const
{
if (str.empty()) {
return std::nullopt;
}

auto format = parseLogFormat(str);
if (format.has_value()) {
return format.value();
} else {
throw UsageError("setting '%s' has invalid value '%s'", name, str);
}
}

template<>
std::string Setting<std::optional<LogFormat>>::to_string() const
{
if (value.has_value()) {
return logFormatToString(value.value());
} else {
// TODO: Will returning the empty string here cause problems?
return "";
}
}

}
2 changes: 2 additions & 0 deletions src/libutil/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ template class Setting<Strings>;
template class Setting<StringSet>;
template class Setting<StringMap>;
template class Setting<std::set<ExperimentalFeature>>;
template class Setting<LogFormat>;
template class Setting<std::optional<LogFormat>>;

static Path parsePath(const AbstractSetting & s, const std::string & str)
{
Expand Down
4 changes: 4 additions & 0 deletions src/libutil/json-utils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ struct json_avoids_null<std::list<T>> : std::true_type {};
template<typename K, typename V>
struct json_avoids_null<std::map<K, V>> : std::true_type {};

enum class LogFormat;
template<>
struct json_avoids_null<LogFormat> : std::true_type {};

}

namespace nlohmann {
Expand Down
20 changes: 20 additions & 0 deletions src/libutil/logging.hh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,26 @@ struct LoggerSettings : Config
Whether Nix should print out a stack trace in case of Nix
expression evaluation errors.
)"};

Setting<LogFormat> logFormat{
this, LogFormat::raw, "log-format",
R"(
The log format to use.
One of `raw`, `raw-with-logs`, `internal-json`, `bar`, or `bar-with-logs`.
)",
{},
false,
std::nullopt,
{[](const LogFormat & value) {
setLogFormat(value);
}}};

Setting<std::optional<LogFormat>> logFormatLegacy{
this, std::nullopt, "log-format-legacy",
R"(
The log format to use for legacy commands like `nix-build` and `nix-shell`.
One of `raw`, `raw-with-logs`, `internal-json`, `bar`, or `bar-with-logs`.
)"};
};

extern LoggerSettings loggerSettings;
Expand Down
37 changes: 25 additions & 12 deletions src/nix/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,22 @@ void mainWrapped(int argc, char * * argv)
return;
}

programPath = argv[0];
auto programName = std::string(baseNameOf(programPath));
auto legacy = (*RegisterLegacyCommand::commands)[programName];

if (!legacy) {
// New-style commands default to `bar` logs.
// `initNix()` reads configuration files and will override this setting
// if it's set.
loggerSettings.logFormat.assign(LogFormat::bar);
}

if (argc > 1 && std::string_view(argv[1]) == "__build-remote") {
programName = "build-remote";
argv++; argc--;
}

initNix();
initGC();

Expand All @@ -337,22 +353,19 @@ void mainWrapped(int argc, char * * argv)

Finally f([] { logger->stop(); });

programPath = argv[0];
auto programName = std::string(baseNameOf(programPath));

if (argc > 1 && std::string_view(argv[1]) == "__build-remote") {
programName = "build-remote";
argv++; argc--;
}

{
auto legacy = (*RegisterLegacyCommand::commands)[programName];
if (legacy) return legacy(argc, argv);
if (legacy) {
// If we're in a legacy command and `logFormatLegacy` has a value, use
// that for the log format setting.
if (loggerSettings.logFormatLegacy.get().has_value()) {
loggerSettings.logFormat.assign(
loggerSettings.logFormatLegacy.get().value()
);
}
return legacy(argc, argv);
}

evalSettings.pureEval = true;

setLogFormat("bar");
settings.verboseBuild = false;
if (isatty(STDERR_FILENO)) {
verbosity = lvlNotice;
Expand Down

0 comments on commit 4c35ede

Please sign in to comment.