Skip to content

Commit

Permalink
lib.fileset.fileFilter: Restrict second argument to paths
Browse files Browse the repository at this point in the history
While this change is backwards-incompatible, I think it's okay because:
- The `fileFilter` function is not yet in a stable NixOS release, it was only merged about [a month ago](NixOS/nixpkgs#257356).
  - All public uses of the function on GitHub only pass a path
- Any `fileFilter pred fileset` can also be expressed as `intersection fileset (fileFilter pred path)` without loss of functionality.
  - This is furthermore pointed out in the new error message when a file set is passed
  • Loading branch information
infinisil committed Nov 15, 2023
1 parent 1c81ce8 commit 186213b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 20 deletions.
20 changes: 15 additions & 5 deletions lib/fileset/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ in {
type :: String,
...
} -> Bool)
-> FileSet
-> Path
-> FileSet
Example:
Expand Down Expand Up @@ -397,14 +397,24 @@ in {
Other attributes may be added in the future.
*/
predicate:
# The file set to filter based on the predicate function
fileset:
# The path whose files to filter
path:
if ! isFunction predicate then
throw ''
lib.fileset.fileFilter: First argument is of type ${typeOf predicate}, but it should be a function instead.''
else if ! isPath path then
if path._type or "" == "fileset" then
throw ''
lib.fileset.fileFilter: Second argument is a file set, but it should be a path instead.
If you need to filter files in a file set, use `intersection fileset (fileFilter pred ./.)` instead.''
else
throw ''
lib.fileset.fileFilter: Second argument is of type ${typeOf path}, but it should be a path instead.''
else if ! pathExists path then
throw ''
lib.fileset.fileFilter: Second argument (${toString path}) is a path that does not exist.''
else
_fileFilter predicate
(_coerce "lib.fileset.fileFilter: Second argument" fileset);
_fileFilter predicate path;

/*
The file set containing all files that are in both of two given file sets.
Expand Down
33 changes: 18 additions & 15 deletions lib/fileset/internal.nix
Original file line number Diff line number Diff line change
Expand Up @@ -786,9 +786,9 @@ rec {
_differenceTree (path + "/${name}") lhsValue (rhs.${name} or null)
) (_directoryEntries path lhs);

# Filters all files in a file set based on a predicate
# Type: ({ name, type, ... } -> Bool) -> FileSet -> FileSet
_fileFilter = predicate: fileset:
# Filters all files in a path based on a predicate
# Type: ({ name, type, ... } -> Bool) -> Path -> FileSet
_fileFilter = predicate: root:
let
# Check the predicate for a single file
# Type: String -> String -> filesetTree
Expand All @@ -807,19 +807,22 @@ rec {

# Check the predicate for all files in a directory
# Type: Path -> filesetTree
fromDir = path: tree:
mapAttrs (name: subtree:
if isAttrs subtree || subtree == "directory" then
fromDir (path + "/${name}") subtree
else if subtree == null then
null
fromDir = path:
mapAttrs (name: type:
if type == "directory" then
fromDir (path + "/${name}")
else
fromFile name subtree
) (_directoryEntries path tree);
fromFile name type
) (readDir path);

rootType = pathType root;
in
if fileset._internalIsEmptyWithoutBase then
_emptyWithoutBase
if rootType == "directory" then
_create root (fromDir root)
else
_create fileset._internalBase
(fromDir fileset._internalBase fileset._internalTree);
# Single files are turned into a directory containing that file or nothing.
_create (dirOf root) {
${baseNameOf root} =
fromFile (baseNameOf root) rootType;
};
}

0 comments on commit 186213b

Please sign in to comment.