1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-26 15:51:15 +02:00

Support Windows paths in canonPath and absPath

`canonPath` and `absPath` work on native paths, and so should switch
between supporting Unix paths and Windows paths accordingly.

The templating is because `CanonPath`, which shares the implementation,
should always be Unix style. It is the pure "nix-native" path type for
virtual file operations --- it is part of Nix's "business logic", and
should not vary with the host OS accordingly.
This commit is contained in:
John Ericson 2024-01-14 14:30:25 -05:00
parent 4531585275
commit 319ec6f84a
3 changed files with 94 additions and 14 deletions

View file

@ -22,10 +22,14 @@ namespace fs = std::filesystem;
namespace nix {
/** Treat the string as possibly an absolute path, by inspecting the start of it. Return whether it was probably intended to be absolute. */
/**
* Treat the string as possibly an absolute path, by inspecting the
* start of it. Return whether it was probably intended to be
* absolute.
*/
static bool isAbsolute(PathView path)
{
return !path.empty() && path[0] == '/';
return fs::path { path }.is_absolute();
}
@ -69,6 +73,9 @@ Path canonPath(PathView path, bool resolveSymlinks)
if (!isAbsolute(path))
throw Error("not an absolute path: '%1%'", path);
// For Windows
auto rootName = fs::path { path }.root_name();
/* This just exists because we cannot set the target of `remaining`
(the callback parameter) directly to a newly-constructed string,
since it is `std::string_view`. */
@ -78,7 +85,7 @@ Path canonPath(PathView path, bool resolveSymlinks)
arbitrary (but high) limit to prevent infinite loops. */
unsigned int followCount = 0, maxFollow = 1024;
return canonPathInner<UnixPathTrait>(
auto ret = canonPathInner<NativePathTrait>(
path,
[&followCount, &temp, maxFollow, resolveSymlinks]
(std::string & result, std::string_view & remaining) {
@ -99,6 +106,10 @@ Path canonPath(PathView path, bool resolveSymlinks)
}
}
});
if (!rootName.empty())
ret = rootName.string() + std::move(ret);
return ret;
}