lib: add ini configuration generator
Many configurations are INI-style files. Attribute sets can be mapped rather painlessly to the INI format. This adds a function toINI inside a new generators library section. Also, unit tests for the default values are provided.
This commit is contained in:
parent
ba73dbbda6
commit
61311665cb
@ -27,6 +27,7 @@ let
|
||||
|
||||
# misc
|
||||
debug = import ./debug.nix;
|
||||
generators = import ./generators.nix;
|
||||
misc = import ./deprecated.nix;
|
||||
|
||||
# domain-specific
|
||||
@ -39,7 +40,7 @@ in
|
||||
customisation maintainers meta sources
|
||||
modules options types
|
||||
licenses platforms systems
|
||||
debug misc
|
||||
debug generators misc
|
||||
sandbox fetchers;
|
||||
}
|
||||
# !!! don't include everything at top-level; perhaps only the most
|
||||
|
53
lib/generators.nix
Normal file
53
lib/generators.nix
Normal file
@ -0,0 +1,53 @@
|
||||
/* Functions that generate widespread config file
|
||||
* formats from nix data structures.
|
||||
* Tests can be found in ./tests.nix
|
||||
*/
|
||||
with import ./trivial.nix;
|
||||
let
|
||||
libStr = import ./strings.nix;
|
||||
libAttr = import ./attrsets.nix;
|
||||
|
||||
flipMapAttrs = flip libAttr.mapAttrs;
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
/* Generates an INI-style config file from an
|
||||
* attrset of sections to an attrset of key-value pairs.
|
||||
*
|
||||
* generators.toINI {} {
|
||||
* foo = { hi = "${pkgs.hello}"; ciao = "bar"; };
|
||||
* baz = { "also, integers" = 42; };
|
||||
* }
|
||||
*
|
||||
*> [baz]
|
||||
*> also, integers=42
|
||||
*>
|
||||
*> [foo]
|
||||
*> ciao=bar
|
||||
*> hi=/nix/store/y93qql1p5ggfnaqjjqhxcw0vqw95rlz0-hello-2.10
|
||||
*
|
||||
* The mk* configuration attributes can generically change
|
||||
* the way sections and key-value strings are generated.
|
||||
*
|
||||
* For more examples see the test cases in ./tests.nix.
|
||||
*/
|
||||
toINI = {
|
||||
# apply transformations (e.g. escapes) to section names
|
||||
mkSectionName ? (name: libStr.escape [ "[" "]" ] name),
|
||||
# format a setting line from key and value
|
||||
mkKeyValue ? (k: v: "${libStr.escape ["="] k}=${toString v}")
|
||||
}: attrsOfAttrs:
|
||||
let
|
||||
# map function to string for each key val
|
||||
mapAttrsToStringsSep = sep: mapFn: attrs:
|
||||
libStr.concatStringsSep sep
|
||||
(libAttr.mapAttrsToList mapFn attrs);
|
||||
mkLine = k: v: mkKeyValue k v + "\n";
|
||||
mkSection = sectName: sectValues: ''
|
||||
[${mkSectionName sectName}]
|
||||
'' + libStr.concatStrings (libAttr.mapAttrsToList mkLine sectValues);
|
||||
in
|
||||
# map input to ini sections
|
||||
mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
|
||||
}
|
@ -130,4 +130,55 @@ runTests {
|
||||
expected = false;
|
||||
};
|
||||
|
||||
|
||||
/* Generator tests */
|
||||
# these tests assume attributes are converted to lists
|
||||
# in alphabetical order
|
||||
|
||||
testToINIEmpty = {
|
||||
expr = generators.toINI {} {};
|
||||
expected = "";
|
||||
};
|
||||
|
||||
testToINIEmptySection = {
|
||||
expr = generators.toINI {} { foo = {}; bar = {}; };
|
||||
expected = ''
|
||||
[bar]
|
||||
|
||||
[foo]
|
||||
'';
|
||||
};
|
||||
|
||||
testToINIDefaultEscapes = {
|
||||
expr = generators.toINI {} {
|
||||
"no [ and ] allowed unescaped" = {
|
||||
"and also no = in keys" = 42;
|
||||
};
|
||||
};
|
||||
expected = ''
|
||||
[no \[ and \] allowed unescaped]
|
||||
and also no \= in keys=42
|
||||
'';
|
||||
};
|
||||
|
||||
testToINIDefaultFull = {
|
||||
expr = generators.toINI {} {
|
||||
"section 1" = {
|
||||
attribute1 = 5;
|
||||
x = "Me-se JarJar Binx";
|
||||
};
|
||||
"foo[]" = {
|
||||
"he\\h=he" = "this is okay";
|
||||
};
|
||||
};
|
||||
expected = ''
|
||||
[foo\[\]]
|
||||
he\h\=he=this is okay
|
||||
|
||||
[section 1]
|
||||
attribute1=5
|
||||
x=Me-se JarJar Binx
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user