68 lines
1.6 KiB
Nix
68 lines
1.6 KiB
Nix
|
path: self: super:
|
||
|
|
||
|
let
|
||
|
inherit (builtins)
|
||
|
attrNames
|
||
|
attrValues
|
||
|
filter
|
||
|
head
|
||
|
isString
|
||
|
listToAttrs
|
||
|
map
|
||
|
match
|
||
|
readDir
|
||
|
tail
|
||
|
toPath
|
||
|
toString;
|
||
|
|
||
|
args = { pkgs = self; };
|
||
|
|
||
|
zipAttrs = names: values:
|
||
|
if (names == []) || (values == [])
|
||
|
then []
|
||
|
else [{
|
||
|
name = head names;
|
||
|
value = head values;
|
||
|
}] ++ zipAttrs (tail names) (tail values);
|
||
|
|
||
|
attrsToList = attrs: zipAttrs (attrNames attrs) (attrValues attrs);
|
||
|
|
||
|
isFile = s: s == "regular";
|
||
|
isDir = s: s == "directory";
|
||
|
|
||
|
joinPath = p: f: toPath ((toString p) + "/" + f);
|
||
|
|
||
|
isNixFile = file:
|
||
|
let res = match "(.*)\.nix" file;
|
||
|
in if res == null then null else head res;
|
||
|
|
||
|
filterNixFiles = dir:
|
||
|
let files = filter (e: isFile e.value) dir;
|
||
|
nixFiles = map (f: {
|
||
|
# Name and value are intentionally flipped to get the
|
||
|
# correct attribute set structure back out
|
||
|
name = isNixFile f.name;
|
||
|
value = f.name; # i.e. the path
|
||
|
}) files;
|
||
|
in filter (f: isString f.name) nixFiles;
|
||
|
|
||
|
traverse = path: dir:
|
||
|
let nixFiles = filterNixFiles dir;
|
||
|
imported = map (f: {
|
||
|
inherit (f) name;
|
||
|
value = import (joinPath path f.value) args;
|
||
|
}) nixFiles;
|
||
|
dirs = map (d: {
|
||
|
inherit (d) name;
|
||
|
value = readTree (joinPath path d.name);
|
||
|
}) (filter (e: isDir e.value) dir);
|
||
|
in listToAttrs (imported ++ dirs);
|
||
|
|
||
|
importOr = path: dir: f:
|
||
|
if dir ? "default.nix"
|
||
|
then import path args
|
||
|
else f path (attrsToList dir);
|
||
|
|
||
|
readTree = path: importOr path (readDir path) traverse;
|
||
|
in readTree path
|