diff options
author | Vincent Ambo <tazjin@google.com> | 2019-11-15T14·52+0000 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2019-11-15T14·52+0000 |
commit | 4d852e2ef73a0901a3426ae5ab93232b6a0a8ed2 (patch) | |
tree | 99a1a6bfe12b89fc6e034f0dd0de58371a436ffd /read-tree.nix | |
parent | 8e53dec88cf7a09da48be66312f6ad0a1f1d3022 (diff) |
feat(build): Add initial read-tree.nix implementation
This file can read a directory tree into a package set structure, paving the way for getting rid of top-level mapping in default.nix.
Diffstat (limited to 'read-tree.nix')
-rw-r--r-- | read-tree.nix | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/read-tree.nix b/read-tree.nix new file mode 100644 index 000000000000..00a2e738bd9d --- /dev/null +++ b/read-tree.nix @@ -0,0 +1,67 @@ +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 |