* Move list of built-in functions to a separate file.
This commit is contained in:
		
							parent
							
								
									1db187ff69
								
							
						
					
					
						commit
						35ac16e75e
					
				
					 3 changed files with 592 additions and 584 deletions
				
			
		| 
						 | 
					@ -20,7 +20,7 @@ man1_MANS = nix-env.1 nix-build.1 nix-store.1 nix-instantiate.1 \
 | 
				
			||||||
FIGURES = figures/user-environments.png
 | 
					FIGURES = figures/user-environments.png
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MANUAL_SRCS = manual.xml introduction.xml installation.xml \
 | 
					MANUAL_SRCS = manual.xml introduction.xml installation.xml \
 | 
				
			||||||
 package-management.xml writing-nix-expressions.xml \
 | 
					 package-management.xml writing-nix-expressions.xml builtins.xml \
 | 
				
			||||||
 build-farm.xml \
 | 
					 build-farm.xml \
 | 
				
			||||||
 $(man1_MANS:.1=.xml) \
 | 
					 $(man1_MANS:.1=.xml) \
 | 
				
			||||||
 troubleshooting.xml bugs.xml opt-common.xml opt-common-syn.xml \
 | 
					 troubleshooting.xml bugs.xml opt-common.xml opt-common-syn.xml \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										588
									
								
								doc/manual/builtins.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										588
									
								
								doc/manual/builtins.xml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,588 @@
 | 
				
			||||||
 | 
					<section xmlns="http://docbook.org/ns/docbook"
 | 
				
			||||||
 | 
					              xmlns:xlink="http://www.w3.org/1999/xlink">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<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 != "" && 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>
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
<chapter xmlns="http://docbook.org/ns/docbook"
 | 
					<chapter xmlns="http://docbook.org/ns/docbook"
 | 
				
			||||||
         xmlns:xlink="http://www.w3.org/1999/xlink"
 | 
					         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>
 | 
					<title>Writing Nix Expressions</title>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1339,589 +1340,8 @@ command-line argument.  See <xref linkend='sec-standard-environment'
 | 
				
			||||||
</section>
 | 
					</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<section><title>Built-in functions</title>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<para>This section lists the functions and constants built into the
 | 
					<xi:include href="builtins.xml" />
 | 
				
			||||||
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 != "" && 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>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</section>
 | 
					</section>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue