nix-filter/default.nix
2021-04-23 18:53:18 +02:00

75 lines
1.9 KiB
Nix

# This is a pure and self-contained library
rec {
# Default to filter when calling this lib.
__functor = self: filter;
# A proper source filter
filter =
{
# Base path to include
path
, # Derivation name
name ? "source"
, # Only allow the following path matches.
#
# Allows all files by default.
allow ? [ (_:_: true) ]
, # Ignore the following matches
deny ? [ ]
}:
let
# If an argument to allow or deny is a path, transform it to a matcher.
#
# This probably needs more work, I don't think that it works on
# sub-folders.
toMatcher = f:
let
# Push these here to memoize the result
path_ = toString f;
path__ = "${toString path}/${f}";
in
if builtins.isFunction f then f
else if builtins.isPath f then (path: _: path_ == path)
else if builtins.isString f then (path: _: path__ == path)
else
throw "Unsupported type ${builtins.typeOf f}";
allow_ = map toMatcher allow;
deny_ = map toMatcher deny;
in
builtins.path {
inherit name path;
filter = path: type:
(builtins.any (f: f path type) allow_) &&
(!builtins.any (f: f path type) deny_);
};
# Match paths with the given extension
matchExt = ext:
path: type:
_hasSuffix ".${ext}" path;
# Used to debug matchers.
debugMatch = label: fn:
path: type:
let
ret = fn path type;
in
builtins.trace "label=${label} path=${path} type=${type} ret=${toString ret}"
ret;
# Lib stuff
_hasSuffix =
# Suffix to check for
suffix:
# Input string
content:
let
lenContent = builtins.stringLength content;
lenSuffix = builtins.stringLength suffix;
in
lenContent >= lenSuffix
&& builtins.substring (lenContent - lenSuffix) lenContent content == suffix;
}