{ lib, ... }: let /* Generate an INI-style config file from an attrset * specifying the global section (no header), and a * list of sections which contain name/value pairs. * * generators.toINI {} { * globalSection = [ * { name = "someGlobalKey"; value = "hi"; } * ]; * sections = [ * { name = "foo"; value = [ * { name = "hi"; value = "${pkgs.hello}"; } * { name = "ciao"; value = "bar"; } * ]; * } * { name = "baz"; * value = [ { name = "also, integers"; value = 42; } ]; * } * ]; * } * *> someGlobalKey=hi *> *> [foo] *> hi=/nix/store/y93qql1p5ggfnaqjjqhxcw0vqw95rlz0-hello-2.10 *> ciao=bar *> *> [baz] *> also, integers=42 *> * * The mk* configuration attributes can generically change * the way sections and key-value strings are generated. * * Order of the sections and of keys is preserved, * duplicate keys are allowed. */ toINI = { # apply transformations (e.g. escapes) to section names mkSectionName ? (name: lib.strings.escape [ "[" "]" ] name) , # format a setting line from key and value mkKeyValue ? lib.generators.mkKeyValueDefault { } "=" , }: { globalSection, sections }: let mkSection = sectName: sectValues: '' [${mkSectionName sectName}] '' + toKeyValue { inherit mkKeyValue; } sectValues; # map input to ini sections mkSections = lib.strings.concatMapStringsSep "\n" ({ name, value }: mkSection name value) sections; mkGlobalSection = if globalSection == [ ] then "" else toKeyValue { inherit mkKeyValue; } globalSection + "\n"; in mkGlobalSection + mkSections; /* Generate a name-value-style config file from a list. * * mkKeyValue is the same as in toINI. */ toKeyValue = { mkKeyValue ? lib.generators.mkKeyValueDefault { } "=" , }: let mkLine = k: v: mkKeyValue k v + "\n"; mkLines = k: v: [ (mkLine k v) ]; in nameValues: lib.strings.concatStrings (lib.concatLists (map ({ name, value }: mkLines name value) nameValues)); in toINI