mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-25 16:33:15 +00:00
lib.path.hasPrefix: init
This commit is contained in:
parent
866f75e5b9
commit
592213ad3f
@ -7,6 +7,7 @@ let
|
|||||||
isPath
|
isPath
|
||||||
split
|
split
|
||||||
match
|
match
|
||||||
|
typeOf
|
||||||
;
|
;
|
||||||
|
|
||||||
inherit (lib.lists)
|
inherit (lib.lists)
|
||||||
@ -18,6 +19,7 @@ let
|
|||||||
all
|
all
|
||||||
concatMap
|
concatMap
|
||||||
foldl'
|
foldl'
|
||||||
|
take
|
||||||
;
|
;
|
||||||
|
|
||||||
inherit (lib.strings)
|
inherit (lib.strings)
|
||||||
@ -100,6 +102,22 @@ let
|
|||||||
# An empty string is not a valid relative path, so we need to return a `.` when we have no components
|
# An empty string is not a valid relative path, so we need to return a `.` when we have no components
|
||||||
(if components == [] then "." else concatStringsSep "/" components);
|
(if components == [] then "." else concatStringsSep "/" components);
|
||||||
|
|
||||||
|
# Type: Path -> { root :: Path, components :: [ String ] }
|
||||||
|
#
|
||||||
|
# Deconstruct a path value type into:
|
||||||
|
# - root: The filesystem root of the path, generally `/`
|
||||||
|
# - components: All the path's components
|
||||||
|
#
|
||||||
|
# This is similar to `splitString "/" (toString path)` but safer
|
||||||
|
# because it can distinguish different filesystem roots
|
||||||
|
deconstructPath =
|
||||||
|
let
|
||||||
|
recurse = components: base:
|
||||||
|
# If the parent of a path is the path itself, then it's a filesystem root
|
||||||
|
if base == dirOf base then { root = base; inherit components; }
|
||||||
|
else recurse ([ (baseNameOf base) ] ++ components) (dirOf base);
|
||||||
|
in recurse [];
|
||||||
|
|
||||||
in /* No rec! Add dependencies on this file at the top. */ {
|
in /* No rec! Add dependencies on this file at the top. */ {
|
||||||
|
|
||||||
/* Append a subpath string to a path.
|
/* Append a subpath string to a path.
|
||||||
@ -155,6 +173,51 @@ in /* No rec! Add dependencies on this file at the top. */ {
|
|||||||
${subpathInvalidReason subpath}'';
|
${subpathInvalidReason subpath}'';
|
||||||
path + ("/" + subpath);
|
path + ("/" + subpath);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Whether the first path is a component-wise prefix of the second path.
|
||||||
|
|
||||||
|
Laws:
|
||||||
|
|
||||||
|
- `hasPrefix p q` is only true if `q == append p s` for some subpath `s`.
|
||||||
|
|
||||||
|
- `hasPrefix` is a [non-strict partial order](https://en.wikipedia.org/wiki/Partially_ordered_set#Non-strict_partial_order) over the set of all path values
|
||||||
|
|
||||||
|
Type:
|
||||||
|
hasPrefix :: Path -> Path -> Bool
|
||||||
|
|
||||||
|
Example:
|
||||||
|
hasPrefix /foo /foo/bar
|
||||||
|
=> true
|
||||||
|
hasPrefix /foo /foo
|
||||||
|
=> true
|
||||||
|
hasPrefix /foo/bar /foo
|
||||||
|
=> false
|
||||||
|
hasPrefix /. /foo
|
||||||
|
=> true
|
||||||
|
*/
|
||||||
|
hasPrefix =
|
||||||
|
path1:
|
||||||
|
assert assertMsg
|
||||||
|
(isPath path1)
|
||||||
|
"lib.path.hasPrefix: First argument is of type ${typeOf path1}, but a path was expected";
|
||||||
|
let
|
||||||
|
path1Deconstructed = deconstructPath path1;
|
||||||
|
in
|
||||||
|
path2:
|
||||||
|
assert assertMsg
|
||||||
|
(isPath path2)
|
||||||
|
"lib.path.hasPrefix: Second argument is of type ${typeOf path2}, but a path was expected";
|
||||||
|
let
|
||||||
|
path2Deconstructed = deconstructPath path2;
|
||||||
|
in
|
||||||
|
assert assertMsg
|
||||||
|
(path1Deconstructed.root == path2Deconstructed.root) ''
|
||||||
|
lib.path.hasPrefix: Filesystem roots must be the same for both paths, but paths with different roots were given:
|
||||||
|
first argument: "${toString path1}" with root "${toString path1Deconstructed.root}"
|
||||||
|
second argument: "${toString path2}" with root "${toString path2Deconstructed.root}"'';
|
||||||
|
take (length path1Deconstructed.components) path2Deconstructed.components == path1Deconstructed.components;
|
||||||
|
|
||||||
|
|
||||||
/* Whether a value is a valid subpath string.
|
/* Whether a value is a valid subpath string.
|
||||||
|
|
||||||
- The value is a string
|
- The value is a string
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
{ libpath }:
|
{ libpath }:
|
||||||
let
|
let
|
||||||
lib = import libpath;
|
lib = import libpath;
|
||||||
inherit (lib.path) append subpath;
|
inherit (lib.path) hasPrefix append subpath;
|
||||||
|
|
||||||
cases = lib.runTests {
|
cases = lib.runTests {
|
||||||
# Test examples from the lib.path.append documentation
|
# Test examples from the lib.path.append documentation
|
||||||
@ -40,6 +40,23 @@ let
|
|||||||
expected = false;
|
expected = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
testHasPrefixExample1 = {
|
||||||
|
expr = hasPrefix /foo /foo/bar;
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
testHasPrefixExample2 = {
|
||||||
|
expr = hasPrefix /foo /foo;
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
testHasPrefixExample3 = {
|
||||||
|
expr = hasPrefix /foo/bar /foo;
|
||||||
|
expected = false;
|
||||||
|
};
|
||||||
|
testHasPrefixExample4 = {
|
||||||
|
expr = hasPrefix /. /foo;
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
|
||||||
# Test examples from the lib.path.subpath.isValid documentation
|
# Test examples from the lib.path.subpath.isValid documentation
|
||||||
testSubpathIsValidExample1 = {
|
testSubpathIsValidExample1 = {
|
||||||
expr = subpath.isValid null;
|
expr = subpath.isValid null;
|
||||||
|
@ -264,7 +264,8 @@ rec {
|
|||||||
lib.strings.hasPrefix: The first argument (${toString pref}) is a path value, but only strings are supported.
|
lib.strings.hasPrefix: The first argument (${toString pref}) is a path value, but only strings are supported.
|
||||||
There is almost certainly a bug in the calling code, since this function always returns `false` in such a case.
|
There is almost certainly a bug in the calling code, since this function always returns `false` in such a case.
|
||||||
This function also copies the path to the Nix store, which may not be what you want.
|
This function also copies the path to the Nix store, which may not be what you want.
|
||||||
This behavior is deprecated and will throw an error in the future.''
|
This behavior is deprecated and will throw an error in the future.
|
||||||
|
You might want to use `lib.path.hasPrefix` instead, which correctly supports paths.''
|
||||||
(substring 0 (stringLength pref) str == pref);
|
(substring 0 (stringLength pref) str == pref);
|
||||||
|
|
||||||
/* Determine whether a string has given suffix.
|
/* Determine whether a string has given suffix.
|
||||||
|
Loading…
Reference in New Issue
Block a user