diff options
author | Profpatsch <mail@profpatsch.de> | 2022-05-05T22·32+0200 |
---|---|---|
committer | Profpatsch <mail@profpatsch.de> | 2022-05-05T22·43+0000 |
commit | 0c51608f6c11fd8e15679d77e7a9ae8c3a51fe78 (patch) | |
tree | 530e7a1bac93acec64362da199575d269ac42d60 | |
parent | 9dac44846696ccdd9cd60359b8ee864f4a20b3f1 (diff) |
feat(users/Profpatsch): add toINI r/4012
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>
-rw-r--r-- | users/Profpatsch/toINI.nix | 79 |
1 files changed, 79 insertions, 0 deletions
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 |