From 93c51acfb5cdc28c4a44cc2ad86359b2b14528f0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 24 Nov 2025 14:04:50 +0100 Subject: [PATCH 1/3] Add Setting specialization Like PathSetting, this normalizes the path (without resolving symlinks). --- src/libutil/configuration.cc | 13 +++++++++++++ src/libutil/include/nix/util/config-impl.hh | 1 + src/libutil/include/nix/util/logging.hh | 4 ++-- src/libutil/logging.cc | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/libutil/configuration.cc b/src/libutil/configuration.cc index 7a0ed22ea..e520a6e38 100644 --- a/src/libutil/configuration.cc +++ b/src/libutil/configuration.cc @@ -433,6 +433,18 @@ std::string BaseSetting::to_string() const [](const auto & kvpair) { return kvpair.first + "=" + kvpair.second; }); } +template<> +std::filesystem::path BaseSetting::parse(const std::string & str) const +{ + return std::filesystem::path(str).lexically_normal(); +} + +template<> +std::string BaseSetting::to_string() const +{ + return value.string(); +} + template class BaseSetting; template class BaseSetting; template class BaseSetting; @@ -445,6 +457,7 @@ template class BaseSetting; template class BaseSetting; template class BaseSetting; template class BaseSetting>; +template class BaseSetting; static Path parsePath(const AbstractSetting & s, const std::string & str) { diff --git a/src/libutil/include/nix/util/config-impl.hh b/src/libutil/include/nix/util/config-impl.hh index f407bc862..6066765c5 100644 --- a/src/libutil/include/nix/util/config-impl.hh +++ b/src/libutil/include/nix/util/config-impl.hh @@ -134,6 +134,7 @@ DECLARE_CONFIG_SERIALISER(Strings) DECLARE_CONFIG_SERIALISER(StringSet) DECLARE_CONFIG_SERIALISER(StringMap) DECLARE_CONFIG_SERIALISER(std::set) +DECLARE_CONFIG_SERIALISER(std::filesystem::path) template T BaseSetting::parse(const std::string & str) const diff --git a/src/libutil/include/nix/util/logging.hh b/src/libutil/include/nix/util/logging.hh index 500d443e6..ec107304b 100644 --- a/src/libutil/include/nix/util/logging.hh +++ b/src/libutil/include/nix/util/logging.hh @@ -54,9 +54,9 @@ struct LoggerSettings : Config expression evaluation errors. )"}; - Setting jsonLogPath{ + Setting jsonLogPath{ this, - "", + {}, "json-log-path", R"( A file or unix socket to which JSON records of Nix's log output are diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index e2f28f553..48dc9e069 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -370,7 +370,7 @@ void applyJSONLogger() if (!loggerSettings.jsonLogPath.get().empty()) { try { std::vector> loggers; - loggers.push_back(makeJSONLogger(std::filesystem::path(loggerSettings.jsonLogPath.get()), false)); + loggers.push_back(makeJSONLogger(loggerSettings.jsonLogPath.get(), false)); try { logger = makeTeeLogger(std::move(logger), std::move(loggers)); } catch (...) { From 1e36f203e6b08c843190fb2b9f7ba1808069d4ec Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 26 Nov 2025 18:16:10 -0500 Subject: [PATCH 2/3] Fix issues with `std::filesystem::path` settings --- src/libutil/configuration.cc | 35 +++++++++++++++++------ src/libutil/include/nix/util/file-path.hh | 5 ++++ src/libutil/include/nix/util/logging.hh | 2 +- src/libutil/logging.cc | 4 +-- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/libutil/configuration.cc b/src/libutil/configuration.cc index e520a6e38..ee24bb4e5 100644 --- a/src/libutil/configuration.cc +++ b/src/libutil/configuration.cc @@ -433,10 +433,18 @@ std::string BaseSetting::to_string() const [](const auto & kvpair) { return kvpair.first + "=" + kvpair.second; }); } +static Path parsePath(const AbstractSetting & s, const std::string & str) +{ + if (str == "") + throw UsageError("setting '%s' is a path and paths cannot be empty", s.name); + else + return canonPath(str); +} + template<> std::filesystem::path BaseSetting::parse(const std::string & str) const { - return std::filesystem::path(str).lexically_normal(); + return parsePath(*this, str); } template<> @@ -445,6 +453,22 @@ std::string BaseSetting::to_string() const return value.string(); } +template<> +std::optional +BaseSetting>::parse(const std::string & str) const +{ + if (str == "") + return std::nullopt; + else + return parsePath(*this, str); +} + +template<> +std::string BaseSetting>::to_string() const +{ + return value ? value->string() : ""; +} + template class BaseSetting; template class BaseSetting; template class BaseSetting; @@ -458,14 +482,7 @@ template class BaseSetting; template class BaseSetting; template class BaseSetting>; template class BaseSetting; - -static Path parsePath(const AbstractSetting & s, const std::string & str) -{ - if (str == "") - throw UsageError("setting '%s' is a path and paths cannot be empty", s.name); - else - return canonPath(str); -} +template class BaseSetting>; PathSetting::PathSetting( Config * options, diff --git a/src/libutil/include/nix/util/file-path.hh b/src/libutil/include/nix/util/file-path.hh index 25349eaf7..52dae32ff 100644 --- a/src/libutil/include/nix/util/file-path.hh +++ b/src/libutil/include/nix/util/file-path.hh @@ -5,6 +5,7 @@ #include "nix/util/types.hh" #include "nix/util/os-string.hh" +#include "nix/util/json-non-null.hh" namespace nix { @@ -53,4 +54,8 @@ std::optional maybePath(PathView path); std::filesystem::path pathNG(PathView path); +template<> +struct json_avoids_null : std::true_type +{}; + } // namespace nix diff --git a/src/libutil/include/nix/util/logging.hh b/src/libutil/include/nix/util/logging.hh index ec107304b..4673895aa 100644 --- a/src/libutil/include/nix/util/logging.hh +++ b/src/libutil/include/nix/util/logging.hh @@ -54,7 +54,7 @@ struct LoggerSettings : Config expression evaluation errors. )"}; - Setting jsonLogPath{ + Setting> jsonLogPath{ this, {}, "json-log-path", diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index 48dc9e069..8f7ec2d29 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -367,10 +367,10 @@ std::unique_ptr makeJSONLogger(const std::filesystem::path & path, bool void applyJSONLogger() { - if (!loggerSettings.jsonLogPath.get().empty()) { + if (auto & opt = loggerSettings.jsonLogPath.get()) { try { std::vector> loggers; - loggers.push_back(makeJSONLogger(loggerSettings.jsonLogPath.get(), false)); + loggers.push_back(makeJSONLogger(*opt, false)); try { logger = makeTeeLogger(std::move(logger), std::move(loggers)); } catch (...) { From 80c545bcdcdf1dedcb31540d7b9a9d786dd57f5d Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 26 Nov 2025 18:43:32 -0500 Subject: [PATCH 3/3] Fix include errors masked by precompiled headers --- src/libutil/include/nix/util/config-impl.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libutil/include/nix/util/config-impl.hh b/src/libutil/include/nix/util/config-impl.hh index 6066765c5..8f6f9a358 100644 --- a/src/libutil/include/nix/util/config-impl.hh +++ b/src/libutil/include/nix/util/config-impl.hh @@ -16,6 +16,7 @@ #include "nix/util/configuration.hh" #include "nix/util/args.hh" #include "nix/util/logging.hh" +#include "nix/util/file-path.hh" namespace nix { @@ -135,6 +136,7 @@ DECLARE_CONFIG_SERIALISER(StringSet) DECLARE_CONFIG_SERIALISER(StringMap) DECLARE_CONFIG_SERIALISER(std::set) DECLARE_CONFIG_SERIALISER(std::filesystem::path) +DECLARE_CONFIG_SERIALISER(std::optional) template T BaseSetting::parse(const std::string & str) const