When given two lists each of which are conditional on basis of mkIf
, how to merge those two lists (akin to mkMerge
for sets)?
I have run into the following pattern several times now and I cannot seem to find documentation explaining how to idiomatically solve this.
Say you’re starting out with this snippet:
someConfigValue = mkIf (cfg.condition1) [ "some value 1" ];
Then you add another conditional value:
someConfigValue = [
(mkIf (cfg.condition1) [ "some value 1" ])
(mkIf (cfg.condition2) [ "some value 2" ])
];
In the specific case at hand (trying to pass this to systemd.services.<name>.LoadCredential
) I get the following error since the internal representation of the two mkIf
values are sets:
error: cannot coerce a set to a string
Using mkMerge
does not seem to work either (since it takes a list of sets and merges those sets).
I could replace the mkIf
s with optionals
and then concatenate the lists using ++
, but that’s dumping all the module logic, so I’m not sure whether that’s the right choice here.
>Solution :
Ordinarily, I would use optionals
for something like this.
If you really want to make it mergable, I think you can instead put whateverService.serviceConfig.LoadCredentials = [ "cred 1" ];
on one side of a merge and whateverService.serviceConfig.LoadCredentials = [ "cred 2" ];
on the other side, and the standard merging logic will put them in the same list.
This more or less results in just pushing someConfigValue
in one level:
config = mkMerge [
(mkIf (cfg.condition1) { someConfigValue = [ "some value 1" ]; })
(mkIf (cfg.condition2) { someConfigValue = [ "some value 2" ]; })
];
Which is more or less how I tend to see mkIf
used: It predicates whole sections of config at the top level, rather than individual values inside of config. Individual values tend to use things like optionals
or optionalString
.