feat(nix/utils): expose pathType of symlink target
In order to make readTree import symlinked directories I've been looking into how to detect if a symlink points to a directory (since this would allow us to use symlinks for //nix/sparseTree). I've found a hack for this: symlinkPointsToDir = path: isSymlink path && builtins.pathExists (toString path + "/.") Unfortunately it doesn't seem to be possible to distinguish whether the symlink target does not exist or is a regular file. Since it's possible, I thought might as well add this to `pathType`. To make returning the extra information workable, I've elected to use the attribute set layout used by `//nix/tag`. This doesn't require us to depend anything (as opposed to yants), but gives us pattern matching (via `nix.tag.match`) and also quite idiomatic checking of pathTypes: pathType ./foo ? file (pathType ./foo).symlink or null == "symlink-directory" Nonexistent paths are encoded like this: pathType ./foo ? missing Of course we can't use this in readTree (since it must be zero dependency), but we can easily inline this hack at some point. Change-Id: I15b64a1ea69953c95dc3239ef5860623652b3089 Reviewed-on: https://cl.tvl.fyi/c/depot/+/3535 Tested-by: BuildkiteCI Reviewed-by: Profpatsch <mail@profpatsch.de> Reviewed-by: tazjin <mail@tazj.in>
This commit is contained in:
parent
0eef0e343f
commit
66fa718ceb
2 changed files with 104 additions and 13 deletions
|
@ -11,8 +11,10 @@ let
|
|||
|
||||
inherit (depot.nix.utils)
|
||||
isDirectory
|
||||
realPathIsDirectory
|
||||
isRegularFile
|
||||
isSymlink
|
||||
pathType
|
||||
storePathName
|
||||
;
|
||||
|
||||
|
@ -29,6 +31,13 @@ let
|
|||
(isDirectory ./symlink-directory) false)
|
||||
(assertUtilsPred "file not isDirectory"
|
||||
(isDirectory ./directory/file) false)
|
||||
# realPathIsDirectory
|
||||
(assertUtilsPred "directory realPathIsDirectory"
|
||||
(realPathIsDirectory ./directory) true)
|
||||
(assertUtilsPred "symlink to directory realPathIsDirectory"
|
||||
(realPathIsDirectory ./symlink-directory) true)
|
||||
(assertUtilsPred "realPathIsDirectory resolves chained symlinks"
|
||||
(realPathIsDirectory ./symlink-symlink-directory) true)
|
||||
# isRegularFile
|
||||
(assertUtilsPred "file isRegularFile"
|
||||
(isRegularFile ./directory/file) true)
|
||||
|
@ -52,12 +61,27 @@ let
|
|||
# missing files throw
|
||||
(assertThrows "isDirectory throws on missing file"
|
||||
(isDirectory ./does-not-exist))
|
||||
(assertThrows "realPathIsDirectory throws on missing file"
|
||||
(realPathIsDirectory ./does-not-exist))
|
||||
(assertThrows "isRegularFile throws on missing file"
|
||||
(isRegularFile ./does-not-exist))
|
||||
(assertThrows "isSymlink throws on missing file"
|
||||
(isSymlink ./does-not-exist))
|
||||
]);
|
||||
|
||||
symlinkPathTypeTests = it "correctly judges symlinks" [
|
||||
(assertEq "symlinks to directories are detected correcty"
|
||||
((pathType ./symlink-directory).symlink or null) "directory")
|
||||
(assertEq "symlinks to symlinks to directories are detected correctly"
|
||||
((pathType ./symlink-symlink-directory).symlink or null) "directory")
|
||||
(assertEq "symlinks to files are detected-ish"
|
||||
((pathType ./symlink-file).symlink or null) "regular-or-missing")
|
||||
(assertEq "symlinks to symlinks to files are detected-ish"
|
||||
((pathType ./symlink-symlink-file).symlink or null) "regular-or-missing")
|
||||
(assertEq "symlinks to nowhere are not distinguished from files"
|
||||
((pathType ./missing).symlink or null) "regular-or-missing")
|
||||
];
|
||||
|
||||
cheddarStorePath =
|
||||
builtins.unsafeDiscardStringContext depot.tools.cheddar.outPath;
|
||||
|
||||
|
@ -75,5 +99,6 @@ in
|
|||
|
||||
runTestsuite "nix.utils" [
|
||||
pathPredicates
|
||||
symlinkPathTypeTests
|
||||
storePathNameTests
|
||||
]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue