-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
lib.fileset should have a way to filter directories #271307
Description
Problem
Sometimes one needs to filter out directories with a specific name throughout the source directory.
For example, you might have a structure like
- foo
- target
- bar
- baz
- target
- qux
- target
And you want to remove all of the target directories.
Currently, the lib.fileset library does not have any function to make this work. To do that currently you need to work around it with either:
-
lib.fileset.fromSource (lib.sources.cleanSourceWith { src = ./. filter = pathString: type: # untested.. type != "directory" || baseNameOf pathString != "target"; }
- Some recursive
readDirandlib.fileset.unionsI don't want to write out
Requirements
- It must not recurse into filtered-out directories for performance reasons
- It must be intuitive to use
Potential solutions
Directory name predicate
directoryFilter (dir: dir.name == "target") ./.This creates a file set containing all files within directories named "target". E.g. ./foo/target/some/file.txt would be included because one of foo, target and some satisfies the predicate. Does it satisfy the requirements?
-
✔️ It doesn't need to recurse into the filtered out directories, but the selection needs to be inverted to actually filter out the ones with
target:difference ./. (directoryFilter (dir: dir.name == "target" ) ./.)
-
❌ This is not intuitive, because one might expect an inverted predicate to return the complement set:
directoryFilter (dir: dir.name != "target" ) ./.
But this doesn't work: This would include
./foo/target/some/file.txt, sincefoosatisfies the predicate.
Give the fileFilter predicate access to the file's directories
Like already described in #269504. This would allow filtering certain directories:
fileFilter (file:
# Only include files whose directory components don't have `target`
! elem "target" file.dirComponents
) ./.This way ./foo/target/some/file.nix would not be included, because target is in ./foo/target/some. Does it satisfy the requirements?
- ❌ No, this does have to recurse for every file, because the predicate needs files. So this would be very slow.
- ✔️ Yes this is intuitive. One can also invert the predicate and get the expected result.
Does a solution satisfying both requirements exist?
I don't know yet
This issue is sponsored by Antithesis ✨
Metadata
Metadata
Assignees
Labels
Fields
Give feedbackProjects
Status