srghma
February 3, 2019, 4:29pm
1
nix
Does someone know such function that merges list of records
if all values to merge are records - merge them recursively
if all values to merge are arrays - concatenate arrays
If values can’t be merged - the latter value is preferred
Example 1:
recursiveMergeAttrs [
{ a = "x"; c = "m"; list = [1]; }
{ a = "y"; b = "z"; list = [2]; }
]
returns
{ a = "y"; b = "z"; c="m"; list = [1 2] }
Example 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 ]; }
2 Likes
vcunat
February 4, 2019, 3:00pm
2
The nixos module system does this. But you need to declare types of the fields, as on different occasions you need “different kind” of merging.
1 Like
volth
February 5, 2019, 12:31am
3
This would be a nice addition next to lib.recursiveUpdate
The module system, yes, requires type declaration, and in some cases leads to infinite recursion
(I recently hit i.r. trying to do
config =
lib.mkMerge (map (x: { networking = { .......; }; })
config.henet-tunnelbroker.tunnels
);
while a simple merge function could work here, so I ended up with lib.recursiveUpdate
+ ad-hoc handling of arrays)
1 Like
Has anything been added to lib
since? Seems like a useful function to have to merge deeply nested attrsets with lists.
edit: I guess a PR would be the way to go if not.
3 Likes
I would really need this! I don’t have the capacities to create the PR myself right now, though. Does it make sense to create a feature request on GitHub?
Use lib.mkMerge
. As said above, the module system handles this.
You might be interested in infuse
, which can do this (and many other things) without dragging in the whole module system.
infuse.nix is a “deep” version of both .override and .overrideAttrs. It generalizes both lib.pipe and recursiveUpdate. It can be used as a leaner, untyped alternative to lib.modules (if you want dynamic typechecking, it works well with yants )
There are two mirrors:
https://codeberg.org/amjoseph/infuse.nix (prettier markdown rendering, PRs disabled)
https://git.sr.ht/~amjoseph/infuse.nix (canonical repo; send patches here)
A tutorial will be added soon, along with the release of several p…