···252 - (+) That can change depending on which files are included, so if it's used for `fileFilter`
253 it would change the `subpath`/`components` value depending on which files are included.
254- (+) If necessary, this restriction can be relaxed later, the opposite wouldn't be possible
255-256-## To update in the future
257-258-Here's a list of places in the library that need to be updated in the future:
259-- 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
···252 - (+) That can change depending on which files are included, so if it's used for `fileFilter`
253 it would change the `subpath`/`components` value depending on which files are included.
254- (+) If necessary, this restriction can be relaxed later, the opposite wouldn't be possible
00000
+31
lib/fileset/default.nix
···11 Basics:
12 - [Implicit coercion from paths to file sets](#sec-fileset-path-coercion)
13000014 - [`lib.fileset.trace`](#function-library-lib.fileset.trace)/[`lib.fileset.traceVal`](#function-library-lib.fileset.trace):
1516 Pretty-print file sets for debugging.
···105 _difference
106 _mirrorStorePath
107 _fetchGitSubmodulesMinver
0108 ;
109110 inherit (builtins)
···147 ;
148149in {
00000000000000000000000000150151 /*
152 Incrementally evaluate and trace a file set in a pretty way.
···11 Basics:
12 - [Implicit coercion from paths to file sets](#sec-fileset-path-coercion)
1314+ - [`lib.fileset.maybeMissing`](#function-library-lib.fileset.maybeMissing):
15+16+ Create a file set from a path that may be missing.
17+18 - [`lib.fileset.trace`](#function-library-lib.fileset.trace)/[`lib.fileset.traceVal`](#function-library-lib.fileset.trace):
1920 Pretty-print file sets for debugging.
···109 _difference
110 _mirrorStorePath
111 _fetchGitSubmodulesMinver
112+ _emptyWithoutBase
113 ;
114115 inherit (builtins)
···152 ;
153154in {
155+156+ /*
157+ Create a file set from a path that may or may not exist:
158+ - If the path does exist, the path is [coerced to a file set](#sec-fileset-path-coercion).
159+ - If the path does not exist, a file set containing no files is returned.
160+161+ Type:
162+ maybeMissing :: Path -> FileSet
163+164+ Example:
165+ # All files in the current directory, but excluding main.o if it exists
166+ difference ./. (maybeMissing ./main.o)
167+ */
168+ maybeMissing =
169+ path:
170+ if ! isPath path then
171+ if isStringLike path then
172+ throw ''
173+ lib.fileset.maybeMissing: Argument ("${toString path}") is a string-like value, but it should be a path instead.''
174+ else
175+ throw ''
176+ lib.fileset.maybeMissing: Argument is of type ${typeOf path}, but it should be a path instead.''
177+ else if ! pathExists path then
178+ _emptyWithoutBase
179+ else
180+ _singleton path;
181182 /*
183 Incrementally evaluate and trace a file set in a pretty way.
+2-1
lib/fileset/internal.nix
···181 ${context} is of type ${typeOf value}, but it should be a file set or a path instead.''
182 else if ! pathExists value then
183 throw ''
184- ${context} (${toString value}) is a path that does not exist.''
0185 else
186 _singleton value;
187
···181 ${context} is of type ${typeOf value}, but it should be a file set or a path instead.''
182 else if ! pathExists value then
183 throw ''
184+ ${context} (${toString value}) is a path that does not exist.
185+ To create a file set from a path that may not exist, use `lib.fileset.maybeMissing`.''
186 else
187 _singleton value;
188
+36-1
lib/fileset/tests.sh
···413\s*Note that this only works for sources created from paths.'
414415# Path coercion errors for non-existent paths
416-expectFailure 'toSource { root = ./.; fileset = ./a; }' 'lib.fileset.toSource: `fileset` \('"$work"'/a\) is a path that does not exist.'
0417418# File sets cannot be evaluated directly
419expectFailure 'union ./. ./.' 'lib.fileset: Directly evaluating a file set is not supported.
···1449checkGitTracked
14501451rm -rf -- *
000000000000000000000000000000000014521453# TODO: Once we have combinators and a property testing library, derive property tests from https://en.wikipedia.org/wiki/Algebra_of_sets
1454
···413\s*Note that this only works for sources created from paths.'
414415# Path coercion errors for non-existent paths
416+expectFailure 'toSource { root = ./.; fileset = ./a; }' 'lib.fileset.toSource: `fileset` \('"$work"'/a\) is a path that does not exist.
417+\s*To create a file set from a path that may not exist, use `lib.fileset.maybeMissing`.'
418419# File sets cannot be evaluated directly
420expectFailure 'union ./. ./.' 'lib.fileset: Directly evaluating a file set is not supported.
···1450checkGitTracked
14511452rm -rf -- *
1453+1454+## lib.fileset.maybeMissing
1455+1456+# Argument must be a path
1457+expectFailure 'maybeMissing "someString"' 'lib.fileset.maybeMissing: Argument \("someString"\) is a string-like value, but it should be a path instead.'
1458+expectFailure 'maybeMissing null' 'lib.fileset.maybeMissing: Argument is of type null, but it should be a path instead.'
1459+1460+tree=(
1461+)
1462+checkFileset 'maybeMissing ./a'
1463+checkFileset 'maybeMissing ./b'
1464+checkFileset 'maybeMissing ./b/c'
1465+1466+# Works on single files
1467+tree=(
1468+ [a]=1
1469+ [b/c]=0
1470+ [b/d]=0
1471+)
1472+checkFileset 'maybeMissing ./a'
1473+tree=(
1474+ [a]=0
1475+ [b/c]=1
1476+ [b/d]=0
1477+)
1478+checkFileset 'maybeMissing ./b/c'
1479+1480+# Works on directories
1481+tree=(
1482+ [a]=0
1483+ [b/c]=1
1484+ [b/d]=1
1485+)
1486+checkFileset 'maybeMissing ./b'
14871488# TODO: Once we have combinators and a property testing library, derive property tests from https://en.wikipedia.org/wiki/Algebra_of_sets
1489