Skip to content

Commit

Permalink
lib.path.append: init
Browse files Browse the repository at this point in the history
This function can be used to append strings to Nix path values in a
safe way.
  • Loading branch information
infinisil committed Jan 18, 2023
1 parent 5c4f616 commit eac2538
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
47 changes: 47 additions & 0 deletions lib/path/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ let

inherit (builtins)
isString
isPath
split
match
;
Expand Down Expand Up @@ -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.
Expand Down
36 changes: 35 additions & 1 deletion lib/path/tests/unit.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit eac2538

Please sign in to comment.