Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ let
hiPrioSet;
inherit (sources) pathType pathIsDirectory cleanSourceFilter
cleanSource sourceByRegex sourceFilesBySuffices
commitIdFromGitRepo;
commitIdFromGitRepo cleanSourceWith;
inherit (modules) evalModules closeModules unifyModuleSyntax
applyIfFunction unpackSubmodule packSubmodule mergeModules
mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
Expand Down
31 changes: 26 additions & 5 deletions lib/sources.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,35 @@ rec {
(type == "symlink" && lib.hasPrefix "result" baseName)
);

cleanSource = builtins.filterSource cleanSourceFilter;
cleanSource = src: cleanSourceWith { filter = cleanSourceFilter; inherit src; };

# Like `builtins.filterSource`, except it will compose with itself,
# allowing you to chain multiple calls together without any
# intermediate copies being put in the nix store.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An example would be nice.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

#
# lib.cleanSourceWith f (lib.cleanSourceWith g ./.) # Succeeds!
# builtins.filterSource f (builtins.filterSource g ./.) # Fails!
cleanSourceWith = { filter, src }:
let
isFiltered = src ? _isLibCleanSourceWith;
origSrc = if isFiltered then src.origSrc else src;
filter' = if isFiltered then name: type: filter name type && src.filter name type else filter;
in {
inherit origSrc;
filter = filter';
outPath = builtins.filterSource filter' origSrc;
_isLibCleanSourceWith = true;
};

# Filter sources by a list of regular expressions.
#
# E.g. `src = sourceByRegex ./my-subproject [".*\.py$" "^database.sql$"]`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC this is actually a misleading example. I believe this will not recurse into directories unless they match these regexes. So in many cases this example would actually filter out everything and leave you with an empty folder. I need to double-check that this is the case but that's how it has appeared in my experience.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize this is tangential to your actual change. Feel free to ignore while I look into opening a separate PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've confirmed this. I'll open a separate PR.

sourceByRegex = src: regexes: builtins.filterSource (path: type:
let relPath = lib.removePrefix (toString src + "/") (toString path);
in lib.any (re: builtins.match re relPath != null) regexes) src;
sourceByRegex = src: regexes: cleanSourceWith {
filter = (path: type:
let relPath = lib.removePrefix (toString src + "/") (toString path);
in lib.any (re: builtins.match re relPath != null) regexes);
inherit src;
};

# Get all files ending with the specified suffices from the given
# directory or its descendants. E.g. `sourceFilesBySuffices ./dir
Expand All @@ -42,7 +63,7 @@ rec {
let filter = name: type:
let base = baseNameOf (toString name);
in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
in builtins.filterSource filter path;
in cleanSourceWith { inherit filter; src = path; };


# Get the commit id of a git repo
Expand Down