tvl-depot/read-tree.nix
Vincent Ambo 050b3aabaf fix(read-tree): Only add marker to imported attribute sets
Sometimes things that get imported are (intentionally) not attribute
sets, e.g. for build functions.

Those should not be merged with the marker because, well, that's not
possible.
2019-12-10 14:46:05 +00:00

54 lines
1.4 KiB
Nix

args: initPath:
let
inherit (builtins)
attrNames
baseNameOf
filter
head
length
listToAttrs
map
match
isAttrs
readDir;
argsWithPath = parts: args // {
locatedAt = parts;
};
# The marker is added to every set that was imported directly by
# readTree.
importWithMark = path: parts:
let imported = import path (argsWithPath parts);
in if (isAttrs imported)
then imported // { __readTree = true; }
else imported;
nixFileName = file:
let res = match "(.*)\.nix" file;
in if res == null then null else head res;
readTree = path: parts:
let
dir = readDir path;
self = importWithMark path parts;
joinChild = c: path + ("/" + c);
# Import non-empty subdirectories
filterDir = f: dir."${f}" == "directory";
children = map (c: {
name = c;
value = readTree (joinChild c) (parts ++ [ c ]);
}) (filter filterDir (attrNames dir));
# Import Nix files
nixFiles = filter (f: f != null) (map nixFileName (attrNames dir));
nixChildren = map (c: let p = joinChild (c + ".nix"); in {
name = c;
value = importWithMark p (parts ++ [ c ]);
}) nixFiles;
in if dir ? "default.nix"
then self // (listToAttrs children)
else listToAttrs (nixChildren ++ children);
in readTree initPath [ (baseNameOf initPath) ]