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:
Profpatsch 2016-11-06 01:51:13 +01:00
parent ba73dbbda6
commit 61311665cb
3 changed files with 106 additions and 1 deletions

View File

@ -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
View 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;
}

View File

@ -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
'';
};
}