39 lines
1.6 KiB
Nix
39 lines
1.6 KiB
Nix
|
{ lib }:
|
||
|
|
||
|
# This Nix expression allows filtering a local directory by specifying dirRootsToInclude, dirsToExclude and filesToInclude.
|
||
|
# It also filters out symlinks to result folders created by nix-build, as well as backup/swap/generated files
|
||
|
|
||
|
let
|
||
|
inherit (lib)
|
||
|
any compare compareLists elem elemAt hasPrefix length min splitString take;
|
||
|
|
||
|
isPathAllowed = allowedPath: path:
|
||
|
let
|
||
|
count = min (length allowedPathElements) (length pathElements);
|
||
|
pathElements = splitString "/" path;
|
||
|
allowedPathElements = splitString "/" allowedPath;
|
||
|
pathElementsSubset = take count pathElements;
|
||
|
allowedPathElementsSubset = take count allowedPathElements;
|
||
|
in (compareLists compare allowedPathElementsSubset pathElementsSubset) == 0;
|
||
|
|
||
|
mkFilter = { dirRootsToInclude, # Relative paths of directories to include
|
||
|
dirsToExclude ? [ ], # Base names of directories to exclude
|
||
|
filesToInclude ? [ ], # Relative path of files to include
|
||
|
filesToExclude ? [ ], # Relative path of files to exclude
|
||
|
root }:
|
||
|
path: type:
|
||
|
let
|
||
|
baseName = baseNameOf (toString path);
|
||
|
subpath = elemAt (splitString "${toString root}/" path) 1;
|
||
|
spdir = elemAt (splitString "/" subpath) 0;
|
||
|
|
||
|
in lib.cleanSourceFilter path type && (
|
||
|
(type != "directory" && (elem spdir filesToInclude) && !(elem spdir filesToExclude)) ||
|
||
|
# check if any part of the directory path is described in dirRootsToInclude
|
||
|
((any (dirRootToInclude: isPathAllowed dirRootToInclude subpath) dirRootsToInclude) && ! (
|
||
|
# Filter out version control software files/directories
|
||
|
(type == "directory" && (elem baseName dirsToExclude))
|
||
|
)));
|
||
|
|
||
|
in mkFilter
|