summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2012-01-03 12:59:31 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2012-01-03 12:59:31 +0000
commit6c31232e1494d1d68a31fb8433dbf593f831dff2 (patch)
tree9acd7f0e2279bd971b5ccd1f1eb8cec8b7937003
parent502d94048ae848eda1fcda2d1e72b339eaa653aa (diff)
parent63227d434cefaa9faeb14afe28ebeb9b2d449ee2 (diff)
downloadguix-6c31232e1494d1d68a31fb8433dbf593f831dff2.tar.gz
* Sync with the trunk.
-rw-r--r--configure.ac3
-rw-r--r--corepkgs/Makefile.am12
-rw-r--r--corepkgs/buildenv.nix (renamed from corepkgs/buildenv/default.nix)7
-rw-r--r--[-rwxr-xr-x]corepkgs/buildenv.pl (renamed from corepkgs/buildenv/builder.pl.in)2
-rw-r--r--corepkgs/buildenv/Makefile.am11
-rw-r--r--corepkgs/channels/Makefile.am11
-rw-r--r--corepkgs/channels/unpack.nix7
-rw-r--r--corepkgs/channels/unpack.sh.in35
-rw-r--r--corepkgs/config.nix.in13
-rw-r--r--corepkgs/nar.nix30
-rw-r--r--corepkgs/nar/Makefile.am11
-rw-r--r--corepkgs/nar/nar.nix7
-rw-r--r--corepkgs/nar/nar.sh.in12
-rw-r--r--corepkgs/unpack-channel.nix11
-rw-r--r--corepkgs/unpack-channel.sh30
-rw-r--r--doc/manual/builtins.xml38
-rw-r--r--doc/manual/nix-prefetch-url.xml2
-rw-r--r--doc/manual/opt-common.xml4
-rw-r--r--doc/manual/writing-nix-expressions.xml84
-rw-r--r--perl/lib/Nix/Config.pm.in1
-rwxr-xr-xscripts/nix-build.in7
-rwxr-xr-xscripts/nix-channel.in22
-rwxr-xr-xscripts/nix-collect-garbage.in7
-rwxr-xr-xscripts/nix-pull.in5
-rwxr-xr-xscripts/nix-push.in23
-rw-r--r--src/nix-env/user-env.cc2
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/common.sh.in7
-rw-r--r--tests/config.nix.in3
-rw-r--r--tests/dependencies.nix1
-rw-r--r--tests/init.sh24
-rw-r--r--tests/lang.sh2
-rw-r--r--tests/lang/eval-okay-search-path.nix2
-rw-r--r--tests/nix-channel.sh43
-rw-r--r--tests/user-envs.sh2
35 files changed, 242 insertions, 243 deletions
diff --git a/configure.ac b/configure.ac
index 0443fe4920..52c92b76bf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -346,9 +346,6 @@ AC_CONFIG_FILES([Makefile
    perl/Makefile
    scripts/Makefile
    corepkgs/Makefile
-   corepkgs/nar/Makefile
-   corepkgs/buildenv/Makefile
-   corepkgs/channels/Makefile
    doc/Makefile
    doc/manual/Makefile
    misc/Makefile
diff --git a/corepkgs/Makefile.am b/corepkgs/Makefile.am
index b303a30eba..86d7027ed0 100644
--- a/corepkgs/Makefile.am
+++ b/corepkgs/Makefile.am
@@ -1 +1,11 @@
-SUBDIRS = nar buildenv channels
+all-local: config.nix
+
+files = nar.nix buildenv.nix buildenv.pl unpack-channel.nix unpack-channel.sh
+
+install-exec-local:
+	$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs
+	$(INSTALL_DATA) config.nix $(files) $(DESTDIR)$(datadir)/nix/corepkgs
+
+include ../substitute.mk
+
+EXTRA_DIST = config.nix.in $(files)
diff --git a/corepkgs/buildenv/default.nix b/corepkgs/buildenv.nix
index d76f527409..6e2bee10b1 100644
--- a/corepkgs/buildenv/default.nix
+++ b/corepkgs/buildenv.nix
@@ -1,9 +1,12 @@
-{system, derivations, manifest}:
+with import <nix/config.nix>;
+
+{ system, derivations, manifest }:
 
 derivation { 
   name = "user-environment";
   system = system;
-  builder = ./builder.pl;
+  builder = perl;
+  args = [ "-w" ./buildenv.pl ];
   
   manifest = manifest;
 
diff --git a/corepkgs/buildenv/builder.pl.in b/corepkgs/buildenv.pl
index 86abe0ca19..52a703c066 100755..100644
--- a/corepkgs/buildenv/builder.pl.in
+++ b/corepkgs/buildenv.pl
@@ -1,5 +1,3 @@
-#! @perl@ -w
-
 use strict;
 use Cwd;
 use IO::Handle;
diff --git a/corepkgs/buildenv/Makefile.am b/corepkgs/buildenv/Makefile.am
deleted file mode 100644
index eeab538abc..0000000000
--- a/corepkgs/buildenv/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-all-local: builder.pl
-
-install-exec-local:
-	$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs
-	$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs/buildenv
-	$(INSTALL_DATA) $(srcdir)/default.nix $(DESTDIR)$(datadir)/nix/corepkgs/buildenv
-	$(INSTALL_PROGRAM) builder.pl $(DESTDIR)$(datadir)/nix/corepkgs/buildenv
-
-include ../../substitute.mk
-
-EXTRA_DIST = default.nix builder.pl.in
diff --git a/corepkgs/channels/Makefile.am b/corepkgs/channels/Makefile.am
deleted file mode 100644
index d4d478f0e2..0000000000
--- a/corepkgs/channels/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-all-local: unpack.sh
-
-install-exec-local:
-	$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs
-	$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs/channels
-	$(INSTALL_DATA) $(srcdir)/unpack.nix $(DESTDIR)$(datadir)/nix/corepkgs/channels
-	$(INSTALL_PROGRAM) unpack.sh $(DESTDIR)$(datadir)/nix/corepkgs/channels
-
-include ../../substitute.mk
-
-EXTRA_DIST = unpack.nix unpack.sh.in
diff --git a/corepkgs/channels/unpack.nix b/corepkgs/channels/unpack.nix
deleted file mode 100644
index 80ca4a3710..0000000000
--- a/corepkgs/channels/unpack.nix
+++ /dev/null
@@ -1,7 +0,0 @@
-{system, inputs}:
-
-derivation {
-  name = "channels";
-  builder = ./unpack.sh;
-  inherit system inputs;
-}
\ No newline at end of file
diff --git a/corepkgs/channels/unpack.sh.in b/corepkgs/channels/unpack.sh.in
deleted file mode 100644
index 6e5939f4f2..0000000000
--- a/corepkgs/channels/unpack.sh.in
+++ /dev/null
@@ -1,35 +0,0 @@
-#! @shell@ -e
-
-# Cygwin compatibility hack: bunzip2 expects cygwin.dll in $PATH.
-export PATH=@coreutils@
-
-@coreutils@/mkdir $out
-@coreutils@/mkdir $out/tmp
-cd $out/tmp
-
-inputs=($inputs)
-for ((n = 0; n < ${#inputs[*]}; n += 2)); do
-    channelName=${inputs[n]}
-    channelTarball=${inputs[n+1]}
-    
-    echo "unpacking channel $channelName"
-    
-    @bzip2@ -d < $channelTarball | @tar@ xf -
-
-    if test -e */channel-name; then
-        channelName="$(@coreutils@/cat */channel-name)"
-    fi
-
-    nr=1
-    attrName=$(echo $channelName | @tr@ -- '- ' '__')
-    dirName=$attrName
-    while test -e ../$dirName; do
-        nr=$((nr+1))
-        dirName=$attrName-$nr
-    done
-
-    @coreutils@/mv * ../$dirName # !!! hacky
-done
-
-cd ..
-@coreutils@/rmdir tmp
diff --git a/corepkgs/config.nix.in b/corepkgs/config.nix.in
new file mode 100644
index 0000000000..b324d732a1
--- /dev/null
+++ b/corepkgs/config.nix.in
@@ -0,0 +1,13 @@
+let
+  fromEnv = var: def:
+    let val = builtins.getEnv var; in
+    if val != "" then val else def;
+in {
+  perl = "@perl@";
+  shell = "@shell@";
+  coreutils = "@coreutils@";
+  bzip2 = fromEnv "NIX_BZIP2" "@bzip2@";
+  tar = "@tar@";
+  tr = "@tr@";
+  nixBinDir = fromEnv "NIX_BIN_DIR" "@bindir@";
+}
diff --git a/corepkgs/nar.nix b/corepkgs/nar.nix
new file mode 100644
index 0000000000..70a4af2f9d
--- /dev/null
+++ b/corepkgs/nar.nix
@@ -0,0 +1,30 @@
+with import <nix/config.nix>;
+
+let
+
+  builder = builtins.toFile "nar.sh"
+    ''
+      export PATH=${nixBinDir}:${coreutils}
+
+      echo "packing ‘$storePath’..."
+      mkdir $out
+      dst=$out/tmp.nar.bz2
+
+      set -o pipefail
+      nix-store --dump "$storePath" | ${bzip2} > $dst
+
+      nix-hash --flat --type $hashAlgo --base32 $dst > $out/narbz2-hash
+
+      mv $out/tmp.nar.bz2 $out/$(cat $out/narbz2-hash).nar.bz2
+    '';
+
+in
+
+{ system, storePath, hashAlgo }:
+
+derivation {
+  name = "nar";
+  builder = shell;
+  args = [ "-e" builder ];
+  inherit system storePath hashAlgo;
+}
diff --git a/corepkgs/nar/Makefile.am b/corepkgs/nar/Makefile.am
deleted file mode 100644
index 103051e225..0000000000
--- a/corepkgs/nar/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-all-local: nar.sh
-
-install-exec-local:
-	$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs
-	$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs/nar
-	$(INSTALL_DATA) $(srcdir)/nar.nix $(DESTDIR)$(datadir)/nix/corepkgs/nar
-	$(INSTALL_PROGRAM) nar.sh $(DESTDIR)$(datadir)/nix/corepkgs/nar
-
-include ../../substitute.mk
-
-EXTRA_DIST = nar.nix nar.sh.in
diff --git a/corepkgs/nar/nar.nix b/corepkgs/nar/nar.nix
deleted file mode 100644
index d3d799998f..0000000000
--- a/corepkgs/nar/nar.nix
+++ /dev/null
@@ -1,7 +0,0 @@
-{ system, storePath, hashAlgo }:
-
-derivation {
-  name = "nar";
-  builder = ./nar.sh;
-  inherit system storePath hashAlgo;
-}
diff --git a/corepkgs/nar/nar.sh.in b/corepkgs/nar/nar.sh.in
deleted file mode 100644
index 1369d3a21f..0000000000
--- a/corepkgs/nar/nar.sh.in
+++ /dev/null
@@ -1,12 +0,0 @@
-#! @shell@ -e
-
-echo "packing $storePath into $out..."
-@coreutils@/mkdir $out
-dst=$out/tmp.nar.bz2
-@bindir@/nix-store --dump "$storePath" > tmp
-
-@bzip2@ < tmp > $dst
-
-@bindir@/nix-hash --flat --type $hashAlgo --base32 $dst > $out/narbz2-hash
-
-@coreutils@/mv $out/tmp.nar.bz2 $out/$(@coreutils@/cat $out/narbz2-hash).nar.bz2
diff --git a/corepkgs/unpack-channel.nix b/corepkgs/unpack-channel.nix
new file mode 100644
index 0000000000..5e6ccf23fd
--- /dev/null
+++ b/corepkgs/unpack-channel.nix
@@ -0,0 +1,11 @@
+with import <nix/config.nix>;
+
+{ system, inputs }:
+
+derivation {
+  name = "channels";
+  builder = shell;
+  args = [ "-e" ./unpack-channel.sh ];
+  inherit system inputs bzip2 tar tr;
+  PATH = "${nixBinDir}:${coreutils}";
+}
diff --git a/corepkgs/unpack-channel.sh b/corepkgs/unpack-channel.sh
new file mode 100644
index 0000000000..7c244a6a85
--- /dev/null
+++ b/corepkgs/unpack-channel.sh
@@ -0,0 +1,30 @@
+mkdir $out
+mkdir $out/tmp
+cd $out/tmp
+
+inputs=($inputs)
+for ((n = 0; n < ${#inputs[*]}; n += 2)); do
+    channelName=${inputs[n]}
+    channelTarball=${inputs[n+1]}
+    
+    echo "unpacking channel $channelName"
+    
+    $bzip2 -d < $channelTarball | $tar xf -
+
+    if test -e */channel-name; then
+        channelName="$(cat */channel-name)"
+    fi
+
+    nr=1
+    attrName=$(echo $channelName | $tr -- '- ' '__')
+    dirName=$attrName
+    while test -e ../$dirName; do
+        nr=$((nr+1))
+        dirName=$attrName-$nr
+    done
+
+    mv * ../$dirName # !!! hacky
+done
+
+cd ..
+rmdir tmp
diff --git a/doc/manual/builtins.xml b/doc/manual/builtins.xml
index c7ebcc9a33..ce68c45bf3 100644
--- a/doc/manual/builtins.xml
+++ b/doc/manual/builtins.xml
@@ -43,10 +43,10 @@ is also available as <function>builtins.derivation</function>.</para>
 
     <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:
+    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>
@@ -442,10 +442,10 @@ x: x + 456</programlisting>
     Example:
 
 <programlisting>
-builtins.listToAttrs [
-  {name = "foo"; value = 123;}
-  {name = "bar"; value = 456;}
-]
+builtins.listToAttrs
+  [ { name = "foo"; value = 123; }
+    { name = "bar"; value = 456; }
+  ]
 </programlisting>
 
     evaluates to
@@ -466,10 +466,10 @@ builtins.listToAttrs [
     example,
 
 <programlisting>
-map (x: "foo" + x) ["bar" "bla" "abc"]</programlisting>
+map (x: "foo" + x) [ "bar" "bla" "abc" ]</programlisting>
 
-    evaluates to <literal>["foobar" "foobla"
-    "fooabc"]</literal>.</para></listitem>
+    evaluates to <literal>[ "foobar" "foobla" "fooabc"
+    ]</literal>.</para></listitem>
     
   </varlistentry>
 
@@ -491,10 +491,10 @@ map (x: "foo" + x) ["bar" "bla" "abc"]</programlisting>
     a package name and version.  The package name is everything up to
     but not including the first dash followed by a digit, and the
     version is everything following that dash.  The result is returned
-    in an attribute set <literal>{name, version}</literal>.  Thus,
+    in an attribute set <literal>{ name, version }</literal>.  Thus,
     <literal>builtins.parseDrvName "nix-0.12pre12876"</literal>
-    returns <literal>{name = "nix"; version =
-    "0.12pre12876";}</literal>.</para></listitem>
+    returns <literal>{ name = "nix"; version = "0.12pre12876";
+    }</literal>.</para></listitem>
 
   </varlistentry>
 
@@ -550,9 +550,9 @@ in config.someSetting</programlisting>
     exist in <replaceable>attrs</replaceable>. For instance,
 
 <screen>
-removeAttrs { x = 1; y = 2; z = 3; } ["a" "x" "z"]</screen>
+removeAttrs { x = 1; y = 2; z = 3; } [ "a" "x" "z" ]</screen>
 
-    evaluates to <literal>{y = 2;}</literal>.</para></listitem>
+    evaluates to <literal>{ y = 2; }</literal>.</para></listitem>
 
   </varlistentry>
 
@@ -632,7 +632,7 @@ removeAttrs { x = 1; y = 2; z = 3; } ["a" "x" "z"]</screen>
     linkend='ex-hello-builder' /> into one file:
 
 <programlisting>
-{stdenv, fetchurl, perl}:
+{ stdenv, fetchurl, perl }:
 
 stdenv.mkDerivation {
   name = "hello-2.1.1";
@@ -765,12 +765,12 @@ in foo</programlisting>
     using <function>toXML</function></title>
     
 <programlisting><![CDATA[
-{stdenv, fetchurl, libxslt, jira, uberwiki}:
+{ stdenv, fetchurl, libxslt, jira, uberwiki }:
 
 stdenv.mkDerivation (rec {
   name = "web-server";
 
-  buildInputs = [libxslt];
+  buildInputs = [ libxslt ];
   
   builder = builtins.toFile "builder.sh" "
     source $stdenv/setup
diff --git a/doc/manual/nix-prefetch-url.xml b/doc/manual/nix-prefetch-url.xml
index b31b699af0..0d953e9467 100644
--- a/doc/manual/nix-prefetch-url.xml
+++ b/doc/manual/nix-prefetch-url.xml
@@ -12,7 +12,7 @@
 
 <refnamediv>
   <refname>nix-prefetch-url</refname>
-  <refpurpose>copy a file from a URL into the store and print its MD5 hash</refpurpose>
+  <refpurpose>copy a file from a URL into the store and print its hash</refpurpose>
 </refnamediv>
 
 <refsynopsisdiv>
diff --git a/doc/manual/opt-common.xml b/doc/manual/opt-common.xml
index e86e4b4125..c36c6df410 100644
--- a/doc/manual/opt-common.xml
+++ b/doc/manual/opt-common.xml
@@ -264,8 +264,8 @@
   expression evaluator will automatically try to call functions that
   it encounters.  It can automatically call functions for which every
   argument has a <link linkend='ss-functions'>default value</link>
-  (e.g., <literal>{<replaceable>argName</replaceable> ?
-  <replaceable>defaultValue</replaceable>}:
+  (e.g., <literal>{ <replaceable>argName</replaceable> ?
+  <replaceable>defaultValue</replaceable> }:
   <replaceable>...</replaceable></literal>).  With
   <option>--arg</option>, you can also call functions that have
   arguments without a default value (or override a default value).
diff --git a/doc/manual/writing-nix-expressions.xml b/doc/manual/writing-nix-expressions.xml
index 35fdf535b7..e16225433d 100644
--- a/doc/manual/writing-nix-expressions.xml
+++ b/doc/manual/writing-nix-expressions.xml
@@ -52,7 +52,7 @@ need to do three things:
 <example xml:id='ex-hello-nix'><title>Nix expression for GNU Hello
 (<filename>default.nix</filename>)</title>
 <programlisting>
-{stdenv, fetchurl, perl}: <co xml:id='ex-hello-nix-co-1' />
+{ stdenv, fetchurl, perl }: <co xml:id='ex-hello-nix-co-1' />
 
 stdenv.mkDerivation { <co xml:id='ex-hello-nix-co-2' />
   name = "hello-2.1.1"; <co xml:id='ex-hello-nix-co-3' />
@@ -92,8 +92,8 @@ the single Nix expression in that directory
     function that downloads files.  <varname>perl</varname> is the
     Perl interpreter.</para>
 
-    <para>Nix functions generally have the form <literal>{x, y, ...,
-    z}: e</literal> where <varname>x</varname>, <varname>y</varname>,
+    <para>Nix functions generally have the form <literal>{ x, y, ...,
+    z }: e</literal> where <varname>x</varname>, <varname>y</varname>,
     etc. are the names of the expected arguments, and where
     <replaceable>e</replaceable> is the body of the function.  So
     here, the entire remainder of the file is the body of the
@@ -114,10 +114,10 @@ the single Nix expression in that directory
     <emphasis>attributes</emphasis>.  An attribute set is just a list
     of key/value pairs where each value is an arbitrary Nix
     expression.  They take the general form
-    <literal>{<replaceable>name1</replaceable> =
+    <literal>{ <replaceable>name1</replaceable> =
     <replaceable>expr1</replaceable>; <replaceable>...</replaceable>
     <replaceable>nameN</replaceable> =
-    <replaceable>exprN</replaceable>;}</literal>.</para>
+    <replaceable>exprN</replaceable>; }</literal>.</para>
 
   </callout>
 
@@ -564,7 +564,7 @@ genericBuild <co xml:id='ex-hello-builder2-co-3' /></programlisting>
 expression, like this:
 
 <programlisting>
-  buildInputs = [perl];</programlisting>
+  buildInputs = [ perl ];</programlisting>
 
 The <varname>perl</varname> attribute can then be removed, and the
 builder becomes even shorter:
@@ -771,14 +771,14 @@ stdenv.mkDerivation {
 values between square brackets.  For example,
 
 <programlisting>
-[ 123 ./foo.nix "abc" (f {x=y;}) ]</programlisting>
+[ 123 ./foo.nix "abc" (f { x = y; }) ]</programlisting>
 
 defines a list of four elements, the last being the result of a call
 to the function <varname>f</varname>.  Note that function calls have
 to be enclosed in parentheses.  If they had been omitted, e.g.,
 
 <programlisting>
-[ 123 ./foo.nix "abc" f {x=y;} ]</programlisting>
+[ 123 ./foo.nix "abc" f { x = y; } ]</programlisting>
 
 the result would be a list of five elements, the fourth one being a
 function and the fifth being an attribute set.</para>
@@ -891,15 +891,12 @@ propagate attributes).  This can be shortened using the
 <literal>inherit</literal> keyword.  For instance,
 
 <programlisting>
-let
-  x = 123;
-in 
-  {
-    inherit x;
-    y = 456;
-  }</programlisting>
-
-evaluates to <literal>{x = 123; y = 456;}</literal>.  (Note that this
+let x = 123; in 
+{ inherit x;
+  y = 456;
+}</programlisting>
+
+evaluates to <literal>{ x = 123; y = 456; }</literal>.  (Note that this
 works because <varname>x</varname> is added to the lexical scope by
 the <literal>let</literal> construct.)  It is also possible to inherit
 attributes from another attribute set.  For instance, in this fragment
@@ -960,20 +957,20 @@ in if negate true then concat "foo" "bar" else ""</programlisting>
   arguments of a function); e.g.,
 
   <programlisting>
-map (concat "foo") ["bar" "bla" "abc"]</programlisting>
+map (concat "foo") [ "bar" "bla" "abc" ]</programlisting>
 
-  evaluates to <literal>["foobar" "foobla"
-  "fooabc"]</literal>.</para></listitem>
+  evaluates to <literal>[ "foobar" "foobla"
+  "fooabc" ]</literal>.</para></listitem>
 
   
   <listitem><para>An <emphasis>attribute set pattern</emphasis> of the
-  form <literal>{name1, name2, …, nameN}</literal>
+  form <literal>{ name1, name2, …, nameN }</literal>
   matches an attribute set containing the listed attributes, and binds
   the values of those attributes to variables in the function body.
   For example, the function
 
 <programlisting>
-{x, y, z}: z + y + x</programlisting>
+{ x, y, z }: z + y + x</programlisting>
 
   can only be called with a set containing exactly the attributes
   <varname>x</varname>, <varname>y</varname> and
@@ -982,7 +979,7 @@ map (concat "foo") ["bar" "bla" "abc"]</programlisting>
   (<literal>...</literal>): 
 
 <programlisting>
-{x, y, z, ....}: z + y + x</programlisting>
+{ x, y, z, ... }: z + y + x</programlisting>
 
   This works on any set that contains at least the three named
   attributes.</para>
@@ -995,7 +992,7 @@ map (concat "foo") ["bar" "bla" "abc"]</programlisting>
   <replaceable>e</replaceable> is an arbitrary expression.  For example,
 
 <programlisting>
-{x, y ? "foo", z ? "bar"}: z + y + x</programlisting>
+{ x, y ? "foo", z ? "bar" }: z + y + x</programlisting>
 
   specifies a function that only requires an attribute named
   <varname>x</varname>, but optionally accepts <varname>y</varname>
@@ -1007,11 +1004,11 @@ map (concat "foo") ["bar" "bla" "abc"]</programlisting>
   of the <literal>@</literal>-sign.  For example:
 
 <programlisting>
-args@{x, y, z, ...}: z + y + x + args.a</programlisting>
+args@{ x, y, z, ... }: z + y + x + args.a</programlisting>
 
   Here <varname>args</varname> is bound to the entire argument, which
-  is further matches against the pattern <literal>{x, y, z,
-  ...}</literal>.</para></listitem>
+  is further matches against the pattern <literal>{ x, y, z,
+  ... }</literal>.</para></listitem>
 
 
 </itemizedlist>
@@ -1020,8 +1017,8 @@ args@{x, y, z, ...}: z + y + x + args.a</programlisting>
 a name, you can bind them to an attribute, e.g.,
 
 <programlisting>
-let concat = {x, y}: x + y;
-in concat {x = "foo"; y = "bar";}</programlisting>
+let concat = { x, y }: x + y;
+in concat { x = "foo"; y = "bar"; }</programlisting>
 
 </para>
 
@@ -1142,7 +1139,7 @@ lexical scope of the expression <replaceable>e2</replaceable>.  For
 instance,
 
 <programlisting>
-let as = {x = "foo"; y = "bar";};
+let as = { x = "foo"; y = "bar"; };
 in with as; x + y</programlisting>
 
 evaluates to <literal>"foobar"</literal> since the
@@ -1480,21 +1477,20 @@ allowedReferences = [];
     references graph of their inputs.  The attribute is a list of
     inputs in the Nix store whose references graph the builder needs
     to know.  The value of this attribute should be a list of pairs
-    <literal>[<replaceable>name1</replaceable>
+    <literal>[ <replaceable>name1</replaceable>
     <replaceable>path1</replaceable> <replaceable>name2</replaceable>
-    <replaceable>path2</replaceable>
-    <replaceable>...</replaceable>]</literal>.  The references graph
-    of each <replaceable>pathN</replaceable> will be stored in a text
-    file <replaceable>nameN</replaceable> in the temporary build
-    directory.  The text files have the format used by
-    <command>nix-store --register-validity</command> (with the deriver
-    fields left empty).  For example, when the following derivation is
-    built:
+    <replaceable>path2</replaceable> <replaceable>...</replaceable>
+    ]</literal>.  The references graph of each
+    <replaceable>pathN</replaceable> will be stored in a text file
+    <replaceable>nameN</replaceable> in the temporary build directory.
+    The text files have the format used by <command>nix-store
+    --register-validity</command> (with the deriver fields left
+    empty).  For example, when the following derivation is built:
 
 <programlisting>
 derivation {
   ...
-  exportReferencesGraph = ["libfoo-graph" libfoo];
+  exportReferencesGraph = [ "libfoo-graph" libfoo ];
 };
 </programlisting>
 
@@ -1571,14 +1567,14 @@ fetchurl {
     <varname>fetchurl</varname>:
 
 <programlisting>
-{stdenv, curl}: # The <command>curl</command> program is used for downloading.
+{ stdenv, curl }: # The <command>curl</command> program is used for downloading.
 
-{url, md5}:
+{ url, md5 }:
 
 stdenv.mkDerivation {
   name = baseNameOf (toString url);
   builder = ./builder.sh;
-  buildInputs = [curl];
+  buildInputs = [ curl ];
 
   # This is a fixed-output derivation; the output must be a regular
   # file with MD5 hash <varname>md5</varname>.
@@ -1650,7 +1646,7 @@ stdenv.mkDerivation {
     Nixpkgs has the line
 
 <programlisting>
-impureEnvVars = ["http_proxy" "https_proxy" <replaceable>...</replaceable>];
+impureEnvVars = [ "http_proxy" "https_proxy" <replaceable>...</replaceable> ];
 </programlisting>
 
     to make it use the proxy server configuration specified by the
diff --git a/perl/lib/Nix/Config.pm.in b/perl/lib/Nix/Config.pm.in
index b657683be3..c88854daf0 100644
--- a/perl/lib/Nix/Config.pm.in
+++ b/perl/lib/Nix/Config.pm.in
@@ -2,6 +2,7 @@ package Nix::Config;
 
 $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
 $libexecDir = $ENV{"NIX_LIBEXEC_DIR"} || "@libexecdir@";
+$stateDir = $ENV{"NIX_STATE_DIR"} || "@localstatedir@/nix";
 $manifestDir = $ENV{"NIX_MANIFESTS_DIR"} || "@localstatedir@/nix/manifests";
 $logDir = $ENV{"NIX_LOG_DIR"} || "@localstatedir@/log/nix";
 $confDir = $ENV{"NIX_CONF_DIR"} || "@sysconfdir@/nix";
diff --git a/scripts/nix-build.in b/scripts/nix-build.in
index d9d1da73b1..68c24b75d4 100755
--- a/scripts/nix-build.in
+++ b/scripts/nix-build.in
@@ -1,8 +1,7 @@
 #! @perl@ -w -I@libexecdir@/nix
 
 use strict;
-
-my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
+use Nix::Config;
 
 
 my $addDrvLink = 0;
@@ -156,7 +155,7 @@ foreach my $expr (@exprs) {
     # Instantiate.
     my @drvPaths;
     # !!! would prefer the perl 5.8.0 pipe open feature here.
-    my $pid = open(DRVPATHS, "-|") || exec "$binDir/nix-instantiate", "--add-root", $drvLink, "--indirect", @instArgs, $expr;
+    my $pid = open(DRVPATHS, "-|") || exec "$Nix::Config::binDir/nix-instantiate", "--add-root", $drvLink, "--indirect", @instArgs, $expr;
     while (<DRVPATHS>) {chomp; push @drvPaths, $_;}
     if (!close DRVPATHS) {
         die "nix-instantiate killed by signal " . ($? & 127) . "\n" if ($? & 127);
@@ -170,7 +169,7 @@ foreach my $expr (@exprs) {
 
     # Build.
     my @outPaths;
-    $pid = open(OUTPATHS, "-|") || exec "$binDir/nix-store", "--add-root", $outLink, "--indirect", "-r",
+    $pid = open(OUTPATHS, "-|") || exec "$Nix::Config::binDir/nix-store", "--add-root", $outLink, "--indirect", "-r",
         @buildArgs, @drvPaths;
     while (<OUTPATHS>) {chomp; push @outPaths, $_;}
     if (!close OUTPATHS) {
diff --git a/scripts/nix-channel.in b/scripts/nix-channel.in
index 3688063cba..9bfa047226 100755
--- a/scripts/nix-channel.in
+++ b/scripts/nix-channel.in
@@ -1,15 +1,13 @@
 #! @perl@ -w
 
 use strict;
+use Nix::Config;
 
-my $rootsDir = "@localstatedir@/nix/gcroots";
-
-my $stateDir = $ENV{"NIX_STATE_DIR"};
-$stateDir = "@localstatedir@/nix" unless defined $stateDir;
+my $manifestDir = $Nix::Config::manifestDir;
 
 
 # Turn on caching in nix-prefetch-url.
-my $channelCache = "$stateDir/channel-cache";
+my $channelCache = "$Nix::Config::stateDir/channel-cache";
 mkdir $channelCache, 0755 unless -e $channelCache;
 $ENV{'NIX_DOWNLOAD_CACHE'} = $channelCache if -W $channelCache;
 
@@ -79,19 +77,19 @@ sub update {
     readChannels;
 
     # Create the manifests directory if it doesn't exist.
-    mkdir "$stateDir/manifests", 0755 unless -e "$stateDir/manifests";
+    mkdir $manifestDir, 0755 unless -e $manifestDir;
 
     # Do we have write permission to the manifests directory?  If not,
     # then just skip pulling the manifest and just download the Nix
     # expressions.  If the user is a non-privileged user in a
     # multi-user Nix installation, he at least gets installation from
     # source.
-    if (-W "$stateDir/manifests") {
+    if (-W $manifestDir) {
 
         # Pull cache manifests.
         foreach my $url (@channels) {
             #print "pulling cache manifest from `$url'\n";
-            system("@bindir@/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0
+            system("$Nix::Config::binDir/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0
                 or die "cannot pull cache manifest from `$url'";
         }
 
@@ -110,7 +108,7 @@ sub update {
         print "downloading Nix expressions from `$fullURL'...\n";
         $ENV{"PRINT_PATH"} = 1;
         $ENV{"QUIET"} = 1;
-        my ($hash, $path) = `@bindir@/nix-prefetch-url '$fullURL'`;
+        my ($hash, $path) = `$Nix::Config::binDir/nix-prefetch-url '$fullURL'`;
         die "cannot fetch `$fullURL'" if $? != 0;
         chomp $path;
         $inputs .= '"' . $channelName . '"' . " " . $path . " ";
@@ -121,13 +119,13 @@ sub update {
     my $userName = getpwuid($<);
     die "who ARE you? go away" unless defined $userName;
 
-    my $rootFile = "$rootsDir/per-user/$userName/channels";
+    my $rootFile = "$Nix::Config::stateDir/gcroots/per-user/$userName/channels";
     
     # Build the Nix expression.
     print "unpacking channel Nix expressions...\n";
     my $outPath = `\\
-        @bindir@/nix-build --out-link '$rootFile' --drv-link '$rootFile'.tmp \\
-        @datadir@/nix/corepkgs/channels/unpack.nix \\
+        $Nix::Config::binDir/nix-build --out-link '$rootFile' --drv-link '$rootFile'.tmp \\
+        '<nix/unpack-channel.nix>' \\
         --argstr system @system@ --arg inputs '$inputs'`
         or die "cannot unpack the channels";
     chomp $outPath;
diff --git a/scripts/nix-collect-garbage.in b/scripts/nix-collect-garbage.in
index f445c1c712..00e61a24b7 100755
--- a/scripts/nix-collect-garbage.in
+++ b/scripts/nix-collect-garbage.in
@@ -1,11 +1,10 @@
 #! @perl@ -w
 
 use strict;
+use Nix::Config;
 
 my $profilesDir = "@localstatedir@/nix/profiles";
 
-my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
-
 
 # Process the command line arguments.
 my @args = ();
@@ -36,7 +35,7 @@ sub removeOldGenerations {
         $name = $dir . "/" . $name;
         if (-l $name && (readlink($name) =~ /link/)) {
             print STDERR "removing old generations of profile $name\n";
-            system("$binDir/nix-env", "-p", $name, "--delete-generations", "old");
+            system("$Nix::Config::binDir/nix-env", "-p", $name, "--delete-generations", "old");
         }
         elsif (! -l $name && -d $name) {
             removeOldGenerations $name;
@@ -50,4 +49,4 @@ removeOldGenerations $profilesDir if $removeOld;
 
 
 # Run the actual garbage collector.
-exec "$binDir/nix-store", "--gc", @args;
+exec "$Nix::Config::binDir/nix-store", "--gc", @args;
diff --git a/scripts/nix-pull.in b/scripts/nix-pull.in
index 74545a3500..136a5c9fa4 100755
--- a/scripts/nix-pull.in
+++ b/scripts/nix-pull.in
@@ -8,9 +8,6 @@ use Nix::Manifest;
 my $tmpDir = tempdir("nix-pull.XXXXXX", CLEANUP => 1, TMPDIR => 1)
     or die "cannot create a temporary directory";
 
-my $libexecDir = ($ENV{"NIX_LIBEXEC_DIR"} or "@libexecdir@");
-my $storeDir = ($ENV{"NIX_STORE_DIR"} or "@storedir@");
-my $stateDir = ($ENV{"NIX_STATE_DIR"} or "@localstatedir@/nix");
 my $manifestDir = $Nix::Config::manifestDir;
 
 
@@ -25,7 +22,7 @@ if (! -e $manifestDir) {
 
 
 # Make sure that the manifests directory is scanned for GC roots.
-my $gcRootsDir = "$stateDir/gcroots";
+my $gcRootsDir = "$Nix::Config::stateDir/gcroots";
 my $manifestDirLink = "$gcRootsDir/manifests";
 if (! -l $manifestDirLink) {
     symlink($manifestDir, $manifestDirLink) or die "cannot create symlink `$manifestDirLink'";
diff --git a/scripts/nix-push.in b/scripts/nix-push.in
index cf46d00dfb..1e0918abd6 100755
--- a/scripts/nix-push.in
+++ b/scripts/nix-push.in
@@ -18,11 +18,6 @@ my $curl = "$Nix::Config::curl --fail --silent";
 my $extraCurlFlags = ${ENV{'CURL_FLAGS'}};
 $curl = "$curl $extraCurlFlags" if defined $extraCurlFlags;
 
-my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
-
-my $dataDir = $ENV{"NIX_DATA_DIR"};
-$dataDir = "@datadir@" unless defined $dataDir;
-
 
 # Parse the command line.
 my $localCopy;
@@ -82,7 +77,7 @@ foreach my $path (@ARGV) {
     # Get all paths referenced by the normalisation of the given 
     # Nix expression.
     my $pid = open(READ,
-        "$binDir/nix-store --query --requisites --force-realise " .
+        "$Nix::Config::binDir/nix-store --query --requisites --force-realise " .
         "--include-outputs '$path'|") or die;
     
     while (<READ>) {
@@ -107,7 +102,7 @@ foreach my $storePath (@storePaths) {
 
     # Construct a Nix expression that creates a Nix archive.
     my $nixexpr = 
-        "((import $dataDir/nix/corepkgs/nar/nar.nix) " .
+        "(import <nix/nar.nix> " .
         "{ storePath = builtins.storePath \"$storePath\"; system = \"@system@\"; hashAlgo = \"$hashAlgo\"; }) ";
     
     print NIX $nixexpr;
@@ -120,7 +115,7 @@ close NIX;
 # Instantiate store derivations from the Nix expression.
 my @storeExprs;
 print STDERR "instantiating store derivations...\n";
-my $pid = open(READ, "$binDir/nix-instantiate $nixExpr|")
+my $pid = open(READ, "$Nix::Config::binDir/nix-instantiate $nixExpr|")
     or die "cannot run nix-instantiate";
 while (<READ>) {
     chomp;
@@ -142,7 +137,7 @@ while (scalar @tmp > 0) {
     my @tmp2 = @tmp[0..$n - 1];
     @tmp = @tmp[$n..scalar @tmp - 1];
 
-    my $pid = open(READ, "$binDir/nix-store --realise @tmp2|")
+    my $pid = open(READ, "$Nix::Config::binDir/nix-store --realise @tmp2|")
         or die "cannot run nix-store";
     while (<READ>) {
         chomp;
@@ -182,16 +177,16 @@ for (my $n = 0; $n < scalar @storePaths; $n++) {
 
     my $narbz2Size = stat($narFile)->size;
 
-    my $references = `$binDir/nix-store --query --references '$storePath'`;
+    my $references = `$Nix::Config::binDir/nix-store --query --references '$storePath'`;
     die "cannot query references for `$storePath'" if $? != 0;
     $references = join(" ", split(" ", $references));
 
-    my $deriver = `$binDir/nix-store --query --deriver '$storePath'`;
+    my $deriver = `$Nix::Config::binDir/nix-store --query --deriver '$storePath'`;
     die "cannot query deriver for `$storePath'" if $? != 0;
     chomp $deriver;
     $deriver = "" if $deriver eq "unknown-deriver";
 
-    my $narHash = `$binDir/nix-store --query --hash '$storePath'`;
+    my $narHash = `$Nix::Config::binDir/nix-store --query --hash '$storePath'`;
     die "cannot query hash for `$storePath'" if $? != 0;
     chomp $narHash;
 
@@ -199,13 +194,13 @@ for (my $n = 0; $n < scalar @storePaths; $n++) {
     # store of the host), the database doesn't contain the hash.  So
     # compute it.
     if ($narHash =~ /^sha256:0*$/) {
-        $narHash = `$binDir/nix-hash --type sha256 --base32 '$storePath'`;
+        $narHash = `$Nix::Config::binDir/nix-hash --type sha256 --base32 '$storePath'`;
         die "cannot hash `$storePath'" if $? != 0;
         chomp $narHash;
         $narHash = "sha256:$narHash";
     }
 
-    my $narSize = `$binDir/nix-store --query --size '$storePath'`;
+    my $narSize = `$Nix::Config::binDir/nix-store --query --size '$storePath'`;
     die "cannot query size for `$storePath'" if $? != 0;
     chomp $narSize;
 
diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc
index 670052bcbb..0dcdcc0d18 100644
--- a/src/nix-env/user-env.cc
+++ b/src/nix-env/user-env.cc
@@ -112,7 +112,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
 
     /* Get the environment builder expression. */
     Value envBuilder;
-    state.evalFile(nixDataDir + "/nix/corepkgs/buildenv", envBuilder);
+    state.evalFile(state.findFile("nix/buildenv.nix"), envBuilder);
 
     /* Construct a Nix expression that calls the user environment
        builder with the manifest as argument. */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 70352dbb5d..15c103ec46 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -8,7 +8,8 @@ TESTS = init.sh hash.sh lang.sh add.sh simple.sh dependencies.sh \
   referrers.sh user-envs.sh logging.sh nix-build.sh misc.sh fixed.sh \
   gc-runtime.sh install-package.sh check-refs.sh filter-source.sh \
   remote-store.sh export.sh export-graph.sh negative-caching.sh \
-  binary-patching.sh timeout.sh secure-drv-outputs.sh multiple-outputs.sh
+  binary-patching.sh timeout.sh secure-drv-outputs.sh nix-channel.sh \
+  multiple-outputs.sh
 
 XFAIL_TESTS =
 
@@ -38,4 +39,3 @@ EXTRA_DIST = $(TESTS) \
   multiple-outputs.nix \
   $(wildcard lang/*.nix) $(wildcard lang/*.exp) $(wildcard lang/*.exp.xml) $(wildcard lang/*.flags) $(wildcard lang/dir*/*.nix) \
   common.sh.in
-
diff --git a/tests/common.sh.in b/tests/common.sh.in
index 4ab490a626..7504dc059e 100644
--- a/tests/common.sh.in
+++ b/tests/common.sh.in
@@ -9,7 +9,6 @@ if ! NIX_STORE_DIR=$(readlink -f $TEST_ROOT/store 2> /dev/null); then
     export NIX_IGNORE_SYMLINK_STORE=1
     NIX_STORE_DIR=$TEST_ROOT/store
 fi
-export NIX_DATA_DIR=$TEST_ROOT/data
 export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
 export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
 export NIX_STATE_DIR=$TEST_ROOT/var/nix
@@ -19,15 +18,11 @@ export NIX_BIN_DIR=$TEST_ROOT/bin
 export NIX_LIBEXEC_DIR=$TEST_ROOT/bin
 export NIX_MANIFESTS_DIR=$TEST_ROOT/var/nix/manifests
 export NIX_ROOT_FINDER=
+export NIX_PATH=nix=$TOP/corepkgs
 export SHARED=$TEST_ROOT/shared
 
 export PATH=$NIX_BIN_DIR:$TOP/scripts:$PATH
 
-export REAL_BIN_DIR=@bindir@
-export REAL_LIBEXEC_DIR=@libexecdir@
-export REAL_LOCALSTATE_DIR=@localstatedir@
-export REAL_DATA_DIR=@datadir@
-export REAL_STORE_DIR=@storedir@
 export NIX_BUILD_HOOK=
 export PERL=perl
 export PERL5LIB=$TOP/perl/lib:$PERL5LIB
diff --git a/tests/config.nix.in b/tests/config.nix.in
index 2bfee8b44b..db3da14513 100644
--- a/tests/config.nix.in
+++ b/tests/config.nix.in
@@ -13,5 +13,6 @@ rec {
       builder = shell;
       args = ["-e" args.builder];
       PATH = path;
-    } // removeAttrs args ["builder"]);
+    } // removeAttrs args ["builder" "meta"])
+    // { meta = args.meta or {}; };
 }
diff --git a/tests/dependencies.nix b/tests/dependencies.nix
index 00717ae98d..6f6a7e46fa 100644
--- a/tests/dependencies.nix
+++ b/tests/dependencies.nix
@@ -17,6 +17,7 @@ let {
     builder = ./dependencies.builder0.sh  + "/FOOBAR/../.";
     input1 = input1 + "/.";
     inherit input2;
+    meta.description = "Random test package";
   };
 
 }
diff --git a/tests/init.sh b/tests/init.sh
index 63e939dff1..9ce7985d70 100644
--- a/tests/init.sh
+++ b/tests/init.sh
@@ -10,7 +10,6 @@ fi
 mkdir "$TEST_ROOT"
 
 mkdir "$NIX_STORE_DIR"
-mkdir "$NIX_DATA_DIR"
 mkdir "$NIX_LOCALSTATE_DIR"
 mkdir -p "$NIX_LOG_DIR"/drvs
 mkdir "$NIX_STATE_DIR"
@@ -39,29 +38,6 @@ env-keep-derivations = false
 fsync-metadata = false
 EOF
 
-mkdir $NIX_DATA_DIR/nix
-cp -pr $TOP/corepkgs $NIX_DATA_DIR/nix/
-# Bah, scripts have the prefix hard-coded.  This is really messy stuff
-# (and likely to fail).
-for i in \
-    $NIX_DATA_DIR/nix/corepkgs/nar/nar.sh \
-    ; do
-    sed < $i > $i.tmp \
-        -e "s^$REAL_BIN_DIR/nix-store^$NIX_BIN_DIR/nix-store^" \
-        -e "s^$REAL_BIN_DIR/nix-hash^$NIX_BIN_DIR/nix-hash^" \
-        -e "s^$REAL_LIBEXEC_DIR^$NIX_LIBEXEC_DIR^" \
-        -e "s^$REAL_LOCALSTATE_DIR^$NIX_LOCALSTATE_DIR^" \
-        -e "s^$REAL_DATA_DIR^$NIX_DATA_DIR^" \
-        -e "s^$REAL_STORE_DIR\([^/]\)^$NIX_STORE_DIR\1^"
-    mv $i.tmp $i
-    chmod +x $i
-done
-
-# Another ugly hack.
-sed "s|^$|PATH='$PATH'|" < $NIX_DATA_DIR/nix/corepkgs/nar/nar.sh > tmp
-chmod +x tmp
-mv tmp $NIX_DATA_DIR/nix/corepkgs/nar/nar.sh
-
 # An uberhack for Mac OS X 10.5: download-using-manifests uses Perl,
 # and Perl links against Darwin's libutil.dylib (in /usr/lib), but
 # when running "make check", the libtool wrapper script around the Nix
diff --git a/tests/lang.sh b/tests/lang.sh
index c9fc65e6ac..cab1cfd9b0 100644
--- a/tests/lang.sh
+++ b/tests/lang.sh
@@ -40,7 +40,7 @@ for i in lang/eval-okay-*.nix; do
         if test -e lang/$i.flags; then
             flags=$(cat lang/$i.flags)
         fi
-        if ! NIX_PATH=lang/dir3:lang/dir4 nix-instantiate $flags --eval-only --strict lang/$i.nix > lang/$i.out; then
+        if ! NIX_PATH=lang/dir3:lang/dir4:$NIX_PATH nix-instantiate $flags --eval-only --strict lang/$i.nix > lang/$i.out; then
             echo "FAIL: $i should evaluate"
             fail=1
         elif ! diff lang/$i.out lang/$i.exp; then
diff --git a/tests/lang/eval-okay-search-path.nix b/tests/lang/eval-okay-search-path.nix
index 21485dbbf6..9b71150233 100644
--- a/tests/lang/eval-okay-search-path.nix
+++ b/tests/lang/eval-okay-search-path.nix
@@ -1,3 +1,3 @@
-assert builtins.pathExists <nix/buildenv>;
+assert builtins.pathExists <nix/buildenv.nix>;
 
 import <a.nix> + import <b.nix> + import <c.nix> + import <dir5/c.nix>
diff --git a/tests/nix-channel.sh b/tests/nix-channel.sh
new file mode 100644
index 0000000000..4819b57c91
--- /dev/null
+++ b/tests/nix-channel.sh
@@ -0,0 +1,43 @@
+source common.sh
+
+clearProfiles
+clearManifests
+
+rm -f $TEST_ROOT/.nix-channels
+
+# Override location of ~/.nix-channels.
+export HOME=$TEST_ROOT
+
+# Test add/list/remove.
+nix-channel --add http://foo/bar
+nix-channel --list | grep -q http://foo/bar
+nix-channel --remove http://foo/bar
+
+[ -e $TEST_ROOT/.nix-channels ]
+[ "$(cat $TEST_ROOT/.nix-channels)" = '' ]
+
+# Create a channel.
+rm -rf $TEST_ROOT/foo
+mkdir -p $TEST_ROOT/foo
+nix-push --copy $TEST_ROOT/foo $TEST_ROOT/foo/MANIFEST $(nix-store -r $(nix-instantiate dependencies.nix))
+rm -rf $TEST_ROOT/nixexprs
+mkdir -p $TEST_ROOT/nixexprs
+cp config.nix dependencies.nix dependencies.builder*.sh $TEST_ROOT/nixexprs/
+ln -s dependencies.nix $TEST_ROOT/nixexprs/default.nix
+(cd $TEST_ROOT && tar cvf - nixexprs) | bzip2 > $TEST_ROOT/foo/nixexprs.tar.bz2
+
+# Test the update action.
+nix-channel --add file://$TEST_ROOT/foo
+nix-channel --update
+
+# Do a query.
+nix-env -qa \* --meta --xml --out-path > $TEST_ROOT/meta.xml
+if [ "$xmllint" != false ]; then
+    $xmllint --noout $TEST_ROOT/meta.xml || fail "malformed XML"
+fi
+grep -q 'meta.*description.*Random test package' $TEST_ROOT/meta.xml
+grep -q 'item.*attrPath="foo".*name="dependencies"' $TEST_ROOT/meta.xml
+
+# Do an install.
+nix-env -i dependencies
+[ -e $TEST_ROOT/var/nix/profiles/default/foobar ]
diff --git a/tests/user-envs.sh b/tests/user-envs.sh
index 5037e28b91..2bc9bee50b 100644
--- a/tests/user-envs.sh
+++ b/tests/user-envs.sh
@@ -36,7 +36,7 @@ nix-env -p $profiles/test -q '*' | grep -q foo-2.0pre1
 test "$($profiles/test/bin/foo)" = "foo-2.0pre1"
 
 # Upgrade "foo": should install foo-2.0.
-NIX_PATH=nixpkgs=./user-envs.nix nix-env -p $profiles/test -f '<nixpkgs>' -u foo
+NIX_PATH=nixpkgs=./user-envs.nix:$NIX_PATH nix-env -p $profiles/test -f '<nixpkgs>' -u foo
 
 # Query installed: should contain foo-2.0 now.
 test "$(nix-env -p $profiles/test -q '*' | wc -l)" -eq 1