aboutsummaryrefslogtreecommitdiff
path: root/doc/manual/writing-nix-expressions.xml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/manual/writing-nix-expressions.xml')
-rw-r--r--doc/manual/writing-nix-expressions.xml586
1 files changed, 3 insertions, 583 deletions
diff --git a/doc/manual/writing-nix-expressions.xml b/doc/manual/writing-nix-expressions.xml
index ce6c1f4ad..c4bc35cc7 100644
--- a/doc/manual/writing-nix-expressions.xml
+++ b/doc/manual/writing-nix-expressions.xml
@@ -1,6 +1,7 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
- xml:id='chap-writing-nix-expressions'>
+ xml:id='chap-writing-nix-expressions'
+ xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Writing Nix Expressions</title>
@@ -1339,589 +1340,8 @@ command-line argument. See <xref linkend='sec-standard-environment'
</section>
-<section><title>Built-in functions</title>
-<para>This section lists the functions and constants built into the
-Nix expression evaluator. (The built-in function
-<function>derivation</function> is discussed above.) Some built-ins,
-such as <function>derivation</function>, are always in scope of every
-Nix expression; you can just access them right away. But to prevent
-polluting the namespace too much, most built-ins are not in scope.
-Instead, you can access them through the <varname>builtins</varname>
-built-in value, which is an attribute set that contains all built-in
-functions and values. For instance, <function>derivation</function>
-is also available as <function>builtins.derivation</function>.</para>
-
-
-<variablelist>
-
-
- <varlistentry><term><function>abort</function> <replaceable>s</replaceable></term>
-
- <listitem><para>Abort Nix expression evaluation, print error
- message <replaceable>s</replaceable>.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>builtins.add</function>
- <replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
-
- <listitem><para>Return the sum of the integers
- <replaceable>e1</replaceable> and
- <replaceable>e2</replaceable>.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>builtins.attrNames</function>
- <replaceable>attrs</replaceable></term>
-
- <listitem><para>Return the names of the attributes in the
- attribute set <replaceable>attrs</replaceable> in a sorted list.
- For instance, <literal>builtins.attrNames {y = 1; x =
- "foo";}</literal> evaluates to <literal>["x" "y"]</literal>.
- There is no built-in function <function>attrValues</function>, but
- you can easily define it yourself:
-
-<programlisting>
-attrValues = attrs: map (name: builtins.getAttr name attrs) (builtins.attrNames attrs);</programlisting>
-
- </para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>baseNameOf</function> <replaceable>s</replaceable></term>
-
- <listitem><para>Return the <emphasis>base name</emphasis> of the
- string <replaceable>s</replaceable>, that is, everything following
- the final slash in the string. This is similar to the GNU
- <command>basename</command> command.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><varname>builtins</varname></term>
-
- <listitem><para>The attribute set <varname>builtins</varname>
- contains all the built-in functions and values. You can use
- <varname>builtins</varname> to test for the availability of
- features in the Nix installation, e.g.,
-
-<programlisting>
-if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
-
- This allows a Nix expression to fall back gracefully on older Nix
- installations that don’t have the desired built-in function.
- However, in that case you should not write
-
-<programlisting>
-if builtins ? getEnv then __getEnv "PATH" else ""</programlisting>
-
- This Nix expression will trigger an “undefined variable” error on
- older Nix versions since <function>__getEnv</function> doesn’t
- exist. <literal>builtins.getEnv</literal>, on the other hand, is
- safe since <literal>builtins</literal> always exists and attribute
- selection is lazy, so it’s only performed if the test
- succeeds.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry
- xml:id='builtin-currentSystem'><term><varname>builtins.currentSystem</varname></term>
-
- <listitem><para>The built-in value <varname>currentSystem</varname>
- evaluates to the Nix platform identifier for the Nix installation
- on which the expression is being evaluated, such as
- <literal>"i686-linux"</literal> or
- <literal>"powerpc-darwin"</literal>.</para></listitem>
-
- </varlistentry>
-
-
- <!--
- <varlistentry><term><function>currentTime</function></term>
-
- <listitem><para>The built-in value <varname>currentTime</varname>
- returns the current system time in seconds since 00:00:00 1/1/1970
- UTC. Due to the evaluation model of Nix expressions
- (<emphasis>maximal laziness</emphasis>), it always yields the same
- value within an execution of Nix.</para></listitem>
-
- </varlistentry>
- -->
-
-
- <!--
- <varlistentry><term><function>dependencyClosure</function></term>
-
- <listitem><para>TODO</para></listitem>
-
- </varlistentry>
- -->
-
-
- <varlistentry><term><function>derivation</function>
- <replaceable>attrs</replaceable></term>
-
- <listitem><para><function>derivation</function> is described in
- <xref linkend='ssec-derivation' />.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>dirOf</function> <replaceable>s</replaceable></term>
-
- <listitem><para>Return the directory part of the string
- <replaceable>s</replaceable>, that is, everything before the final
- slash in the string. This is similar to the GNU
- <command>dirname</command> command.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>builtins.getAttr</function>
- <replaceable>s</replaceable> <replaceable>attrs</replaceable></term>
-
- <listitem><para><function>getAttr</function> returns the attribute
- named <replaceable>s</replaceable> from the attribute set
- <replaceable>attrs</replaceable>. Evaluation aborts if the
- attribute doesn’t exist. This is a dynamic version of the
- <literal>.</literal> operator, since <replaceable>s</replaceable>
- is an expression rather than an identifier.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>builtins.getEnv</function>
- <replaceable>s</replaceable></term>
-
- <listitem><para><function>getEnv</function> returns the value of
- the environment variable <replaceable>s</replaceable>, or an empty
- string if the variable doesn’t exist. This function should be
- used with care, as it can introduce all sorts of nasty environment
- dependencies in your Nix expression.</para>
-
- <para><function>getEnv</function> is used in Nix Packages to
- locate the file <filename>~/.nixpkgs/config.nix</filename>, which
- contains user-local settings for Nix Packages. (That is, it does
- a <literal>getEnv "HOME"</literal> to locate the user’s home
- directory.)</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>builtins.hasAttr</function>
- <replaceable>s</replaceable> <replaceable>attrs</replaceable></term>
-
- <listitem><para><function>hasAttr</function> returns
- <literal>true</literal> if the attribute set
- <replaceable>attrs</replaceable> has an attribute named
- <replaceable>s</replaceable>, and <literal>false</literal>
- otherwise. This is a dynamic version of the <literal>?</literal>
- operator, since <replaceable>s</replaceable> is an expression
- rather than an identifier.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>builtins.head</function>
- <replaceable>list</replaceable></term>
-
- <listitem><para>Return the first element of a list; abort
- evaluation if the argument isn’t a list or is an empty list. You
- can test whether a list is empty by comparing it with
- <literal>[]</literal>.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>import</function>
- <replaceable>path</replaceable></term>
-
- <listitem><para>Load, parse and return the Nix expression in the
- file <replaceable>path</replaceable>. Evaluation aborts if the
- file doesn’t exist or contains an incorrect Nix
- expression. <function>import</function> implements Nix’s module
- system: you can put any Nix expression (such as an attribute set
- or a function) in a separate file, and use it from Nix expressions
- in other files.</para>
-
- <para>A Nix expression loaded by <function>import</function> must
- not contain any <emphasis>free variables</emphasis> (identifiers
- that are not defined in the Nix expression itself and are not
- built-in). Therefore, it cannot refer to variables that are in
- scope at the call site. For instance, if you have a calling
- expression
-
-<programlisting>
-rec {
- x = 123;
- y = import ./foo.nix;
-}</programlisting>
-
- then the following <filename>foo.nix</filename> will give an
- error:
-
-<programlisting>
-x + 456</programlisting>
-
- since <varname>x</varname> is not in scope in
- <filename>foo.nix</filename>. If you want <varname>x</varname>
- to be available in <filename>foo.nix</filename>, you should pass
- it as a function argument:
-
-<programlisting>
-rec {
- x = 123;
- y = import ./foo.nix x;
-}</programlisting>
-
- and
-
-<programlisting>
-x: x + 456</programlisting>
-
- (The function argument doesn’t have to be called
- <varname>x</varname> in <filename>foo.nix</filename>; any name
- would work.)</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>builtins.isList</function>
- <replaceable>e</replaceable></term>
-
- <listitem><para>Return <literal>true</literal> if
- <replaceable>e</replaceable> evaluates to a list, and
- <literal>false</literal> otherwise.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>isNull</function>
- <replaceable>e</replaceable></term>
-
- <listitem><para>Return <literal>true</literal> if
- <replaceable>e</replaceable> evaluates to <literal>null</literal>,
- and <literal>false</literal> otherwise.</para>
-
- <warning><para>This function is <emphasis>deprecated</emphasis>;
- just write <literal>e == null</literal> instead.</para></warning>
-
- </listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>builtins.lessThan</function>
- <replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
-
- <listitem><para>Return <literal>true</literal> if the integer
- <replaceable>e1</replaceable> is less than the integer
- <replaceable>e2</replaceable>, and <literal>false</literal>
- otherwise. Evaluation aborts if either
- <replaceable>e1</replaceable> or <replaceable>e2</replaceable>
- does not evaluate to an integer.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>map</function>
- <replaceable>f</replaceable> <replaceable>list</replaceable></term>
-
- <listitem><para>Apply the function <replaceable>f</replaceable> to
- each element in the list <replaceable>list</replaceable>. For
- example,
-
-<programlisting>
-map (x: "foo" + x) ["bar" "bla" "abc"]</programlisting>
-
- evaluates to <literal>["foobar" "foobla"
- "fooabc"]</literal>.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>builtins.pathExists</function>
- <replaceable>path</replaceable></term>
-
- <listitem><para>Return <literal>true</literal> if the path
- <replaceable>path</replaceable> exists, and
- <literal>false</literal> otherwise. One application of this
- function is to conditionally include a Nix expression containing
- user configuration:
-
-<programlisting>
-let
- fileName = builtins.getEnv "CONFIG_FILE";
- config =
- if fileName != "" &amp;&amp; builtins.pathExists (builtins.toPath fileName)
- then import (builtins.toPath fileName)
- else { someSetting = false; }; <lineannotation># default configuration</lineannotation>
-in config.someSetting</programlisting>
-
- (Note that <envar>CONFIG_FILE</envar> must be an absolute path for
- this to work.)</para></listitem>
-
- </varlistentry>
-
-
- <!--
- <varlistentry><term><function>relativise</function></term>
-
- <listitem><para>TODO</para></listitem>
-
- </varlistentry>
- -->
-
-
- <varlistentry><term><function>removeAttrs</function>
- <replaceable>attrs</replaceable> <replaceable>list</replaceable></term>
-
- <listitem><para>Remove the attributes listed in
- <replaceable>list</replaceable> from the attribute set
- <replaceable>attrs</replaceable>. The attributes don’t have to
- exist in <replaceable>attrs</replaceable>. For instance,
-
-<screen>
-removeAttrs { x = 1; y = 2; z = 3; } ["a" "x" "z"]</screen>
-
- evaluates to <literal>{y = 2;}</literal>.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>builtins.tail</function>
- <replaceable>list</replaceable></term>
-
- <listitem><para>Return the second to last elements of a list;
- abort evaluation if the argument isn’t a list or is an empty
- list.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry
- xml:id='builtin-toFile'><term><function>builtins.toFile</function>
- <replaceable>name</replaceable> <replaceable>s</replaceable></term>
-
- <listitem><para>Store the string <replaceable>s</replaceable> in a
- file in the Nix store and return its path. The file has suffix
- <replaceable>name</replaceable>. This file can be used as an
- input to derivations. One application is to write builders
- “inline”. For instance, the following Nix expression combines
- <xref linkend='ex-hello-nix' /> and <xref
- linkend='ex-hello-builder' /> into one file:
-
-<programlisting>
-{stdenv, fetchurl, perl}:
-
-stdenv.mkDerivation {
- name = "hello-2.1.1";
-
- builder = builtins.toFile "builder.sh" "
- source $stdenv/setup
-
- PATH=$perl/bin:$PATH
-
- tar xvfz $src
- cd hello-*
- ./configure --prefix=$out
- make
- make install
- ";
-
- src = fetchurl {
- url = http://nix.cs.uu.nl/dist/tarballs/hello-2.1.1.tar.gz;
- md5 = "70c9ccf9fac07f762c24f2df2290784d";
- };
- inherit perl;
-}</programlisting>
-
- </para>
-
- <para>It is even possible for one file to refer to another, e.g.,
-
-<programlisting>
- builder = let
- configFile = builtins.toFile "foo.conf" "
- # This is some dummy configuration file.
- <replaceable>...</replaceable>
- ";
- in builtins.toFile "builder.sh" "
- source $stdenv/setup
- <replaceable>...</replaceable>
- cp ${configFile} $out/etc/foo.conf
- ";</programlisting>
-
- Note that <literal>${configFile}</literal> is an antiquotation
- (see <xref linkend='ssec-values' />), so the result of the
- expression <literal>configFile</literal> (i.e., a path like
- <filename>/nix/store/m7p7jfny445k...-foo.conf</filename>) will be
- spliced into the resulting string.</para>
-
- <para>It is however <emphasis>not</emphasis> allowed to have files
- mutually referring to each other, like so:
-
-<programlisting>
-let
- foo = builtins.toFile "foo" "...${bar}...";
- bar = builtins.toFile "bar" "...${foo}...";
-in foo</programlisting>
-
- This is not allowed because it would cause a cyclic dependency in
- the computation of the cryptographic hashes for
- <varname>foo</varname> and <varname>bar</varname>.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>builtins.toPath</function> <replaceable>s</replaceable></term>
-
- <listitem><para>Convert the string value
- <replaceable>s</replaceable> into a path value. The string
- <replaceable>s</replaceable> must represent an absolute path
- (i.e., must start with <literal>/</literal>). The path need not
- exist. The resulting path is canonicalised, e.g.,
- <literal>builtins.toPath "//foo/xyzzy/../bar/"</literal> returns
- <literal>/foo/bar</literal>.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry><term><function>toString</function> <replaceable>e</replaceable></term>
-
- <listitem><para>Convert the expression
- <replaceable>e</replaceable> to a string.
- <replaceable>e</replaceable> can be a string (in which case
- <function>toString</function> is a no-op) or a path (e.g.,
- <literal>toString /foo/bar</literal> yields
- <literal>"/foo/bar"</literal>.</para></listitem>
-
- </varlistentry>
-
-
- <varlistentry xml:id='builtin-toXML'><term><function>builtins.toXML</function> <replaceable>e</replaceable></term>
-
- <listitem><para>Return a string containing an XML representation
- of <replaceable>e</replaceable>. The main application for
- <function>toXML</function> is to communicate information with the
- builder in a more structured format than plain environment
- variables.</para>
-
- <!-- TODO: more formally describe the schema of the XML
- representation -->
-
- <para><xref linkend='ex-toxml' /> shows an example where this is
- the case. The builder is supposed to generate the configuration
- file for a <link xlink:href='http://jetty.mortbay.org/'>Jetty
- servlet container</link>. A servlet container contains a number
- of servlets (<filename>*.war</filename> files) each exported under
- a specific URI prefix. So the servlet configuration is a list of
- attribute sets containing the <varname>path</varname> and
- <varname>war</varname> of the servlet (<xref
- linkend='ex-toxml-co-servlets' />). 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
- <function>toXML</function>, which is unambiguous and can easily be
- processed with the appropriate tools. For instance, in the
- example an XSLT stylesheet (<xref linkend='ex-toxml-co-stylesheet'
- />) is applied to it (<xref linkend='ex-toxml-co-apply' />) to
- generate the XML configuration file for the Jetty server. The XML
- representation produced from <xref linkend='ex-toxml-co-servlets'
- /> by <function>toXML</function> is shown in <xref
- linkend='ex-toxml-result' />.</para>
-
- <para>Note that <xref linkend='ex-toxml' /> uses the <function
- linkend='builtin-toFile'>toFile</function> built-in to write the
- builder and the stylesheet “inline” in the Nix expression. The
- path of the stylesheet is spliced into the builder at
- <literal>xsltproc ${stylesheet}
- <replaceable>...</replaceable></literal>.</para>
-
- <example xml:id='ex-toxml'><title>Passing information to a builder
- using <function>toXML</function></title>
-
-<programlisting><![CDATA[
-{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]]> <co xml:id='ex-toxml-co-apply' /> <![CDATA[
- ";
-
- stylesheet = builtins.toFile "stylesheet.xsl"]]> <co xml:id='ex-toxml-co-stylesheet' /> <![CDATA[
- "<?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 []]> <co xml:id='ex-toxml-co-servlets' /> <![CDATA[
- { path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
- { path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
- ];
-})]]></programlisting>
-
- </example>
-
- <example xml:id='ex-toxml-result'><title>XML representation produced by
- <function>toXML</function></title>
-
-<programlisting><![CDATA[<?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>]]></programlisting>
-
- </example>
-
- </listitem>
-
- </varlistentry>
-
-
-</variablelist>
-
-</section>
+<xi:include href="builtins.xml" />
</section>