From 0c51608f6c11fd8e15679d77e7a9ae8c3a51fe78 Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Fri, 6 May 2022 00:32:49 +0200 Subject: feat(users/Profpatsch): add toINI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- users/Profpatsch/toINI.nix | 79 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 users/Profpatsch/toINI.nix (limited to 'users/Profpatsch') diff --git a/users/Profpatsch/toINI.nix b/users/Profpatsch/toINI.nix new file mode 100644 index 000000000000..537505d30bbc --- /dev/null +++ b/users/Profpatsch/toINI.nix @@ -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 -- cgit 1.4.1