Skip to content

Commit 1e36f20

Browse files
committed
Fix issues with std::filesystem::path settings
1 parent 37cf990 commit 1e36f20

File tree

4 files changed

+34
-12
lines changed

4 files changed

+34
-12
lines changed

src/libutil/configuration.cc

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,18 @@ std::string BaseSetting<StringMap>::to_string() const
433433
[](const auto & kvpair) { return kvpair.first + "=" + kvpair.second; });
434434
}
435435

436+
static Path parsePath(const AbstractSetting & s, const std::string & str)
437+
{
438+
if (str == "")
439+
throw UsageError("setting '%s' is a path and paths cannot be empty", s.name);
440+
else
441+
return canonPath(str);
442+
}
443+
436444
template<>
437445
std::filesystem::path BaseSetting<std::filesystem::path>::parse(const std::string & str) const
438446
{
439-
return std::filesystem::path(str).lexically_normal();
447+
return parsePath(*this, str);
440448
}
441449

442450
template<>
@@ -445,6 +453,22 @@ std::string BaseSetting<std::filesystem::path>::to_string() const
445453
return value.string();
446454
}
447455

456+
template<>
457+
std::optional<std::filesystem::path>
458+
BaseSetting<std::optional<std::filesystem::path>>::parse(const std::string & str) const
459+
{
460+
if (str == "")
461+
return std::nullopt;
462+
else
463+
return parsePath(*this, str);
464+
}
465+
466+
template<>
467+
std::string BaseSetting<std::optional<std::filesystem::path>>::to_string() const
468+
{
469+
return value ? value->string() : "";
470+
}
471+
448472
template class BaseSetting<int>;
449473
template class BaseSetting<unsigned int>;
450474
template class BaseSetting<long>;
@@ -458,14 +482,7 @@ template class BaseSetting<StringSet>;
458482
template class BaseSetting<StringMap>;
459483
template class BaseSetting<std::set<ExperimentalFeature>>;
460484
template class BaseSetting<std::filesystem::path>;
461-
462-
static Path parsePath(const AbstractSetting & s, const std::string & str)
463-
{
464-
if (str == "")
465-
throw UsageError("setting '%s' is a path and paths cannot be empty", s.name);
466-
else
467-
return canonPath(str);
468-
}
485+
template class BaseSetting<std::optional<std::filesystem::path>>;
469486

470487
PathSetting::PathSetting(
471488
Config * options,

src/libutil/include/nix/util/file-path.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "nix/util/types.hh"
77
#include "nix/util/os-string.hh"
8+
#include "nix/util/json-non-null.hh"
89

910
namespace nix {
1011

@@ -53,4 +54,8 @@ std::optional<std::filesystem::path> maybePath(PathView path);
5354

5455
std::filesystem::path pathNG(PathView path);
5556

57+
template<>
58+
struct json_avoids_null<std::filesystem::path> : std::true_type
59+
{};
60+
5661
} // namespace nix

src/libutil/include/nix/util/logging.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct LoggerSettings : Config
5454
expression evaluation errors.
5555
)"};
5656

57-
Setting<std::filesystem::path> jsonLogPath{
57+
Setting<std::optional<std::filesystem::path>> jsonLogPath{
5858
this,
5959
{},
6060
"json-log-path",

src/libutil/logging.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,10 +367,10 @@ std::unique_ptr<Logger> makeJSONLogger(const std::filesystem::path & path, bool
367367

368368
void applyJSONLogger()
369369
{
370-
if (!loggerSettings.jsonLogPath.get().empty()) {
370+
if (auto & opt = loggerSettings.jsonLogPath.get()) {
371371
try {
372372
std::vector<std::unique_ptr<Logger>> loggers;
373-
loggers.push_back(makeJSONLogger(loggerSettings.jsonLogPath.get(), false));
373+
loggers.push_back(makeJSONLogger(*opt, false));
374374
try {
375375
logger = makeTeeLogger(std::move(logger), std::move(loggers));
376376
} catch (...) {

0 commit comments

Comments
 (0)