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:
parent
9dac448466
commit
0c51608f6c
1 changed files with 79 additions and 0 deletions
79
users/Profpatsch/toINI.nix
Normal file
79
users/Profpatsch/toINI.nix
Normal 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
|
Loading…
Reference in a new issue