1
0
Fork 0
mirror of https://git.sr.ht/~goorzhel/turboprop synced 2024-12-14 11:37:37 +00:00

Parametrize, exhaustively document flattenTree

This commit is contained in:
Antonio Gurgel 2024-08-10 12:45:51 -07:00
parent 4956f2f769
commit d6c9c75891
2 changed files with 41 additions and 25 deletions

View file

@ -49,32 +49,48 @@
(parseYAMLsFile yamlPath)
);
# Borrowed from divnix/digga and made more generic:
# https://github.com/divnix/digga/blob/baa54f8/src/importers.nix#L2-L59
# Borrowed from divnix/digga, with minor modifications:
# - Slash separators instead of periods, because `output.sh`
# will use these values as paths to build the derivation.
# - Look for functions (half-built service modules), not paths.
flattenTree = tree: let
op = sum: path: val: let
pathStr = builtins.concatStringsSep "/" path;
in
if builtins.isFunction val
then
(sum
// {
"${pathStr}" = val;
})
else if builtins.isAttrs val
then
(recurse sum path val)
else
sum; # ignore val
recurse = sum: path: val:
#
# Normally I dislike writing code-rephrasing comments, but every time I come
# across this function I burn 10m mentally reparsing it.
# - Input:
# - tree (attrs): Arbitrarily-nested elements, e.g.:
# {"a" = {"b" = <...>;}; "c" = <...>;}
# - pathSep (str): Path separator to use in output.
# - isLeaf (any -> bool): Determines "value" halves
# of output's KV pairs.
# - Output: flat attrset of functions, e.g.:
# {"a/b" = <thunk>; "c" = <thunk>;}
flattenTree = {
tree,
pathSep ? "/",
isLeaf ? builtins.isFunction,
}: let
# Contains the `foldl'` that forms the core of this function.
# Inputs:
# - acc (attrs): The accumulator.
# - path ([str]): `cursor`'s path in `tree`, e.g.: ["a" "b"].
# - cursor (any): A value in `tree` under inspection.
recurse = acc: path: cursor:
builtins.foldl'
(sum: key: op sum (path ++ [key]) val.${key})
sum
(builtins.attrNames val);
(acc: key: op acc (path ++ [key]) cursor.${key})
acc
(builtins.attrNames cursor);
# Modifies accumulator according to cursor's type.
# If `cursor` is on a leaf, append to `acc` the key-value pair of
# the char-separated path and the leaf.
# If `cursor` is on an attrset, recurse into it.
# Otherwise, return accumulator unmodified.
op = acc: path: cursor: let
pathStr = builtins.concatStringsSep pathSep path;
in
if isLeaf cursor
then acc // {"${pathStr}" = cursor;}
else if builtins.isAttrs cursor
then recurse acc path cursor
else acc; # ignore value
in
recurse {} [] tree;
}

View file

@ -111,7 +111,7 @@ in {
paths = [];
namespaces = [];
}
(lib.flattenTree modules);
(lib.flattenTree {tree = modules;});
namespaces = {
namespaces, # list of names