Does someone know such function that merges list of records
recursiveMergeAttrs [
{ a = "x"; c = "m"; list = [1]; }
{ a = "y"; b = "z"; list = [2]; }
]
returns
{ a = "y"; b = "z"; c="m"; list = [1 2] }
recursiveMergeAttrs [
{
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/hda";
}
{
boot.loader.grub.device = "";
}
]
returns
{
boot.loader.grub.enable = true;
boot.loader.grub.device = "";
}
P.S.
recursiveUpdate is not working
recursiveMergeAttrs = listOfAttrsets: lib.fold (attrset: acc: lib.recursiveUpdate attrset acc) {} listOfAttrsets
recursiveMergeAttrs [ { a = "x"; c = "m"; list = [1]; } { a = "y"; b = "z"; list = [2]; } ]
returns
{ a = "y"; b = "z"; c = "m"; list = [ 2 ]; }
Did it
{ lib, ... }:
with lib;
/*
Merges list of records, concatenates arrays, if two values can't be merged - the latter is preferred
Example 1:
recursiveMerge [
{ a = "x"; c = "m"; list = [1]; }
{ a = "y"; b = "z"; list = [2]; }
]
returns
{ a = "y"; b = "z"; c="m"; list = [1 2] }
Example 2:
recursiveMerge [
{
a.a = [1];
a.b = 1;
a.c = [1 1];
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/hda";
}
{
a.a = [2];
a.b = 2;
a.c = [1 2];
boot.loader.grub.device = "";
}
]
returns
{
a = {
a = [ 1 2 ];
b = 2;
c = [ 1 2 ];
};
boot = {
loader = {
grub = {
device = "";
enable = true;
};
};
};
}
*/
let
recursiveMerge = attrList:
let f = attrPath:
zipAttrsWith (n: values:
if tail values == []
then head values
else if all isList values
then unique (concatLists values)
else if all isAttrs values
then f (attrPath ++ [n]) values
else last values
);
in f [] attrList;
in
recursiveMerge