about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nixos/doc/manual/development/settings-options.xml12
-rw-r--r--pkgs/pkgs-lib/formats.nix26
-rw-r--r--pkgs/pkgs-lib/tests/formats.nix16
3 files changed, 51 insertions, 3 deletions
diff --git a/nixos/doc/manual/development/settings-options.xml b/nixos/doc/manual/development/settings-options.xml
index 7795d7c804454..7292cac62b707 100644
--- a/nixos/doc/manual/development/settings-options.xml
+++ b/nixos/doc/manual/development/settings-options.xml
@@ -50,7 +50,7 @@
        </varlistentry>
        <varlistentry>
          <term>
-           <varname>pkgs.formats.ini</varname> { <replaceable>listsAsDuplicateKeys</replaceable> ? false, ... }
+           <varname>pkgs.formats.ini</varname> { <replaceable>listsAsDuplicateKeys</replaceable> ? false, <replaceable>listToValue</replaceable> ? null, ... }
          </term>
          <listitem>
            <para>
@@ -66,6 +66,16 @@
                    </para>
                  </listitem>
                </varlistentry>
+               <varlistentry>
+                 <term>
+                   <varname>listToValue</varname>
+                 </term>
+                 <listitem>
+                   <para>
+                     A function for turning a list of values into a single value.
+                   </para>
+                 </listitem>
+               </varlistentry>
              </variablelist>
             It returns a set with INI-specific attributes <varname>type</varname> and <varname>generate</varname> as specified <link linkend='pkgs-formats-result'>below</link>.
            </para>
diff --git a/pkgs/pkgs-lib/formats.nix b/pkgs/pkgs-lib/formats.nix
index 14589f8ecdc3a..4b6982f387d08 100644
--- a/pkgs/pkgs-lib/formats.nix
+++ b/pkgs/pkgs-lib/formats.nix
@@ -56,7 +56,16 @@ rec {
       };
     };
 
-  ini = { listsAsDuplicateKeys ? false, ... }@args: {
+  ini = {
+    # Represents lists as duplicate keys
+    listsAsDuplicateKeys ? false,
+    # Alternative to listsAsDuplicateKeys, converts list to non-list
+    # listToValue :: [IniAtom] -> IniAtom
+    listToValue ? null,
+    ...
+    }@args:
+    assert !listsAsDuplicateKeys || listToValue == null;
+    {
 
     type = with lib.types; let
 
@@ -74,12 +83,25 @@ rec {
           coercedTo singleIniAtom lib.singleton (listOf singleIniAtom) // {
             description = singleIniAtom.description + " or a list of them for duplicate keys";
           }
+        else if listToValue != null then
+          coercedTo singleIniAtom lib.singleton (nonEmptyListOf singleIniAtom) // {
+            description = singleIniAtom.description + " or a non-empty list of them";
+          }
         else
           singleIniAtom;
 
     in attrsOf (attrsOf iniAtom);
 
-    generate = name: value: pkgs.writeText name (lib.generators.toINI args value);
+    generate = name: value:
+      let
+        transformedValue =
+          if listToValue != null
+          then
+            lib.mapAttrs (section: lib.mapAttrs (key: val:
+              if lib.isList val then listToValue val else val
+            )) value
+          else value;
+      in pkgs.writeText name (lib.generators.toINI (removeAttrs args ["listToValue"]) transformedValue);
 
   };
 
diff --git a/pkgs/pkgs-lib/tests/formats.nix b/pkgs/pkgs-lib/tests/formats.nix
index 16b760a5ada14..2c117e29e9ba9 100644
--- a/pkgs/pkgs-lib/tests/formats.nix
+++ b/pkgs/pkgs-lib/tests/formats.nix
@@ -124,6 +124,22 @@ in runBuildTests {
     '';
   };
 
+  testIniListToValue = {
+    drv = evalFormat formats.ini { listToValue = concatMapStringsSep ", " (generators.mkValueStringDefault {}); } {
+      foo = {
+        bar = [ null true "test" 1.2 10 ];
+        baz = false;
+        qux = "qux";
+      };
+    };
+    expected = ''
+      [foo]
+      bar=null, true, test, 1.200000, 10
+      baz=false
+      qux=qux
+    '';
+  };
+
   testTomlAtoms = {
     drv = evalFormat formats.toml {} {
       false = false;