diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fileset/README.md | 16 | ||||
-rw-r--r-- | lib/fileset/default.nix | 31 | ||||
-rw-r--r-- | lib/fileset/internal.nix | 3 | ||||
-rwxr-xr-x | lib/fileset/tests.sh | 37 | ||||
-rw-r--r-- | lib/trivial.nix | 2 |
5 files changed, 82 insertions, 7 deletions
diff --git a/lib/fileset/README.md b/lib/fileset/README.md index 14b6877a9065c..93e0199c32a4b 100644 --- a/lib/fileset/README.md +++ b/lib/fileset/README.md @@ -253,7 +253,15 @@ The `fileFilter` function takes a path, and not a file set, as its second argume it would change the `subpath`/`components` value depending on which files are included. - (+) If necessary, this restriction can be relaxed later, the opposite wouldn't be possible -## To update in the future - -Here's a list of places in the library that need to be updated in the future: -- If/Once a function exists that can optionally include a path depending on whether it exists, the error message for the path not existing in `_coerce` should mention the new function +### Strict path existence checking + +Coercing paths that don't exist to file sets always gives an error. + +- (-) Sometimes you want to remove a file that may not always exist using `difference ./. ./does-not-exist`, + but this does not work because coercion of `./does-not-exist` fails, + even though its existence would have no influence on the result. + - (+) This is dangerous, because you wouldn't be protected against typos anymore. + E.g. when trying to prevent `./secret` from being imported, a typo like `difference ./. ./sercet` would import it regardless. + - (+) `difference ./. (maybeMissing ./does-not-exist)` can be used to do this more explicitly. + - (+) `difference ./. (difference ./foo ./foo/bar)` should report an error when `./foo/bar` does not exist ("double negation"). Unfortunately, the current internal representation does not lend itself to a behavior where both `difference x ./does-not-exists` and double negation are handled and checked correctly. + This could be fixed, but would require significant changes to the internal representation that are not worth the effort and the risk of introducing implicit behavior. diff --git a/lib/fileset/default.nix b/lib/fileset/default.nix index 1c3efaed43aad..75e609a072e73 100644 --- a/lib/fileset/default.nix +++ b/lib/fileset/default.nix @@ -11,6 +11,10 @@ Basics: - [Implicit coercion from paths to file sets](#sec-fileset-path-coercion) + - [`lib.fileset.maybeMissing`](#function-library-lib.fileset.maybeMissing): + + Create a file set from a path that may be missing. + - [`lib.fileset.trace`](#function-library-lib.fileset.trace)/[`lib.fileset.traceVal`](#function-library-lib.fileset.trace): Pretty-print file sets for debugging. @@ -105,6 +109,7 @@ let _difference _mirrorStorePath _fetchGitSubmodulesMinver + _emptyWithoutBase ; inherit (builtins) @@ -149,6 +154,32 @@ let in { /* + Create a file set from a path that may or may not exist: + - If the path does exist, the path is [coerced to a file set](#sec-fileset-path-coercion). + - If the path does not exist, a file set containing no files is returned. + + Type: + maybeMissing :: Path -> FileSet + + Example: + # All files in the current directory, but excluding main.o if it exists + difference ./. (maybeMissing ./main.o) + */ + maybeMissing = + path: + if ! isPath path then + if isStringLike path then + throw '' + lib.fileset.maybeMissing: Argument ("${toString path}") is a string-like value, but it should be a path instead.'' + else + throw '' + lib.fileset.maybeMissing: Argument is of type ${typeOf path}, but it should be a path instead.'' + else if ! pathExists path then + _emptyWithoutBase + else + _singleton path; + + /* Incrementally evaluate and trace a file set in a pretty way. This function is only intended for debugging purposes. The exact tracing format is unspecified and may change. diff --git a/lib/fileset/internal.nix b/lib/fileset/internal.nix index e2f4ba3ca3feb..35d556e78391c 100644 --- a/lib/fileset/internal.nix +++ b/lib/fileset/internal.nix @@ -182,7 +182,8 @@ rec { ${context} is of type ${typeOf value}, but it should be a file set or a path instead.'' else if ! pathExists value then throw '' - ${context} (${toString value}) is a path that does not exist.'' + ${context} (${toString value}) is a path that does not exist. + To create a file set from a path that may not exist, use `lib.fileset.maybeMissing`.'' else _singleton value; diff --git a/lib/fileset/tests.sh b/lib/fileset/tests.sh index 046a6bc22e680..077aefe371c35 100755 --- a/lib/fileset/tests.sh +++ b/lib/fileset/tests.sh @@ -413,7 +413,8 @@ expectFailure 'toSource { root = ./.; fileset = cleanSourceWith { src = ./.; }; \s*Note that this only works for sources created from paths.' # Path coercion errors for non-existent paths -expectFailure 'toSource { root = ./.; fileset = ./a; }' 'lib.fileset.toSource: `fileset` \('"$work"'/a\) is a path that does not exist.' +expectFailure 'toSource { root = ./.; fileset = ./a; }' 'lib.fileset.toSource: `fileset` \('"$work"'/a\) is a path that does not exist. +\s*To create a file set from a path that may not exist, use `lib.fileset.maybeMissing`.' # File sets cannot be evaluated directly expectFailure 'union ./. ./.' 'lib.fileset: Directly evaluating a file set is not supported. @@ -1483,6 +1484,40 @@ checkGitTracked rm -rf -- * +## lib.fileset.maybeMissing + +# Argument must be a path +expectFailure 'maybeMissing "someString"' 'lib.fileset.maybeMissing: Argument \("someString"\) is a string-like value, but it should be a path instead.' +expectFailure 'maybeMissing null' 'lib.fileset.maybeMissing: Argument is of type null, but it should be a path instead.' + +tree=( +) +checkFileset 'maybeMissing ./a' +checkFileset 'maybeMissing ./b' +checkFileset 'maybeMissing ./b/c' + +# Works on single files +tree=( + [a]=1 + [b/c]=0 + [b/d]=0 +) +checkFileset 'maybeMissing ./a' +tree=( + [a]=0 + [b/c]=1 + [b/d]=0 +) +checkFileset 'maybeMissing ./b/c' + +# Works on directories +tree=( + [a]=0 + [b/c]=1 + [b/d]=1 +) +checkFileset 'maybeMissing ./b' + # TODO: Once we have combinators and a property testing library, derive property tests from https://en.wikipedia.org/wiki/Algebra_of_sets echo >&2 tests ok diff --git a/lib/trivial.nix b/lib/trivial.nix index a89c1aa25b1f7..caff77190fde2 100644 --- a/lib/trivial.nix +++ b/lib/trivial.nix @@ -195,7 +195,7 @@ rec { On each release the first letter is bumped and a new animal is chosen starting with that new letter. */ - codeName = "Tapir"; + codeName = "Uakari"; /* Returns the current nixpkgs version suffix as string. */ versionSuffix = |