path: { pkgs, ... } @ args: let inherit (builtins) attrNames filter head isString listToAttrs map match readDir toPath toString; attrsToList = attrs: map (name: { inherit name; value = attrs."${name}"; }) (attrNames 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