about summary refs log tree commit diff
path: root/nix/utils/tests
diff options
context:
space:
mode:
authorsterni <sternenseemann@systemli.org>2021-09-11T16·47+0200
committersterni <sternenseemann@systemli.org>2021-10-02T18·24+0000
commit66fa718cebb4808a95c17e7ee692cf8e5dc87653 (patch)
tree52f5409d179863d484de5bfa9695095562ca4d9a /nix/utils/tests
parent0eef0e343f6ac3b7afbe7f6895fce8b5d20d3b3a (diff)
feat(nix/utils): expose pathType of symlink target r/2947
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>
Diffstat (limited to 'nix/utils/tests')
-rw-r--r--nix/utils/tests/default.nix25
1 files changed, 25 insertions, 0 deletions
diff --git a/nix/utils/tests/default.nix b/nix/utils/tests/default.nix
index 366ddd7c9c94..1ba68486077e 100644
--- a/nix/utils/tests/default.nix
+++ b/nix/utils/tests/default.nix
@@ -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
 ]