feat(users/Profpatsch): add toINI

This is a morph of the `pkgs.lib.generators.toINIWithGlobalSection`
function, which is simplified, inlined, and takes lists instead of
attrsets. This makes the key ordering stable and is easy to generate
from dhall.

Ideally I’d upstream it at one point (in the sense that
`generators.toINI` can also take lists), but that will be a lot more
work that is not necessary atm.

Change-Id: I7d6c129cfee9faedb62f69d479e59a6e05bb7ac6
Reviewed-on: https://cl.tvl.fyi/c/depot/+/5529
Tested-by: BuildkiteCI
Reviewed-by: Profpatsch <mail@profpatsch.de>
This commit is contained in:
Profpatsch 2022-05-06 00:32:49 +02:00
parent 9dac448466
commit 0c51608f6c

View file

@ -0,0 +1,79 @@
{ 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