forked from lix-project/lix
primops: Move toXML to primops/toXML.cc
Change-Id: I8da29345903015e38b9832f0d9b4011dc5bbb17b
This commit is contained in:
parent
a93af3f92f
commit
c96f5bcdd2
|
@ -103,6 +103,7 @@ libexpr_sources = files(
|
|||
'primops/path.cc',
|
||||
'primops/string.cc',
|
||||
'primops/system.cc',
|
||||
'primops/toXML.cc',
|
||||
'primops/types.cc',
|
||||
'value/context.cc',
|
||||
)
|
||||
|
|
|
@ -186,110 +186,6 @@ static void derivationStrictInternal(EvalState & state, const std::string & name
|
|||
/* Convert the argument (which can be any Nix expression) to an XML
|
||||
representation returned in a string. Not all Nix expressions can
|
||||
be sensibly or completely represented (e.g., functions). */
|
||||
static void prim_toXML(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
{
|
||||
std::ostringstream out;
|
||||
NixStringContext context;
|
||||
printValueAsXML(state, true, false, *args[0], out, context, pos);
|
||||
v.mkString(out.str(), context);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_toXML({
|
||||
.name = "__toXML",
|
||||
.args = {"e"},
|
||||
.doc = R"(
|
||||
Return a string containing an XML representation of *e*. The main
|
||||
application for `toXML` is to communicate information with the
|
||||
builder in a more structured format than plain environment
|
||||
variables.
|
||||
|
||||
Here is an example where this is the case:
|
||||
|
||||
```nix
|
||||
{ stdenv, fetchurl, libxslt, jira, uberwiki }:
|
||||
|
||||
stdenv.mkDerivation (rec {
|
||||
name = "web-server";
|
||||
|
||||
buildInputs = [ libxslt ];
|
||||
|
||||
builder = builtins.toFile "builder.sh" "
|
||||
source $stdenv/setup
|
||||
mkdir $out
|
||||
echo "$servlets" | xsltproc ${stylesheet} - > $out/server-conf.xml ①
|
||||
";
|
||||
|
||||
stylesheet = builtins.toFile "stylesheet.xsl" ②
|
||||
"<?xml version='1.0' encoding='UTF-8'?>
|
||||
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
|
||||
<xsl:template match='/'>
|
||||
<Configure>
|
||||
<xsl:for-each select='/expr/list/attrs'>
|
||||
<Call name='addWebApplication'>
|
||||
<Arg><xsl:value-of select=\"attr[@name = 'path']/string/@value\" /></Arg>
|
||||
<Arg><xsl:value-of select=\"attr[@name = 'war']/path/@value\" /></Arg>
|
||||
</Call>
|
||||
</xsl:for-each>
|
||||
</Configure>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
";
|
||||
|
||||
servlets = builtins.toXML [ ③
|
||||
{ path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
|
||||
{ path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
|
||||
];
|
||||
})
|
||||
```
|
||||
|
||||
The builder is supposed to generate the configuration file for a
|
||||
[Jetty servlet container](http://jetty.mortbay.org/). A servlet
|
||||
container contains a number of servlets (`*.war` files) each
|
||||
exported under a specific URI prefix. So the servlet configuration
|
||||
is a list of sets containing the `path` and `war` of the servlet
|
||||
(①). This kind of information is difficult to communicate with the
|
||||
normal method of passing information through an environment
|
||||
variable, which just concatenates everything together into a
|
||||
string (which might just work in this case, but wouldn’t work if
|
||||
fields are optional or contain lists themselves). Instead the Nix
|
||||
expression is converted to an XML representation with `toXML`,
|
||||
which is unambiguous and can easily be processed with the
|
||||
appropriate tools. For instance, in the example an XSLT stylesheet
|
||||
(at point ②) is applied to it (at point ①) to generate the XML
|
||||
configuration file for the Jetty server. The XML representation
|
||||
produced at point ③ by `toXML` is as follows:
|
||||
|
||||
```xml
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<expr>
|
||||
<list>
|
||||
<attrs>
|
||||
<attr name="path">
|
||||
<string value="/bugtracker" />
|
||||
</attr>
|
||||
<attr name="war">
|
||||
<path value="/nix/store/d1jh9pasa7k2...-jira/lib/atlassian-jira.war" />
|
||||
</attr>
|
||||
</attrs>
|
||||
<attrs>
|
||||
<attr name="path">
|
||||
<string value="/wiki" />
|
||||
</attr>
|
||||
<attr name="war">
|
||||
<path value="/nix/store/y6423b1yi4sx...-uberwiki/uberwiki.war" />
|
||||
</attr>
|
||||
</attrs>
|
||||
</list>
|
||||
</expr>
|
||||
```
|
||||
|
||||
Note that we used the `toFile` built-in to write the builder and
|
||||
the stylesheet “inline” in the Nix expression. The path of the
|
||||
stylesheet is spliced into the builder using the syntax `xsltproc
|
||||
${stylesheet}`.
|
||||
)",
|
||||
.fun = prim_toXML,
|
||||
});
|
||||
|
||||
|
||||
/* Store a string in the Nix store as a source file that can be used
|
||||
|
|
115
src/libexpr/primops/toXML.cc
Normal file
115
src/libexpr/primops/toXML.cc
Normal file
|
@ -0,0 +1,115 @@
|
|||
#include "primops.hh"
|
||||
#include "value-to-xml.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* builtins.toXML
|
||||
*/
|
||||
|
||||
static void prim_toXML(EvalState & state, const PosIdx pos, Value ** args, Value & v)
|
||||
{
|
||||
std::ostringstream out;
|
||||
NixStringContext context;
|
||||
printValueAsXML(state, true, false, *args[0], out, context, pos);
|
||||
v.mkString(out.str(), context);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_toXML({
|
||||
.name = "__toXML",
|
||||
.args = {"e"},
|
||||
.doc = R"(
|
||||
Return a string containing an XML representation of *e*. The main
|
||||
application for `toXML` is to communicate information with the
|
||||
builder in a more structured format than plain environment
|
||||
variables.
|
||||
|
||||
Here is an example where this is the case:
|
||||
|
||||
```nix
|
||||
{ stdenv, fetchurl, libxslt, jira, uberwiki }:
|
||||
|
||||
stdenv.mkDerivation (rec {
|
||||
name = "web-server";
|
||||
|
||||
buildInputs = [ libxslt ];
|
||||
|
||||
builder = builtins.toFile "builder.sh" "
|
||||
source $stdenv/setup
|
||||
mkdir $out
|
||||
echo "$servlets" | xsltproc ${stylesheet} - > $out/server-conf.xml ①
|
||||
";
|
||||
|
||||
stylesheet = builtins.toFile "stylesheet.xsl" ②
|
||||
"<?xml version='1.0' encoding='UTF-8'?>
|
||||
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
|
||||
<xsl:template match='/'>
|
||||
<Configure>
|
||||
<xsl:for-each select='/expr/list/attrs'>
|
||||
<Call name='addWebApplication'>
|
||||
<Arg><xsl:value-of select=\"attr[@name = 'path']/string/@value\" /></Arg>
|
||||
<Arg><xsl:value-of select=\"attr[@name = 'war']/path/@value\" /></Arg>
|
||||
</Call>
|
||||
</xsl:for-each>
|
||||
</Configure>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
";
|
||||
|
||||
servlets = builtins.toXML [ ③
|
||||
{ path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
|
||||
{ path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
|
||||
];
|
||||
})
|
||||
```
|
||||
|
||||
The builder is supposed to generate the configuration file for a
|
||||
[Jetty servlet container](http://jetty.mortbay.org/). A servlet
|
||||
container contains a number of servlets (`*.war` files) each
|
||||
exported under a specific URI prefix. So the servlet configuration
|
||||
is a list of sets containing the `path` and `war` of the servlet
|
||||
(①). This kind of information is difficult to communicate with the
|
||||
normal method of passing information through an environment
|
||||
variable, which just concatenates everything together into a
|
||||
string (which might just work in this case, but wouldn’t work if
|
||||
fields are optional or contain lists themselves). Instead the Nix
|
||||
expression is converted to an XML representation with `toXML`,
|
||||
which is unambiguous and can easily be processed with the
|
||||
appropriate tools. For instance, in the example an XSLT stylesheet
|
||||
(at point ②) is applied to it (at point ①) to generate the XML
|
||||
configuration file for the Jetty server. The XML representation
|
||||
produced at point ③ by `toXML` is as follows:
|
||||
|
||||
```xml
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<expr>
|
||||
<list>
|
||||
<attrs>
|
||||
<attr name="path">
|
||||
<string value="/bugtracker" />
|
||||
</attr>
|
||||
<attr name="war">
|
||||
<path value="/nix/store/d1jh9pasa7k2...-jira/lib/atlassian-jira.war" />
|
||||
</attr>
|
||||
</attrs>
|
||||
<attrs>
|
||||
<attr name="path">
|
||||
<string value="/wiki" />
|
||||
</attr>
|
||||
<attr name="war">
|
||||
<path value="/nix/store/y6423b1yi4sx...-uberwiki/uberwiki.war" />
|
||||
</attr>
|
||||
</attrs>
|
||||
</list>
|
||||
</expr>
|
||||
```
|
||||
|
||||
Note that we used the `toFile` built-in to write the builder and
|
||||
the stylesheet “inline” in the Nix expression. The path of the
|
||||
stylesheet is spliced into the builder using the syntax `xsltproc
|
||||
${stylesheet}`.
|
||||
)",
|
||||
.fun = prim_toXML,
|
||||
});
|
||||
|
||||
}
|
Loading…
Reference in a new issue