merge: cleanup/document

This commit is contained in:
colin 2023-01-09 11:47:39 +00:00
parent 6ca3e7086e
commit 5af55ecdbf

View File

@ -31,11 +31,11 @@ rec {
let let
# define the current path, but nothing more. # define the current path, but nothing more.
curLevel = lib.setAttrByPath path {}; curLevel = lib.setAttrByPath path {};
# `take` will either set: # `take curLevel` will act one of two ways here:
# - { $path = path } => { $path = {} }; # - { $path = f.$path; } => { $path = {}; };
# - { $path.next = path.next } => { $path = { next = ?; } } # - { $path.subAttr = f.$path.subAttr; } => { $path = { subAttr = ?; }; }
# so, index $path into the output of `take`, # so, index $path into the output of `take`,
# and if it has any attrs that means we're interested in those too. # and if it has any attrs (like `subAttr`) that means we're interested in those too.
nextLevel = lib.getAttrFromPath path (take curLevel); nextLevel = lib.getAttrFromPath path (take curLevel);
in in
builtins.attrNames nextLevel; builtins.attrNames nextLevel;
@ -49,10 +49,7 @@ rec {
in if subNames == [] then in if subNames == [] then
[ path ] [ path ]
else else
let lib.concatMap (name: findTerminalPaths take (path ++ [name])) subNames;
terminalsPerChild = builtins.map (name: findTerminalPaths take (path ++ [name])) subNames;
in
lib.concatLists terminalsPerChild;
# ensures that all nodes in the attrset from the root to and including the given path # ensures that all nodes in the attrset from the root to and including the given path
# are ordinary attrs -- if they exist. # are ordinary attrs -- if they exist.
@ -64,19 +61,15 @@ rec {
items = lib.pushDownProperties i; items = lib.pushDownProperties i;
# now items is a list where every element is undecorated at the toplevel. # now items is a list where every element is undecorated at the toplevel.
# e.g. each item is an ordinary attrset or primitive. # e.g. each item is an ordinary attrset or primitive.
in # we still need to discharge the *rest* of the path though, for every item.
if path == [] then name = lib.head path;
items downstream = lib.tail path;
dischargeDownstream = it: if path != [] && it ? name then
builtins.map (v: it // { "${name}" = v; }) (dischargeToPath downstream it."${name}")
else else
let [ it ];
name = lib.head path; in
downstream = lib.tail path; lib.concatMap dischargeDownstream items;
dischargeItem = it: if it ? name then
builtins.map (v: it // { "${name}" = v; }) (dischargeToPath downstream it."${name}")
else
[ it ];
in
lib.concatMap dischargeItem items;
# discharge many items but only over one path. # discharge many items but only over one path.
# Type: dischargeItemsToPaths :: [Attrs] -> String -> [Attrs] # Type: dischargeItemsToPaths :: [Attrs] -> String -> [Attrs]
@ -96,9 +89,12 @@ rec {
# check that attrset `i` contains no terminals other than those specified in (or direct ancestors of) paths # check that attrset `i` contains no terminals other than those specified in (or direct ancestors of) paths
assertNoExtraPaths = paths: i: assertNoExtraPaths = paths: i:
let let
clearPath = acc: path: lib.recursiveUpdate acc (lib.setAttrByPath path null); # since the act of discharging should have forced all the relevant data out to the leaves,
remainder = builtins.foldl' clearPath i paths; # we just set each expected terminal to null (initializing the parents when necessary)
expected-remainder = builtins.foldl' clearPath {} paths; # and that gives a standard value for any fully-consumed items that we can do equality comparisons with.
wipePath = acc: path: lib.recursiveUpdate acc (lib.setAttrByPath path null);
remainder = builtins.foldl' wipePath i paths;
expected-remainder = builtins.foldl' wipePath {} paths;
in in
assert remainder == expected-remainder; true; assert remainder == expected-remainder; true;
} }