about summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorSilvan Mosberger <silvan.mosberger@tweag.io>2023-10-26 02:15:54 +0200
committerSilvan Mosberger <silvan.mosberger@tweag.io>2023-10-30 12:48:13 +0100
commit47c81d3286bd027d5b55fa581f9502eff4ea8822 (patch)
tree8ff5b38446a78f97d56e9032565fcb164f6700b4 /lib
parent0f6cc8018c7b7f9244f06ad8072ab017808ad0c2 (diff)
lib.fileset.toSource: Optimise unknown file type error
Compared to the parent commit, this removes any detectable performance
cost :)
Diffstat (limited to 'lib')
-rw-r--r--lib/fileset/internal.nix55
1 files changed, 28 insertions, 27 deletions
diff --git a/lib/fileset/internal.nix b/lib/fileset/internal.nix
index afaa8363373c4..76b95c6ae471b 100644
--- a/lib/fileset/internal.nix
+++ b/lib/fileset/internal.nix
@@ -432,37 +432,38 @@ rec {
           # but builtins.path doesn't call the filter function on the `path` argument itself,
           # meaning this function can never receive "/" as an argument
           pathSlash = path + "/";
-
-          include =
-            # Same as `hasPrefix pathSlash baseString`, but more efficient.
-            # With base /foo/bar we need to include /foo:
-            # hasPrefix "/foo/" "/foo/bar/"
-            if substring 0 (stringLength pathSlash) baseString == pathSlash then
-              true
-            # Same as `! hasPrefix baseString pathSlash`, but more efficient.
-            # With base /foo/bar we need to exclude /baz
-            # ! hasPrefix "/baz/" "/foo/bar/"
-            else if substring 0 baseLength pathSlash != baseString then
-              false
-            else
-              # Same as `removePrefix baseString path`, but more efficient.
-              # From the above code we know that hasPrefix baseString pathSlash holds, so this is safe.
-              # We don't use pathSlash here because we only needed the trailing slash for the prefix matching.
-              # With base /foo and path /foo/bar/baz this gives
-              # inTree (split "/" (removePrefix "/foo/" "/foo/bar/baz"))
-              # == inTree (split "/" "bar/baz")
-              # == inTree [ "bar" "baz" ]
-              inTree (split "/" (substring baseLength (-1) path));
         in
-        # This relies on the fact that Nix only distinguishes path types "directory", "regular", "symlink" and "unknown",
-        # so everything except "unknown" is allowed, seems reasonable to rely on that
-        if include && type == "unknown" then
-          throw ''
+        (
+          # Same as `hasPrefix pathSlash baseString`, but more efficient.
+          # With base /foo/bar we need to include /foo:
+          # hasPrefix "/foo/" "/foo/bar/"
+          if substring 0 (stringLength pathSlash) baseString == pathSlash then
+            true
+          # Same as `! hasPrefix baseString pathSlash`, but more efficient.
+          # With base /foo/bar we need to exclude /baz
+          # ! hasPrefix "/baz/" "/foo/bar/"
+          else if substring 0 baseLength pathSlash != baseString then
+            false
+          else
+            # Same as `removePrefix baseString path`, but more efficient.
+            # From the above code we know that hasPrefix baseString pathSlash holds, so this is safe.
+            # We don't use pathSlash here because we only needed the trailing slash for the prefix matching.
+            # With base /foo and path /foo/bar/baz this gives
+            # inTree (split "/" (removePrefix "/foo/" "/foo/bar/baz"))
+            # == inTree (split "/" "bar/baz")
+            # == inTree [ "bar" "baz" ]
+            inTree (split "/" (substring baseLength (-1) path))
+        )
+        # This is a way have an additional check in case the above is true without any significant performance cost
+        && (
+          # This relies on the fact that Nix only distinguishes path types "directory", "regular", "symlink" and "unknown",
+          # so everything except "unknown" is allowed, seems reasonable to rely on that
+          type != "unknown"
+          || throw ''
             lib.fileset.toSource: `fileset` contains a file that cannot be added to the store: ${path}
                 This file is neither a regular file nor a symlink, the only file types supported by the Nix store.
                 Therefore the file set cannot be added to the Nix store as is. Make sure to not include that file to avoid this error.''
-        else
-          include;
+        );
     in
     # Special case because the code below assumes that the _internalBase is always included in the result
     # which shouldn't be done when we have no files at all in the base