about summary refs log tree commit diff
path: root/lib/path/default.nix
diff options
context:
space:
mode:
authorSilvan Mosberger <silvan.mosberger@tweag.io>2023-07-19 16:20:40 +0200
committerSilvan Mosberger <silvan.mosberger@tweag.io>2023-07-26 23:20:12 +0200
commitb42e178ed4ba33925a474644f5bc54723b2ff15f (patch)
treeecb36719cc09dde24eb08f6f42209f85767eaffe /lib/path/default.nix
parent814f067760d029f532f990974a6df240d4320105 (diff)
lib.path.splitRoot: init
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
Diffstat (limited to 'lib/path/default.nix')
-rw-r--r--lib/path/default.nix46
1 files changed, 46 insertions, 0 deletions
diff --git a/lib/path/default.nix b/lib/path/default.nix
index 3a871bc05283c..1300f0f09011d 100644
--- a/lib/path/default.nix
+++ b/lib/path/default.nix
@@ -271,6 +271,52 @@ in /* No rec! Add dependencies on this file at the top. */ {
               second argument: "${toString path2}" with root "${toString path2Deconstructed.root}"'';
         joinRelPath components;
 
+  /*
+  Split the filesystem root from a [path](https://nixos.org/manual/nix/stable/language/values.html#type-path).
+  The result is an attribute set with these attributes:
+  - `root`: The filesystem root of the path, meaning that this directory has no parent directory.
+  - `subpath`: The [normalised subpath string](#function-library-lib.path.subpath.normalise) that when [appended](#function-library-lib.path.append) to `root` returns the original path.
+
+  Laws:
+  - [Appending](#function-library-lib.path.append) the `root` and `subpath` gives the original path:
+
+        p ==
+          append
+            (splitRoot p).root
+            (splitRoot p).subpath
+
+  - Trying to get the parent directory of `root` using [`readDir`](https://nixos.org/manual/nix/stable/language/builtins.html#builtins-readDir) returns `root` itself:
+
+        dirOf (splitRoot p).root == (splitRoot p).root
+
+  Type:
+    splitRoot :: Path -> { root :: Path, subpath :: String }
+
+  Example:
+    splitRoot /foo/bar
+    => { root = /.; subpath = "./foo/bar"; }
+
+    splitRoot /.
+    => { root = /.; subpath = "./."; }
+
+    # Nix neutralises `..` path components for all path values automatically
+    splitRoot /foo/../bar
+    => { root = /.; subpath = "./bar"; }
+
+    splitRoot "/foo/bar"
+    => <error>
+  */
+  splitRoot = path:
+    assert assertMsg
+      (isPath path)
+      "lib.path.splitRoot: Argument is of type ${typeOf path}, but a path was expected";
+    let
+      deconstructed = deconstructPath path;
+    in {
+      root = deconstructed.root;
+      subpath = joinRelPath deconstructed.components;
+    };
+
   /* Whether a value is a valid subpath string.
 
   - The value is a string