···1-/*
2 <!-- This anchor is here for backwards compatibility -->
3 []{#sec-fileset}
4···6 A file set is a (mathematical) set of local files that can be added to the Nix store for use in Nix derivations.
7 File sets are easy and safe to use, providing obvious and composable semantics with good error messages to prevent mistakes.
89- ## Overview {#sec-fileset-overview}
1011 Basics:
12 - [Implicit coercion from paths to file sets](#sec-fileset-path-coercion)
···58 see [this issue](https://github.com/NixOS/nixpkgs/issues/266356) to request it.
596061- ## Implicit coercion from paths to file sets {#sec-fileset-path-coercion}
6263 All functions accepting file sets as arguments can also accept [paths](https://nixos.org/manual/nix/stable/language/values.html#type-path) as arguments.
64 Such path arguments are implicitly coerced to file sets containing all files under that path:
···78 This is in contrast to using [paths in string interpolation](https://nixos.org/manual/nix/stable/language/values.html#type-path), which does add the entire referenced path to the store.
79 :::
8081- ### Example {#sec-fileset-path-coercion-example}
8283 Assume we are in a local directory with a file hierarchy like this:
84 ```
···157158in {
159160- /*
161 Create a file set from a path that may or may not exist:
162 - If the path does exist, the path is [coerced to a file set](#sec-fileset-path-coercion).
163 - If the path does not exist, a file set containing no files is returned.
164165- Type:
166- maybeMissing :: Path -> FileSet
000000167168- Example:
169- # All files in the current directory, but excluding main.o if it exists
170- difference ./. (maybeMissing ./main.o)
00000000000171 */
172 maybeMissing =
173 path:
···183 else
184 _singleton path;
185186- /*
187 Incrementally evaluate and trace a file set in a pretty way.
188 This function is only intended for debugging purposes.
189 The exact tracing format is unspecified and may change.
···194195 This variant is useful for tracing file sets in the Nix repl.
196197- Type:
198- trace :: FileSet -> Any -> Any
199200- Example:
201- trace (unions [ ./Makefile ./src ./tests/run.sh ]) null
202- =>
203- trace: /home/user/src/myProject
204- trace: - Makefile (regular)
205- trace: - src (all files in directory)
206- trace: - tests
207- trace: - run.sh (regular)
208- null
209- */
210- trace =
211- /*
212- The file set to trace.
213214- This argument can also be a path,
215- which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
216- */
217- fileset:
00000000000000000000218 let
219 # "fileset" would be a better name, but that would clash with the argument name,
220 # and we cannot change that because of https://github.com/nix-community/nixdoc/issues/76
···224 (_printFileset actualFileset)
225 (x: x);
226227- /*
228 Incrementally evaluate and trace a file set in a pretty way.
229 This function is only intended for debugging purposes.
230 The exact tracing format is unspecified and may change.
···234235 This variant is useful for tracing file sets passed as arguments to other functions.
236237- Type:
238- traceVal :: FileSet -> FileSet
0000000000000239240- Example:
241- toSource {
242- root = ./.;
243- fileset = traceVal (unions [
244- ./Makefile
245- ./src
246- ./tests/run.sh
247- ]);
248- }
249- =>
250- trace: /home/user/src/myProject
251- trace: - Makefile (regular)
252- trace: - src (all files in directory)
253- trace: - tests
254- trace: - run.sh (regular)
255- "/nix/store/...-source"
0000000256 */
257- traceVal =
258- /*
259- The file set to trace and return.
260-261- This argument can also be a path,
262- which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
263- */
264- fileset:
265 let
266 # "fileset" would be a better name, but that would clash with the argument name,
267 # and we cannot change that because of https://github.com/nix-community/nixdoc/issues/76
···273 # but that would then duplicate work for consumers of the fileset, because then they have to coerce it again
274 actualFileset;
275276- /*
277 Add the local files contained in `fileset` to the store as a single [store path](https://nixos.org/manual/nix/stable/glossary#gloss-store-path) rooted at `root`.
278279 The result is the store path as a string-like value, making it usable e.g. as the `src` of a derivation, or in string interpolation:
···286287 The name of the store path is always `source`.
288289- Type:
290- toSource :: {
291- root :: Path,
292- fileset :: FileSet,
293- } -> SourceLike
294-295- Example:
296- # Import the current directory into the store
297- # but only include files under ./src
298- toSource {
299- root = ./.;
300- fileset = ./src;
301- }
302- => "/nix/store/...-source"
303-304- # Import the current directory into the store
305- # but only include ./Makefile and all files under ./src
306- toSource {
307- root = ./.;
308- fileset = union
309- ./Makefile
310- ./src;
311- }
312- => "/nix/store/...-source"
313314- # Trying to include a file outside the root will fail
315- toSource {
316- root = ./.;
317- fileset = unions [
318- ./Makefile
319- ./src
320- ../LICENSE
321- ];
322- }
323- => <error>
324325- # The root needs to point to a directory that contains all the files
326- toSource {
327- root = ../.;
328- fileset = unions [
329- ./Makefile
330- ./src
331- ../LICENSE
332- ];
333- }
334- => "/nix/store/...-source"
335336- # The root has to be a local filesystem path
337- toSource {
338- root = "/nix/store/...-source";
339- fileset = ./.;
340- }
341- => <error>
342- */
343- toSource = {
344- /*
345- (required) The local directory [path](https://nixos.org/manual/nix/stable/language/values.html#type-path) that will correspond to the root of the resulting store path.
346 Paths in [strings](https://nixos.org/manual/nix/stable/language/values.html#type-string), including Nix store paths, cannot be passed as `root`.
347 `root` has to be a directory.
348···350 Changing `root` only affects the directory structure of the resulting store path, it does not change which files are added to the store.
351 The only way to change which files get added to the store is by changing the `fileset` attribute.
352 :::
353- */
354- root,
355- /*
356- (required) The file set whose files to import into the store.
357 File sets can be created using other functions in this library.
358 This argument can also be a path,
359 which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
···362 If a directory does not recursively contain any file, it is omitted from the store path contents.
363 :::
364365- */
00000000000000000000000000000000000000000000000000000000000000000366 fileset,
367 }:
368 let
···418 };
419420421- /*
422 The list of file paths contained in the given file set.
423424 :::{.note}
···432433 The resulting list of files can be turned back into a file set using [`lib.fileset.unions`](#function-library-lib.fileset.unions).
434435- Type:
436- toList :: FileSet -> [ Path ]
000000000000000000437438- Example:
439- toList ./.
440- [ ./README.md ./Makefile ./src/main.c ./src/main.h ]
441442- toList (difference ./. ./src)
443- [ ./README.md ./Makefile ]
444 */
445- toList =
446- # The file set whose file paths to return.
447- # This argument can also be a path,
448- # which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
449- fileset:
450 _toList (_coerce "lib.fileset.toList: Argument" fileset);
451452- /*
453 The file set containing all files that are in either of two given file sets.
454 This is the same as [`unions`](#function-library-lib.fileset.unions),
455 but takes just two file sets instead of a list.
···458 The given file sets are evaluated as lazily as possible,
459 with the first argument being evaluated first if needed.
460461- Type:
462- union :: FileSet -> FileSet -> FileSet
00000000000000463464- Example:
465- # Create a file set containing the file `Makefile`
466- # and all files recursively in the `src` directory
467- union ./Makefile ./src
000000000468469- # Create a file set containing the file `Makefile`
470- # and the LICENSE file from the parent directory
471- union ./Makefile ../LICENSE
472 */
473 union =
474- # The first file set.
475- # This argument can also be a path,
476- # which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
477 fileset1:
478- # The second file set.
479- # This argument can also be a path,
480- # which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
481 fileset2:
482 _unionMany
483 (_coerceMany "lib.fileset.union" [
···491 }
492 ]);
493494- /*
495 The file set containing all files that are in any of the given file sets.
496 This is the same as [`union`](#function-library-lib.fileset.unions),
497 but takes a list of file sets instead of just two.
···500 The given file sets are evaluated as lazily as possible,
501 with earlier elements being evaluated first if needed.
502503- Type:
504- unions :: [ FileSet ] -> FileSet
505506- Example:
507- # Create a file set containing selected files
508- unions [
509- # Include the single file `Makefile` in the current directory
510- # This errors if the file doesn't exist
511- ./Makefile
512513- # Recursively include all files in the `src/code` directory
514- # If this directory is empty this has no effect
515- ./src/code
00516517- # Include the files `run.sh` and `unit.c` from the `tests` directory
518- ./tests/run.sh
519- ./tests/unit.c
520521- # Include the `LICENSE` file from the parent directory
522- ../LICENSE
523- ]
0000000000000000000000524 */
525 unions =
526- # A list of file sets.
527- # The elements can also be paths,
528- # which get [implicitly coerced to file sets](#sec-fileset-path-coercion).
529 filesets:
530 if ! isList filesets then
531 throw ''
···541 _unionMany
542 ];
543544- /*
545 The file set containing all files that are in both of two given file sets.
546 See also [Intersection (set theory)](https://en.wikipedia.org/wiki/Intersection_(set_theory)).
547548 The given file sets are evaluated as lazily as possible,
549 with the first argument being evaluated first if needed.
550551- Type:
552- intersection :: FileSet -> FileSet -> FileSet
000000000000000000553554- Example:
555- # Limit the selected files to the ones in ./., so only ./src and ./Makefile
556- intersection ./. (unions [ ../LICENSE ./src ./Makefile ])
000557 */
558 intersection =
559- # The first file set.
560- # This argument can also be a path,
561- # which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
562 fileset1:
563- # The second file set.
564- # This argument can also be a path,
565- # which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
566 fileset2:
567 let
568 filesets = _coerceMany "lib.fileset.intersection" [
···580 (elemAt filesets 0)
581 (elemAt filesets 1);
582583- /*
584 The file set containing all files from the first file set that are not in the second file set.
585 See also [Difference (set theory)](https://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement).
586587 The given file sets are evaluated as lazily as possible,
588 with the first argument being evaluated first if needed.
589590- Type:
591- union :: FileSet -> FileSet -> FileSet
00000000000000000000000592593- Example:
594- # Create a file set containing all files from the current directory,
595- # except ones under ./tests
596- difference ./. ./tests
0000597598- let
599- # A set of Nix-related files
600- nixFiles = unions [ ./default.nix ./nix ./tests/default.nix ];
601- in
602- # Create a file set containing all files under ./tests, except ones in `nixFiles`,
603- # meaning only without ./tests/default.nix
604- difference ./tests nixFiles
605 */
606 difference =
607- # The positive file set.
608- # The result can only contain files that are also in this file set.
609- #
610- # This argument can also be a path,
611- # which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
612 positive:
613- # The negative file set.
614- # The result will never contain files that are also in this file set.
615- #
616- # This argument can also be a path,
617- # which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
618 negative:
619 let
620 filesets = _coerceMany "lib.fileset.difference" [
···632 (elemAt filesets 0)
633 (elemAt filesets 1);
634635- /*
636 Filter a file set to only contain files matching some predicate.
637638- Type:
639- fileFilter ::
640- ({
641- name :: String,
642- type :: String,
643- hasExt :: String -> Bool,
644- ...
645- } -> Bool)
646- -> Path
647- -> FileSet
648649- Example:
650- # Include all regular `default.nix` files in the current directory
651- fileFilter (file: file.name == "default.nix") ./.
652653- # Include all non-Nix files from the current directory
654- fileFilter (file: ! file.hasExt "nix") ./.
655-656- # Include all files that start with a "." in the current directory
657- fileFilter (file: hasPrefix "." file.name) ./.
658659- # Include all regular files (not symlinks or others) in the current directory
660- fileFilter (file: file.type == "regular") ./.
661- */
662- fileFilter =
663- /*
664- The predicate function to call on all files contained in given file set.
665 A file is included in the resulting file set if this function returns true for it.
666667 This function is called with an attribute set containing these attributes:
···678 `hasExt "gitignore"` is true.
679680 Other attributes may be added in the future.
681- */
000000000000000000000000000000000000000682 predicate:
683- # The path whose files to filter
684 path:
685 if ! isFunction predicate then
686 throw ''
···699 else
700 _fileFilter predicate path;
701702- /*
703- Create a file set with the same files as a `lib.sources`-based value.
704- This does not import any of the files into the store.
000000000705706- This can be used to gradually migrate from `lib.sources`-based filtering to `lib.fileset`.
707708- A file set can be turned back into a source using [`toSource`](#function-library-lib.fileset.toSource).
709710- :::{.note}
711- File sets cannot represent empty directories.
712- Turning the result of this function back into a source using `toSource` will therefore not preserve empty directories.
713- :::
714715- Type:
0000716 fromSource :: SourceLike -> FileSet
0717718- Example:
0000719 # There's no cleanSource-like function for file sets yet,
720 # but we can just convert cleanSource to a file set and use it that way
721 toSource {
···740 ./Makefile
741 ./src
742 ]);
000743 */
744 fromSource = source:
745 let
···768 # If there's no filter, no need to run the expensive conversion, all subpaths will be included
769 _singleton path;
770771- /*
772 Create a file set containing all [Git-tracked files](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository) in a repository.
773774 This function behaves like [`gitTrackedWith { }`](#function-library-lib.fileset.gitTrackedWith) - using the defaults.
775776- Type:
777- gitTracked :: Path -> FileSet
00778779- Example:
780- # Include all files tracked by the Git repository in the current directory
781- gitTracked ./.
782783- # Include only files tracked by the Git repository in the parent directory
784- # that are also in the current directory
785- intersection ./. (gitTracked ../.)
00000000000000000786 */
787 gitTracked =
788- /*
789- The [path](https://nixos.org/manual/nix/stable/language/values#type-path) to the working directory of a local Git repository.
790- This directory must contain a `.git` file or subdirectory.
791- */
792 path:
793 _fromFetchGit
794 "gitTracked"
···796 path
797 {};
798799- /*
800 Create a file set containing all [Git-tracked files](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository) in a repository.
801 The first argument allows configuration with an attribute set,
802 while the second argument is the path to the Git working tree.
···820 This may change in the future.
821 :::
822823- Type:
824- gitTrackedWith :: { recurseSubmodules :: Bool ? false } -> Path -> FileSet
0000000000000000000825826- Example:
827- # Include all files tracked by the Git repository in the current directory
828- # and any submodules under it
829- gitTracked { recurseSubmodules = true; } ./.
000830 */
831 gitTrackedWith =
832 {
833- /*
834- (optional, default: `false`) Whether to recurse into [Git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) to also include their tracked files.
835-836- If `true`, this is equivalent to passing the [--recurse-submodules](https://git-scm.com/docs/git-ls-files#Documentation/git-ls-files.txt---recurse-submodules) flag to `git ls-files`.
837- */
838 recurseSubmodules ? false,
839 }:
840- /*
841- The [path](https://nixos.org/manual/nix/stable/language/values#type-path) to the working directory of a local Git repository.
842- This directory must contain a `.git` file or subdirectory.
843- */
844 path:
845 if ! isBool recurseSubmodules then
846 throw "lib.fileset.gitTrackedWith: Expected the attribute `recurseSubmodules` of the first argument to be a boolean, but it's a ${typeOf recurseSubmodules} instead."
···1+/**
2 <!-- This anchor is here for backwards compatibility -->
3 []{#sec-fileset}
4···6 A file set is a (mathematical) set of local files that can be added to the Nix store for use in Nix derivations.
7 File sets are easy and safe to use, providing obvious and composable semantics with good error messages to prevent mistakes.
89+ # Overview {#sec-fileset-overview}
1011 Basics:
12 - [Implicit coercion from paths to file sets](#sec-fileset-path-coercion)
···58 see [this issue](https://github.com/NixOS/nixpkgs/issues/266356) to request it.
596061+ # Implicit coercion from paths to file sets {#sec-fileset-path-coercion}
6263 All functions accepting file sets as arguments can also accept [paths](https://nixos.org/manual/nix/stable/language/values.html#type-path) as arguments.
64 Such path arguments are implicitly coerced to file sets containing all files under that path:
···78 This is in contrast to using [paths in string interpolation](https://nixos.org/manual/nix/stable/language/values.html#type-path), which does add the entire referenced path to the store.
79 :::
8081+ ## Example {#sec-fileset-path-coercion-example}
8283 Assume we are in a local directory with a file hierarchy like this:
84 ```
···157158in {
159160+ /**
161 Create a file set from a path that may or may not exist:
162 - If the path does exist, the path is [coerced to a file set](#sec-fileset-path-coercion).
163 - If the path does not exist, a file set containing no files is returned.
164165+166+ # Inputs
167+168+ `path`
169+170+ : 1\. Function argument
171+172+ # Type
173174+ ```
175+ maybeMissing :: Path -> FileSet
176+ ```
177+178+ # Examples
179+ :::{.example}
180+ ## `lib.fileset.maybeMissing` usage example
181+182+ ```nix
183+ # All files in the current directory, but excluding main.o if it exists
184+ difference ./. (maybeMissing ./main.o)
185+ ```
186+187+ :::
188 */
189 maybeMissing =
190 path:
···200 else
201 _singleton path;
202203+ /**
204 Incrementally evaluate and trace a file set in a pretty way.
205 This function is only intended for debugging purposes.
206 The exact tracing format is unspecified and may change.
···211212 This variant is useful for tracing file sets in the Nix repl.
21300214215+ # Inputs
216+217+ `fileset`
218+219+ : The file set to trace.
220+221+ This argument can also be a path,
222+ which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
223+224+ `val`
225+226+ : The value to return.
0227228+ # Type
229+230+ ```
231+ trace :: FileSet -> Any -> Any
232+ ```
233+234+ # Examples
235+ :::{.example}
236+ ## `lib.fileset.trace` usage example
237+238+ ```nix
239+ trace (unions [ ./Makefile ./src ./tests/run.sh ]) null
240+ =>
241+ trace: /home/user/src/myProject
242+ trace: - Makefile (regular)
243+ trace: - src (all files in directory)
244+ trace: - tests
245+ trace: - run.sh (regular)
246+ null
247+ ```
248+249+ :::
250+ */
251+ trace = fileset:
252 let
253 # "fileset" would be a better name, but that would clash with the argument name,
254 # and we cannot change that because of https://github.com/nix-community/nixdoc/issues/76
···258 (_printFileset actualFileset)
259 (x: x);
260261+ /**
262 Incrementally evaluate and trace a file set in a pretty way.
263 This function is only intended for debugging purposes.
264 The exact tracing format is unspecified and may change.
···268269 This variant is useful for tracing file sets passed as arguments to other functions.
270271+272+ # Inputs
273+274+ `fileset`
275+276+ : The file set to trace and return.
277+278+ This argument can also be a path,
279+ which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
280+281+ # Type
282+283+ ```
284+ traceVal :: FileSet -> FileSet
285+ ```
286287+ # Examples
288+ :::{.example}
289+ ## `lib.fileset.traceVal` usage example
290+291+ ```nix
292+ toSource {
293+ root = ./.;
294+ fileset = traceVal (unions [
295+ ./Makefile
296+ ./src
297+ ./tests/run.sh
298+ ]);
299+ }
300+ =>
301+ trace: /home/user/src/myProject
302+ trace: - Makefile (regular)
303+ trace: - src (all files in directory)
304+ trace: - tests
305+ trace: - run.sh (regular)
306+ "/nix/store/...-source"
307+ ```
308+309+ :::
310 */
311+ traceVal = fileset:
0000000312 let
313 # "fileset" would be a better name, but that would clash with the argument name,
314 # and we cannot change that because of https://github.com/nix-community/nixdoc/issues/76
···320 # but that would then duplicate work for consumers of the fileset, because then they have to coerce it again
321 actualFileset;
322323+ /**
324 Add the local files contained in `fileset` to the store as a single [store path](https://nixos.org/manual/nix/stable/glossary#gloss-store-path) rooted at `root`.
325326 The result is the store path as a string-like value, making it usable e.g. as the `src` of a derivation, or in string interpolation:
···333334 The name of the store path is always `source`.
335336+ # Inputs
00000000000000000000000337338+ Takes an attribute set with the following attributes
000000000339340+ `root` (Path; _required_)
000000000341342+ : The local directory [path](https://nixos.org/manual/nix/stable/language/values.html#type-path) that will correspond to the root of the resulting store path.
000000000343 Paths in [strings](https://nixos.org/manual/nix/stable/language/values.html#type-string), including Nix store paths, cannot be passed as `root`.
344 `root` has to be a directory.
345···347 Changing `root` only affects the directory structure of the resulting store path, it does not change which files are added to the store.
348 The only way to change which files get added to the store is by changing the `fileset` attribute.
349 :::
350+351+ `fileset` (FileSet; _required_)
352+353+ : The file set whose files to import into the store.
354 File sets can be created using other functions in this library.
355 This argument can also be a path,
356 which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
···359 If a directory does not recursively contain any file, it is omitted from the store path contents.
360 :::
361362+ # Type
363+364+ ```
365+ toSource :: {
366+ root :: Path,
367+ fileset :: FileSet,
368+ } -> SourceLike
369+ ```
370+371+ # Examples
372+ :::{.example}
373+ ## `lib.fileset.toSource` usage example
374+375+ ```nix
376+ # Import the current directory into the store
377+ # but only include files under ./src
378+ toSource {
379+ root = ./.;
380+ fileset = ./src;
381+ }
382+ => "/nix/store/...-source"
383+384+ # Import the current directory into the store
385+ # but only include ./Makefile and all files under ./src
386+ toSource {
387+ root = ./.;
388+ fileset = union
389+ ./Makefile
390+ ./src;
391+ }
392+ => "/nix/store/...-source"
393+394+ # Trying to include a file outside the root will fail
395+ toSource {
396+ root = ./.;
397+ fileset = unions [
398+ ./Makefile
399+ ./src
400+ ../LICENSE
401+ ];
402+ }
403+ => <error>
404+405+ # The root needs to point to a directory that contains all the files
406+ toSource {
407+ root = ../.;
408+ fileset = unions [
409+ ./Makefile
410+ ./src
411+ ../LICENSE
412+ ];
413+ }
414+ => "/nix/store/...-source"
415+416+ # The root has to be a local filesystem path
417+ toSource {
418+ root = "/nix/store/...-source";
419+ fileset = ./.;
420+ }
421+ => <error>
422+ ```
423+424+ :::
425+ */
426+ toSource = {
427+ root,
428 fileset,
429 }:
430 let
···480 };
481482483+ /**
484 The list of file paths contained in the given file set.
485486 :::{.note}
···494495 The resulting list of files can be turned back into a file set using [`lib.fileset.unions`](#function-library-lib.fileset.unions).
496497+498+ # Inputs
499+500+ `fileset`
501+502+ : The file set whose file paths to return. This argument can also be a path, which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
503+504+ # Type
505+506+ ```
507+ toList :: FileSet -> [ Path ]
508+ ```
509+510+ # Examples
511+ :::{.example}
512+ ## `lib.fileset.toList` usage example
513+514+ ```nix
515+ toList ./.
516+ [ ./README.md ./Makefile ./src/main.c ./src/main.h ]
517518+ toList (difference ./. ./src)
519+ [ ./README.md ./Makefile ]
520+ ```
521522+ :::
0523 */
524+ toList = fileset:
0000525 _toList (_coerce "lib.fileset.toList: Argument" fileset);
526527+ /**
528 The file set containing all files that are in either of two given file sets.
529 This is the same as [`unions`](#function-library-lib.fileset.unions),
530 but takes just two file sets instead of a list.
···533 The given file sets are evaluated as lazily as possible,
534 with the first argument being evaluated first if needed.
535536+537+ # Inputs
538+539+ `fileset1`
540+541+ : The first file set. This argument can also be a path, which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
542+543+ `fileset2`
544+545+ : The second file set. This argument can also be a path, which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
546+547+ # Type
548+549+ ```
550+ union :: FileSet -> FileSet -> FileSet
551+ ```
552553+ # Examples
554+ :::{.example}
555+ ## `lib.fileset.union` usage example
556+557+ ```nix
558+ # Create a file set containing the file `Makefile`
559+ # and all files recursively in the `src` directory
560+ union ./Makefile ./src
561+562+ # Create a file set containing the file `Makefile`
563+ # and the LICENSE file from the parent directory
564+ union ./Makefile ../LICENSE
565+ ```
566567+ :::
00568 */
569 union =
000570 fileset1:
000571 fileset2:
572 _unionMany
573 (_coerceMany "lib.fileset.union" [
···581 }
582 ]);
583584+ /**
585 The file set containing all files that are in any of the given file sets.
586 This is the same as [`union`](#function-library-lib.fileset.unions),
587 but takes a list of file sets instead of just two.
···590 The given file sets are evaluated as lazily as possible,
591 with earlier elements being evaluated first if needed.
59200593594+ # Inputs
00000595596+ `filesets`
597+598+ : A list of file sets. The elements can also be paths, which get [implicitly coerced to file sets](#sec-fileset-path-coercion).
599+600+ # Type
601602+ ```
603+ unions :: [ FileSet ] -> FileSet
604+ ```
605606+ # Examples
607+ :::{.example}
608+ ## `lib.fileset.unions` usage example
609+610+ ```nix
611+ # Create a file set containing selected files
612+ unions [
613+ # Include the single file `Makefile` in the current directory
614+ # This errors if the file doesn't exist
615+ ./Makefile
616+617+ # Recursively include all files in the `src/code` directory
618+ # If this directory is empty this has no effect
619+ ./src/code
620+621+ # Include the files `run.sh` and `unit.c` from the `tests` directory
622+ ./tests/run.sh
623+ ./tests/unit.c
624+625+ # Include the `LICENSE` file from the parent directory
626+ ../LICENSE
627+ ]
628+ ```
629+630+ :::
631 */
632 unions =
000633 filesets:
634 if ! isList filesets then
635 throw ''
···645 _unionMany
646 ];
647648+ /**
649 The file set containing all files that are in both of two given file sets.
650 See also [Intersection (set theory)](https://en.wikipedia.org/wiki/Intersection_(set_theory)).
651652 The given file sets are evaluated as lazily as possible,
653 with the first argument being evaluated first if needed.
654655+656+ # Inputs
657+658+ `fileset1`
659+660+ : The first file set. This argument can also be a path, which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
661+662+ `fileset2`
663+664+ : The second file set. This argument can also be a path, which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
665+666+ # Type
667+668+ ```
669+ intersection :: FileSet -> FileSet -> FileSet
670+ ```
671+672+ # Examples
673+ :::{.example}
674+ ## `lib.fileset.intersection` usage example
675676+ ```nix
677+ # Limit the selected files to the ones in ./., so only ./src and ./Makefile
678+ intersection ./. (unions [ ../LICENSE ./src ./Makefile ])
679+ ```
680+681+ :::
682 */
683 intersection =
000684 fileset1:
000685 fileset2:
686 let
687 filesets = _coerceMany "lib.fileset.intersection" [
···699 (elemAt filesets 0)
700 (elemAt filesets 1);
701702+ /**
703 The file set containing all files from the first file set that are not in the second file set.
704 See also [Difference (set theory)](https://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement).
705706 The given file sets are evaluated as lazily as possible,
707 with the first argument being evaluated first if needed.
708709+710+ # Inputs
711+712+ `positive`
713+714+ : The positive file set. The result can only contain files that are also in this file set. This argument can also be a path, which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
715+716+ `negative`
717+718+ : The negative file set. The result will never contain files that are also in this file set. This argument can also be a path, which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).
719+720+ # Type
721+722+ ```
723+ union :: FileSet -> FileSet -> FileSet
724+ ```
725+726+ # Examples
727+ :::{.example}
728+ ## `lib.fileset.difference` usage example
729+730+ ```nix
731+ # Create a file set containing all files from the current directory,
732+ # except ones under ./tests
733+ difference ./. ./tests
734735+ let
736+ # A set of Nix-related files
737+ nixFiles = unions [ ./default.nix ./nix ./tests/default.nix ];
738+ in
739+ # Create a file set containing all files under ./tests, except ones in `nixFiles`,
740+ # meaning only without ./tests/default.nix
741+ difference ./tests nixFiles
742+ ```
743744+ :::
000000745 */
746 difference =
00000747 positive:
00000748 negative:
749 let
750 filesets = _coerceMany "lib.fileset.difference" [
···762 (elemAt filesets 0)
763 (elemAt filesets 1);
764765+ /**
766 Filter a file set to only contain files matching some predicate.
7670000000000768769+ # Inputs
00770771+ `predicate`
0000772773+ : The predicate function to call on all files contained in given file set.
00000774 A file is included in the resulting file set if this function returns true for it.
775776 This function is called with an attribute set containing these attributes:
···787 `hasExt "gitignore"` is true.
788789 Other attributes may be added in the future.
790+791+ `path`
792+793+ : The path whose files to filter
794+795+ # Type
796+797+ ```
798+ fileFilter ::
799+ ({
800+ name :: String,
801+ type :: String,
802+ hasExt :: String -> Bool,
803+ ...
804+ } -> Bool)
805+ -> Path
806+ -> FileSet
807+ ```
808+809+ # Examples
810+ :::{.example}
811+ ## `lib.fileset.fileFilter` usage example
812+813+ ```nix
814+ # Include all regular `default.nix` files in the current directory
815+ fileFilter (file: file.name == "default.nix") ./.
816+817+ # Include all non-Nix files from the current directory
818+ fileFilter (file: ! file.hasExt "nix") ./.
819+820+ # Include all files that start with a "." in the current directory
821+ fileFilter (file: hasPrefix "." file.name) ./.
822+823+ # Include all regular files (not symlinks or others) in the current directory
824+ fileFilter (file: file.type == "regular") ./.
825+ ```
826+827+ :::
828+ */
829+ fileFilter =
830 predicate:
0831 path:
832 if ! isFunction predicate then
833 throw ''
···846 else
847 _fileFilter predicate path;
848849+ /**
850+ Create a file set with the same files as a `lib.sources`-based value.
851+ This does not import any of the files into the store.
852+853+ This can be used to gradually migrate from `lib.sources`-based filtering to `lib.fileset`.
854+855+ A file set can be turned back into a source using [`toSource`](#function-library-lib.fileset.toSource).
856+857+ :::{.note}
858+ File sets cannot represent empty directories.
859+ Turning the result of this function back into a source using `toSource` will therefore not preserve empty directories.
860+ :::
8610862863+ # Inputs
864865+ `source`
000866867+ : 1\. Function argument
868+869+ # Type
870+871+ ```
872 fromSource :: SourceLike -> FileSet
873+ ```
874875+ # Examples
876+ :::{.example}
877+ ## `lib.fileset.fromSource` usage example
878+879+ ```nix
880 # There's no cleanSource-like function for file sets yet,
881 # but we can just convert cleanSource to a file set and use it that way
882 toSource {
···901 ./Makefile
902 ./src
903 ]);
904+ ```
905+906+ :::
907 */
908 fromSource = source:
909 let
···932 # If there's no filter, no need to run the expensive conversion, all subpaths will be included
933 _singleton path;
934935+ /**
936 Create a file set containing all [Git-tracked files](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository) in a repository.
937938 This function behaves like [`gitTrackedWith { }`](#function-library-lib.fileset.gitTrackedWith) - using the defaults.
939940+941+ # Inputs
942+943+ `path`
944945+ : The [path](https://nixos.org/manual/nix/stable/language/values#type-path) to the working directory of a local Git repository.
946+ This directory must contain a `.git` file or subdirectory.
0947948+ # Type
949+950+ ```
951+ gitTracked :: Path -> FileSet
952+ ```
953+954+ # Examples
955+ :::{.example}
956+ ## `lib.fileset.gitTracked` usage example
957+958+ ```nix
959+ # Include all files tracked by the Git repository in the current directory
960+ gitTracked ./.
961+962+ # Include only files tracked by the Git repository in the parent directory
963+ # that are also in the current directory
964+ intersection ./. (gitTracked ../.)
965+ ```
966+967+ :::
968 */
969 gitTracked =
0000970 path:
971 _fromFetchGit
972 "gitTracked"
···974 path
975 {};
976977+ /**
978 Create a file set containing all [Git-tracked files](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository) in a repository.
979 The first argument allows configuration with an attribute set,
980 while the second argument is the path to the Git working tree.
···998 This may change in the future.
999 :::
10001001+1002+ # Inputs
1003+1004+ `options` (attribute set)
1005+ : `recurseSubmodules` (optional, default: `false`)
1006+ : Whether to recurse into [Git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) to also include their tracked files.
1007+ If `true`, this is equivalent to passing the [--recurse-submodules](https://git-scm.com/docs/git-ls-files#Documentation/git-ls-files.txt---recurse-submodules) flag to `git ls-files`.
1008+1009+ `path`
1010+ : The [path](https://nixos.org/manual/nix/stable/language/values#type-path) to the working directory of a local Git repository.
1011+ This directory must contain a `.git` file or subdirectory.
1012+1013+ # Type
1014+1015+ ```
1016+ gitTrackedWith :: { recurseSubmodules :: Bool ? false } -> Path -> FileSet
1017+ ```
1018+1019+ # Examples
1020+ :::{.example}
1021+ ## `lib.fileset.gitTrackedWith` usage example
10221023+ ```nix
1024+ # Include all files tracked by the Git repository in the current directory
1025+ # and any submodules under it
1026+ gitTracked { recurseSubmodules = true; } ./.
1027+ ```
1028+1029+ :::
1030 */
1031 gitTrackedWith =
1032 {
000001033 recurseSubmodules ? false,
1034 }:
00001035 path:
1036 if ! isBool recurseSubmodules then
1037 throw "lib.fileset.gitTrackedWith: Expected the attribute `recurseSubmodules` of the first argument to be a boolean, but it's a ${typeOf recurseSubmodules} instead."