Merge pull request #20507 from Profpatsch/lib-ini-generator
lib: File generators from Nix Expressions
This commit is contained in:
commit
1dd7bb2bb6
@ -8,6 +8,15 @@
|
|||||||
The nixpkgs repository has several utility functions to manipulate Nix expressions.
|
The nixpkgs repository has several utility functions to manipulate Nix expressions.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<section xml:id="sec-overrides">
|
||||||
|
<title>Overriding</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Sometimes one wants to override parts of
|
||||||
|
<literal>nixpkgs</literal>, e.g. derivation attributes, the results of
|
||||||
|
derivations or even the whole package set.
|
||||||
|
</para>
|
||||||
|
|
||||||
<section xml:id="sec-pkgs-overridePackages">
|
<section xml:id="sec-pkgs-overridePackages">
|
||||||
<title>pkgs.overridePackages</title>
|
<title>pkgs.overridePackages</title>
|
||||||
|
|
||||||
@ -258,6 +267,40 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
|||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-generators">
|
||||||
|
<title>Generators</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Generators are functions that create file formats from nix
|
||||||
|
data structures, e. g. for configuration files.
|
||||||
|
There are generators available for: <literal>INI</literal>,
|
||||||
|
<literal>JSON</literal> and <literal>YAML</literal>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
All generators follow a similar call interface: <code>generatorName
|
||||||
|
configFunctions data</code>, where <literal>configFunctions</literal> is a
|
||||||
|
set of user-defined functions that format variable parts of the content.
|
||||||
|
They each have common defaults, so often they do not need to be set
|
||||||
|
manually. An example is <code>mkSectionName ? (name: libStr.escape [ "[" "]"
|
||||||
|
] name)</code> from the <literal>INI</literal> generator. It gets the name
|
||||||
|
of a section and returns a sanitized name. The default
|
||||||
|
<literal>mkSectionName</literal> escapes <literal>[</literal> and
|
||||||
|
<literal>]</literal> with a backslash.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<note><para>Nix store paths can be converted to strings by enclosing a
|
||||||
|
derivation attribute like so: <code>"${drv}"</code>.</para></note>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Detailed documentation for each generator can be found in
|
||||||
|
<literal>lib/generators.nix</literal>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section xml:id="sec-fhs-environments">
|
<section xml:id="sec-fhs-environments">
|
||||||
<title>buildFHSUserEnv</title>
|
<title>buildFHSUserEnv</title>
|
||||||
|
@ -27,6 +27,7 @@ let
|
|||||||
|
|
||||||
# misc
|
# misc
|
||||||
debug = import ./debug.nix;
|
debug = import ./debug.nix;
|
||||||
|
generators = import ./generators.nix;
|
||||||
misc = import ./deprecated.nix;
|
misc = import ./deprecated.nix;
|
||||||
|
|
||||||
# domain-specific
|
# domain-specific
|
||||||
@ -39,7 +40,7 @@ in
|
|||||||
customisation maintainers meta sources
|
customisation maintainers meta sources
|
||||||
modules options types
|
modules options types
|
||||||
licenses platforms systems
|
licenses platforms systems
|
||||||
debug misc
|
debug generators misc
|
||||||
sandbox fetchers;
|
sandbox fetchers;
|
||||||
}
|
}
|
||||||
# !!! don't include everything at top-level; perhaps only the most
|
# !!! don't include everything at top-level; perhaps only the most
|
||||||
|
72
lib/generators.nix
Normal file
72
lib/generators.nix
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/* Functions that generate widespread file
|
||||||
|
* formats from nix data structures.
|
||||||
|
*
|
||||||
|
* They all follow a similar interface:
|
||||||
|
* generator { config-attrs } data
|
||||||
|
*
|
||||||
|
* Tests can be found in ./tests.nix
|
||||||
|
* Documentation in the manual, #sec-generators
|
||||||
|
*/
|
||||||
|
with import ./trivial.nix;
|
||||||
|
let
|
||||||
|
libStr = import ./strings.nix;
|
||||||
|
libAttr = import ./attrsets.nix;
|
||||||
|
|
||||||
|
flipMapAttrs = flip libAttr.mapAttrs;
|
||||||
|
in
|
||||||
|
|
||||||
|
rec {
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
|
||||||
|
/* Generates JSON from an arbitrary (non-function) value.
|
||||||
|
* For more information see the documentation of the builtin.
|
||||||
|
*/
|
||||||
|
toJSON = {}: builtins.toJSON;
|
||||||
|
|
||||||
|
|
||||||
|
/* YAML has been a strict superset of JSON since 1.2, so we
|
||||||
|
* use toJSON. Before it only had a few differences referring
|
||||||
|
* to implicit typing rules, so it should work with older
|
||||||
|
* parsers as well.
|
||||||
|
*/
|
||||||
|
toYAML = {}@args: toJSON args;
|
||||||
|
}
|
@ -130,4 +130,78 @@ runTests {
|
|||||||
expected = false;
|
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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
/* right now only invocation check */
|
||||||
|
testToJSONSimple =
|
||||||
|
let val = {
|
||||||
|
foobar = [ "baz" 1 2 3 ];
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
expr = generators.toJSON {} val;
|
||||||
|
# trival implementation
|
||||||
|
expected = builtins.toJSON val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* right now only invocation check */
|
||||||
|
testToYAMLSimple =
|
||||||
|
let val = {
|
||||||
|
list = [ { one = 1; } { two = 2; } ];
|
||||||
|
all = 42;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
expr = generators.toYAML {} val;
|
||||||
|
# trival implementation
|
||||||
|
expected = builtins.toJSON val;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user