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
87 changes: 27 additions & 60 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,6 @@ let

leaves =
let
listFilesRecursive =
x:
if isImportTree x then
x.files
else if hasOutPath x then
listFilesRecursive x.outPath
else if isDirectory x then
listDirFilesRecursive x
else
[ x ];

nixFilter = andNot (hasInfix "/_") (hasSuffix ".nix");

Expand All @@ -79,57 +69,39 @@ let

otherFilter = and filterf (if initf != null then initf else (_: true));

filter = x: if isPathLike x then pathFilter x else otherFilter x;

isFileRelative =
root:
{ file, rel }:
if file != null && hasPrefix root file then
{
file = null;
rel = removePrefix root file;
}
# Filter an explicit user supplied path:
filterFiles =
x:
if hasOutPath x then
filterFiles x.outPath
else if isImportTree x then
# Use the foreign import-tree filtering so that relative path are correctly handled:
(x.filter filterf).files
else if isPathLike x then
if builtins.readFileType x == "directory" then
let
dir = toString x;
# Apply pathFilter to relative path from the user-supplied directory:
relativize = file: removePrefix dir (toString file);
in
builtins.filter (compose pathFilter relativize) (listDirFilesRecursive x)
else
# For explicit user-supplied (non-directory) files, ignore filter:
x
else if otherFilter x then
x
else
{ inherit file rel; };
getFileRelative = { file, rel }: if rel == null then file else rel;

# Strip the first matching root-directory prefix from a file, yielding a
# path relative to that root (or the file itself if none match). Folds the
# `{ file, rel }` state directly over the roots — once a root matches,
# `file` becomes null and later roots are no-ops.
makeRelative =
roots:
let
dirs = builtins.map builtins.toString (builtins.filter isDirectory (flatten roots));
in
file:
getFileRelative (
builtins.foldl' (acc: root: isFileRelative root acc) {
file = builtins.toString file;
rel = null;
} dirs
);

rootRelative =
roots:
let
mkRel = makeRelative roots;
in
x: if isPathLike x then mkRel x else x;
[ ];
in
root:
let
roots = flatten [
paths
root
];
files = flatten (map listFilesRecursive roots);
relativize = rootRelative [
paths
root
];
files = flatten (map filterFiles roots);
in
map mapf (builtins.filter (compose filter relativize) files);
map mapf files;

in
result;
Expand All @@ -139,9 +111,6 @@ let
# lib.lists.flatten
flatten = x: if builtins.isList x then builtins.concatMap flatten x else [ x ];

# lib.strings.hasPrefix
hasPrefix = pre: s: builtins.substring 0 (builtins.stringLength pre) s == pre;

# lib.strings.removePrefix
removePrefix =
pre: s:
Expand Down Expand Up @@ -207,8 +176,6 @@ let
attrs: k: f:
attrs // { ${k} = f attrs.${k}; };

isDirectory = and (x: builtins.readFileType x == "directory") isPathLike;

isPathLike = x: builtins.isPath x || builtins.isString x || hasOutPath x;

hasOutPath = and (x: x ? outPath) builtins.isAttrs;
Expand All @@ -232,7 +199,7 @@ let
initial = {
# Accumulated configuration
api = { };
mapf = (i: i);
mapf = i: i;
filterf = _: true;
paths = [ ];
scoped = { };
Expand Down Expand Up @@ -277,11 +244,11 @@ let
withLib = _lib: mergeAttrs { };
initFilter = initf: mergeAttrs { inherit initf; };
pipeTo = pipef: mergeAttrs { inherit pipef; };
leaves = mergeAttrs { pipef = (i: i); };
leaves = mergeAttrs { pipef = i: i; };
leafs =
builtins.warn "import-tree.leafs has been deprecated. Use import-tree.leaves instead."
(mergeAttrs {
pipef = (i: i);
pipef = i: i;
});

# Applies empty (for already path-configured trees)
Expand Down
16 changes: 16 additions & 0 deletions tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,17 @@ in
];
};

import-tree."test can take other import-trees as if they were paths - hidden paths variant" = {
expr = lit.leaves [
(it.addPath [ ./tree/a/b/_c ])
./tree/modules/hello-world
];
expected = [
./tree/a/b/_c/d/e.nix
./tree/modules/hello-world/mod.nix
];
};

import-tree."test can be used in submodule" = {
expr =
(lib.evalModules {
Expand All @@ -275,6 +286,11 @@ in
expected = [ ./tree/a/b/_c/d/e.nix ];
};

leaves."test loads root file from hidden directory" = {
expr = lit.leaves ./tree/a/b/_c/d/e.nix;
expected = [ ./tree/a/b/_c/d/e.nix ];
};

scoped."test adds attrs via scopedImport" = {
expr =
(lib.evalModules {
Expand Down
Loading