summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSilvan Mosberger <silvan.mosberger@tweag.io>2023-01-18 18:09:44 +0100
committerSilvan Mosberger <silvan.mosberger@tweag.io>2023-01-18 20:17:31 +0100
commiteac2538707ee6edd475cb40bfa2ec3d2c05c3ac0 (patch)
tree6f163de8470bd3520c7925a0c2f2f685053e19d2
parentlib.path: Minor improvements (diff)
downloadnixpkgs-eac2538707ee6edd475cb40bfa2ec3d2c05c3ac0.tar.gz
lib.path.append: init
This function can be used to append strings to Nix path values in a safe way.
-rw-r--r--lib/path/default.nix47
-rw-r--r--lib/path/tests/unit.nix36
2 files changed, 82 insertions, 1 deletions
diff --git a/lib/path/default.nix b/lib/path/default.nix
index 6fa7c1dd6419..075e2fc0d137 100644
--- a/lib/path/default.nix
+++ b/lib/path/default.nix
@@ -4,6 +4,7 @@ let
inherit (builtins)
isString
+ isPath
split
match
;
@@ -98,6 +99,52 @@ let
in /* No rec! Add dependencies on this file at the top. */ {
+ /* Append a subpath string to a path.
+
+ Like `path + ("/" + string)` but safer, because it errors instead of returning potentially surprising results.
+ More specifically, it checks that the first argument is a [path value type](https://nixos.org/manual/nix/stable/language/values.html#type-path"),
+ and that the second argument is a valid subpath string (see `lib.path.subpath.isValid`).
+
+ Type:
+ append :: Path -> String -> Path
+
+ Example:
+ append /foo "bar/baz"
+ => /foo/bar/baz
+
+ # subpaths don't need to be normalised
+ append /foo "./bar//baz/./"
+ => /foo/bar/baz
+
+ # can append to root directory
+ append /. "foo/bar"
+ => /foo/bar
+
+ # first argument needs to be a path value type
+ append "/foo" "bar"
+ => <error>
+
+ # second argument needs to be a valid subpath string
+ append /foo /bar
+ => <error>
+ append /foo ""
+ => <error>
+ append /foo "/bar"
+ => <error>
+ append /foo "../bar"
+ => <error>
+ */
+ append =
+ # The absolute path to append to
+ path:
+ # The subpath string to append
+ subpath:
+ assert assertMsg (isPath path) ''
+ lib.path.append: The first argument is of type ${builtins.typeOf path}, but a path was expected'';
+ assert assertMsg (isValid subpath) ''
+ lib.path.append: Second argument is not a valid subpath string:
+ ${subpathInvalidReason subpath}'';
+ path + ("/" + subpath);
/* Whether a value is a valid subpath string.
diff --git a/lib/path/tests/unit.nix b/lib/path/tests/unit.nix
index da2c950de914..a1a45173a909 100644
--- a/lib/path/tests/unit.nix
+++ b/lib/path/tests/unit.nix
@@ -3,9 +3,43 @@
{ libpath }:
let
lib = import libpath;
- inherit (lib.path) subpath;
+ inherit (lib.path) append subpath;
cases = lib.runTests {
+ # Test examples from the lib.path.append documentation
+ testAppendExample1 = {
+ expr = append /foo "bar/baz";
+ expected = /foo/bar/baz;
+ };
+ testAppendExample2 = {
+ expr = append /foo "./bar//baz/./";
+ expected = /foo/bar/baz;
+ };
+ testAppendExample3 = {
+ expr = append /. "foo/bar";
+ expected = /foo/bar;
+ };
+ testAppendExample4 = {
+ expr = (builtins.tryEval (append "/foo" "bar")).success;
+ expected = false;
+ };
+ testAppendExample5 = {
+ expr = (builtins.tryEval (append /foo /bar)).success;
+ expected = false;
+ };
+ testAppendExample6 = {
+ expr = (builtins.tryEval (append /foo "")).success;
+ expected = false;
+ };
+ testAppendExample7 = {
+ expr = (builtins.tryEval (append /foo "/bar")).success;
+ expected = false;
+ };
+ testAppendExample8 = {
+ expr = (builtins.tryEval (append /foo "../bar")).success;
+ expected = false;
+ };
+
# Test examples from the lib.path.subpath.isValid documentation
testSubpathIsValidExample1 = {
expr = subpath.isValid null;