Skip to content

libutil: Add PathFmt wrapped type for formatting fs::path, fix all double-quoting issues#15030

Merged
Ericson2314 merged 2 commits intoNixOS:masterfrom
xokdvium:path-fmt-squash-double-quotes
Jan 21, 2026
Merged

libutil: Add PathFmt wrapped type for formatting fs::path, fix all double-quoting issues#15030
Ericson2314 merged 2 commits intoNixOS:masterfrom
xokdvium:path-fmt-squash-double-quotes

Conversation

@xokdvium
Copy link
Contributor

Motivation

This will once and for all get rid of all double-quoting issues. On windows the quoting
is doubly bad because it escaped all \ to \, which is very bad for error messages. In
order to prevent future regressions of std::filesystem::path formatting now must use a special
type PathFmt (like Magenta). In the future we could even change how we render filesystem paths.

Context


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

@github-actions github-actions bot added new-cli Relating to the "nix" command store Issues and pull requests concerning the Nix store repl The Read Eval Print Loop, "nix repl" command and debugger fetching Networking with the outside (non-Nix) world, input locking labels Jan 21, 2026
@xokdvium xokdvium force-pushed the path-fmt-squash-double-quotes branch from 303f27d to ffc9a41 Compare January 21, 2026 02:37
createOutLinksMaybe(buildables, store);

logger->cout("%s", app.program);
logger->cout("%s", app.program.string());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a regression in 2.33. @Ericson2314

script += fmt("SHELL=\"%s\"\n", shell);
if (foundInteractive)
script += fmt("PATH=\"%s${PATH:+:$PATH}\"\n", std::filesystem::path(shell).parent_path());
script += fmt("PATH=\"%s${PATH:+:$PATH}\"\n", std::filesystem::path(shell).parent_path().string());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also a regression

std::cout << "Additional system types: " << concatStringsSep(", ", settings.extraPlatforms.get()) << "\n";
std::cout << "Features: " << concatStringsSep(", ", cfg) << "\n";
std::cout << "System configuration file: " << (settings.nixConfDir / "nix.conf") << "\n";
std::cout << "System configuration file: " << (settings.nixConfDir / "nix.conf").string() << "\n";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A regression in 2.33 too

auto rootCgroupPath = *cgroupFS / getRootCgroup().rel();
if (!pathExists(rootCgroupPath))
throw Error("expected cgroup directory '%s'", rootCgroupPath);
throw Error("expected cgroup directory %s", PathFmt(rootCgroupPath));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double quotes

execv(buildHook.native().c_str(), stringsToCharPtrs(args).data());

throw SysError("executing '%s'", buildHook);
throw SysError("executing %s", PathFmt(buildHook));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also double quotes

…uble-quoting issues

This will once and for all get rid of all double-quoting issues. On windows the quoting
is doubly bad because it escaped all \ to \\, which is very bad for error messages. In
order to prevent future regression std::filesystem::path formatting now must use a special
type PathFmt (like Magenta). In the future we could even change how we render filesystem paths.
@xokdvium xokdvium force-pushed the path-fmt-squash-double-quotes branch from ffc9a41 to 6dd89b5 Compare January 21, 2026 03:06
@github-actions github-actions bot added the with-tests Issues related to testing. PRs with tests have some priority label Jan 21, 2026
@Ericson2314 Ericson2314 added this pull request to the merge queue Jan 21, 2026
Merged via the queue into NixOS:master with commit c6d07ec Jan 21, 2026
14 checks passed
@edolstra
Copy link
Member

Can't we do this automatically, without the PathFmt wrapper? I.e. just change the default formatting for paths to not include the quotes?

@xokdvium
Copy link
Contributor Author

I.e. just change the default formatting for paths to not include the quotes?

That could be an option. Ideally and eventually when strings are eradicated as paths we'd just have an overload for operator% that does the quoting for us.

But considering just how many silent regressions it causes I think it's only logical to force compilation errors when not explicit. That necessarily forces changes to call sites to update all of the quoting – as is the intention. Evidence shows that we step into this footgun time and time again, so requiring changes is better than having more silent regressions.

@edolstra
Copy link
Member

Yeah but my point is that if we change the default formatting to not include quotes, then we don't have this footgun anymore. It will behave like every other type (in particular Path).

@mightyiam
Copy link

Thank you for fixing. Here's a silly workaround in the meantime:
mightyiam/infra@7683b5b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fetching Networking with the outside (non-Nix) world, input locking new-cli Relating to the "nix" command repl The Read Eval Print Loop, "nix repl" command and debugger store Issues and pull requests concerning the Nix store with-tests Issues related to testing. PRs with tests have some priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants