summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--lib/generators.nix18
-rw-r--r--lib/tests/misc.nix12
2 files changed, 24 insertions, 6 deletions
diff --git a/lib/generators.nix b/lib/generators.nix
index a64e94bd5cbd..240a19789b54 100644
--- a/lib/generators.nix
+++ b/lib/generators.nix
@@ -76,10 +76,14 @@ rec {
    * mkKeyValue is the same as in toINI.
    */
   toKeyValue = {
-    mkKeyValue ? mkKeyValueDefault {} "="
-  }: attrs:
-    let mkLine = k: v: mkKeyValue k v + "\n";
-    in libStr.concatStrings (libAttr.mapAttrsToList mkLine attrs);
+    mkKeyValue ? mkKeyValueDefault {} "=",
+    listsAsDuplicateKeys ? false
+  }:
+  let mkLine = k: v: mkKeyValue k v + "\n";
+      mkLines = if listsAsDuplicateKeys
+        then k: v: map (mkLine k) (if lib.isList v then v else [v])
+        else k: v: [ (mkLine k v) ];
+  in attrs: libStr.concatStrings (lib.concatLists (libAttr.mapAttrsToList mkLines attrs));
 
 
   /* Generate an INI-style config file from an
@@ -106,7 +110,9 @@ rec {
     # apply transformations (e.g. escapes) to section names
     mkSectionName ? (name: libStr.escape [ "[" "]" ] name),
     # format a setting line from key and value
-    mkKeyValue    ? mkKeyValueDefault {} "="
+    mkKeyValue    ? mkKeyValueDefault {} "=",
+    # allow lists as values for duplicate keys
+    listsAsDuplicateKeys ? false
   }: attrsOfAttrs:
     let
         # map function to string for each key val
@@ -115,7 +121,7 @@ rec {
             (libAttr.mapAttrsToList mapFn attrs);
         mkSection = sectName: sectValues: ''
           [${mkSectionName sectName}]
-        '' + toKeyValue { inherit mkKeyValue; } sectValues;
+        '' + toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } sectValues;
     in
       # map input to ini sections
       mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix
index 01ff5ecf1485..739c5d5fe15d 100644
--- a/lib/tests/misc.nix
+++ b/lib/tests/misc.nix
@@ -348,6 +348,18 @@ runTests {
     '';
   };
 
+  testToINIDuplicateKeys = {
+    expr = generators.toINI { listsAsDuplicateKeys = true; } { foo.bar = true; baz.qux = [ 1 false ]; };
+    expected = ''
+      [baz]
+      qux=1
+      qux=false
+
+      [foo]
+      bar=true
+    '';
+  };
+
   testToINIDefaultEscapes = {
     expr = generators.toINI {} {
       "no [ and ] allowed unescaped" = {