diff --git a/configure.ac b/configure.ac
index 7f2b0a7ce..221aa598f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT(nix, 0.11)
+AC_INIT(nix, 0.12)
AC_CONFIG_SRCDIR(README)
AC_CONFIG_AUX_DIR(config)
AM_INIT_AUTOMAKE([dist-bzip2 foreign])
@@ -273,6 +273,10 @@ AM_CONDITIONAL(INIT_STATE, test "$init_state" = "yes")
AC_CHECK_FUNCS([setresuid setreuid lchown])
+# Nice to have, but not essential.
+AC_CHECK_FUNCS([strsignal])
+
+
# This is needed if ATerm, Berkeley DB or bzip2 are static libraries,
# and the Nix libraries are dynamic.
if test "$(uname)" = "Darwin"; then
diff --git a/doc/manual/build-farm.xml b/doc/manual/build-farm.xml
index cfca63f36..9a6345896 100644
--- a/doc/manual/build-farm.xml
+++ b/doc/manual/build-farm.xml
@@ -36,10 +36,10 @@ build farm, since:
builds, and Nix expressions are self-contained.
Nix will only rebuild things that have actually
- changed. For instance, if the sources of a component haven't
- changed between runs of the build farm, the component won't be
- rebuild (unless it was garbage-collected). Also, dependencies
- typically don't change very often, so they only need to be built
+ changed. For instance, if the sources of a package haven't changed
+ between runs of the build farm, the package won't be rebuilt (unless
+ it was garbage-collected). Also, dependencies typically don't
+ change very often, so they only need to be built
once.The results of a Nix build farm can be made
diff --git a/doc/manual/builtins.xml b/doc/manual/builtins.xml
index b6c886199..3b6b80324 100644
--- a/doc/manual/builtins.xml
+++ b/doc/manual/builtins.xml
@@ -441,6 +441,15 @@ in config.someSetting
-->
+ builtins.readFile
+ path
+
+ Return the contents of the file
+ path as a string.
+
+
+
+
removeAttrsattrslist
@@ -477,7 +486,7 @@ removeAttrs { x = 1; y = 2; z = 3; } ["a" "x" "z"]
- builtins.substr
+ builtins.substringstartlens
diff --git a/doc/manual/glossary.xml b/doc/manual/glossary.xml
index e76f99a26..efbf96f0a 100644
--- a/doc/manual/glossary.xml
+++ b/doc/manual/glossary.xml
@@ -74,9 +74,9 @@
Nix expression
- A high-level description of software components and
+ A high-level description of software packages and
compositions thereof. Deploying software using Nix entails writing
- Nix expressions for your components. Nix expressions are translated
+ Nix expressions for your packages. Nix expressions are translated
to derivations that are stored in the Nix store. These derivations
can then be built.
diff --git a/doc/manual/installation.xml b/doc/manual/installation.xml
index 72e4b541a..d61c0c230 100644
--- a/doc/manual/installation.xml
+++ b/doc/manual/installation.xml
@@ -42,9 +42,8 @@ platforms as well.Obtaining NixThe easiest way to obtain Nix is to download a source
-distribution. RPMs for Red Hat, SuSE, and Fedora Core are also
-available.
+xlink:href="http://nix.cs.uu.nl/">source distribution. RPMs
+for Red Hat, SuSE, and Fedora Core are also available.Alternatively, the most recent sources of Nix can be obtained
from its
Installing from RPMs
-RPM packages of Nix can be downloaded from http://www.cs.uu.nl/groups/ST/Trace/Nix.
-These RPMs should work for most fairly recent releases of SuSE and Red
-Hat Linux. They have been known to work work on SuSE Linux 8.1 and
-9.0, and Red Hat 9.0. In fact, it should work on any RPM-based Linux
-distribution based on glibc 2.3 or later.
+RPM packages of Nix can be downloaded from . These RPMs should work for most
+fairly recent releases of SuSE and Red Hat Linux. They have been
+known to work work on SuSE Linux 8.1 and 9.0, and Red Hat 9.0. In
+fact, it should work on any RPM-based Linux distribution based on
+glibc 2.3 or later.Once downloaded, the RPMs can be installed or upgraded using
rpm -U. For example,
diff --git a/doc/manual/introduction.xml b/doc/manual/introduction.xml
index 7f7cd11d5..d2f23bf44 100644
--- a/doc/manual/introduction.xml
+++ b/doc/manual/introduction.xml
@@ -50,7 +50,7 @@ are complete. In general, when you’re making a package for a package
management system like RPM, you have to specify for each package what
its dependencies are, but there are no guarantees that this
specification is complete. If you forget a dependency, then the
-component will build and work correctly on your
+package will build and work correctly on your
machine if you have the dependency installed, but not on the end
user's machine if it's not there.
diff --git a/doc/manual/nix-build.xml b/doc/manual/nix-build.xml
index 3f35f5de3..695ddcf46 100644
--- a/doc/manual/nix-build.xml
+++ b/doc/manual/nix-build.xml
@@ -19,6 +19,7 @@
nix-buildnamevalue
+ namevalue
diff --git a/doc/manual/nix-channel.xml b/doc/manual/nix-channel.xml
index 8ee4a5f27..14021067c 100644
--- a/doc/manual/nix-channel.xml
+++ b/doc/manual/nix-channel.xml
@@ -62,11 +62,11 @@ also .Downloads the Nix expressions of all subscribed
- channels, makes the conjunction of these the default for
- nix-env operations (by calling nix-env
- -I), and performs a nix-pull on the
- manifests of all channels to make pre-built binaries
- available.
+ channels, makes them the default for nix-env
+ operations (by symlinking them in the directory
+ ~/.nix-defexpr), and performs a
+ nix-pull on the manifests of all channels to
+ make pre-built binaries available.
diff --git a/doc/manual/nix-env.xml b/doc/manual/nix-env.xml
index 9af8c0c02..9f73b2d4c 100644
--- a/doc/manual/nix-env.xml
+++ b/doc/manual/nix-env.xml
@@ -19,6 +19,7 @@
nix-envnamevalue
+ namevalue
@@ -48,7 +49,7 @@
DescriptionThe command nix-env is used to manipulate Nix
-user environments. User environments are sets of software components
+user environments. User environments are sets of software packages
available to a user at some point in time. In other words, they are a
synthesised view of the programs available in the Nix store. There
may be many user environments: different users can have different
@@ -141,13 +142,33 @@ linkend="sec-common-options" />.~/.nix-defexpr
-
-
- The default Nix expression used by the
- , , and
- operations to obtain
- derivations. The option may be used to
- override this default.
+ A directory that contains the default Nix
+ expressions used by the ,
+ , and operations to obtain derivations. The
+ option may be used to override this
+ default.
+
+ The Nix expressions in this directory are combined into a
+ single attribute set, with each file as an attribute that has the
+ name of the file. Thus, if ~/.nix-defexpr
+ contains two files, foo and
+ bar, then the default Nix expression will
+ essentially be
+
+
+{
+ foo = import ~/.nix-defexpr/foo;
+ bar = import ~/.nix-defexpr/bar;
+}
+
+
+
+ The command nix-channel places symlinks
+ to the downloaded Nix expressions from each subscribed channel in
+ this directory.
+
+
@@ -212,11 +233,21 @@ number of possible ways:
If there are multiple derivations matching a name in
args that have the same name (e.g.,
gcc-3.3.6 and gcc-4.1.1), then
- only the highest version will be installed. You can force the
- installation of multiple derivations with the same name by being
- specific about the versions. For instance, nix-env -i
- gcc-3.3.6 gcc-4.1.1 will install both version of GCC (and
- will probably cause a user environment conflict!).
+ the derivation with the highest priority is
+ used. A derivation can define a priority by declaring the
+ meta.priority attribute. This attribute should
+ be a number, with a higher value denoting a lower priority. The
+ default priority is 0.
+
+ If there are multiple matching derivations with the same
+ priority, then the derivation with the highest version will be
+ installed.
+
+ You can force the installation of multiple derivations with
+ the same name by being specific about the versions. For instance,
+ nix-env -i gcc-3.3.6 gcc-4.1.1 will install both
+ version of GCC (and will probably cause a user environment
+ conflict!).If
@@ -263,6 +294,15 @@ number of possible ways:
+ /
+
+ Use only derivations for which a substitute is
+ registered, i.e., there is a pre-built binary available that can
+ be downloaded in lieu of building the derivation. Thus, no
+ packages will be built from source.
+
+
+
@@ -378,7 +418,7 @@ the following paths will be substituted:
-Operation
+Operation Synopsis
@@ -463,6 +503,9 @@ installed.
+For the other flags, see .
+
Examples
@@ -572,6 +615,111 @@ $ nix-env -e '*' (remove everything)
+
+
+Operation
+
+Synopsis
+
+
+ nix-env
+
+ name
+ value
+ drvnames
+
+
+
+Description
+
+The operation allows meta attributes
+of installed packages to be modified. There are several attributes
+that can be usefully modified, because they affect the behaviour of
+nix-env or the user environment build
+script:
+
+
+
+ priority can be changed to
+ resolve filename clashes. The user environment build script uses
+ the meta.priority attribute of derivations to
+ resolve filename collisions between packages. Lower priority values
+ denote a higher priority. For instance, the GCC wrapper package and
+ the Binutils package in Nixpkgs both have a file
+ bin/ld, so previously if you tried to install
+ both you would get a collision. Now, on the other hand, the GCC
+ wrapper declares a higher priority than Binutils, so the former’s
+ bin/ld is symlinked in the user
+ environment.
+
+ keep can be set to
+ true to prevent the package from being upgraded
+ or replaced. This is useful if you want to hang on to an older
+ version of a package.
+
+ active can be set to
+ false to “disable” the package. That is, no
+ symlinks will be generated to the files of the package, but it
+ remains part of the profile (so it won’t be garbage-collected). It
+ can be set back to true to re-enable the
+ package.
+
+
+
+
+
+
+
+Examples
+
+To prevent the currently installed Firefox from being upgraded:
+
+
+$ nix-env --set-flag keep true firefox
+
+After this, nix-env -u will ignore Firefox.
+
+To disable the currently installed Firefox, then install a new
+Firefox while the old remains part of the profile:
+
+
+$ nix-env -q \*
+firefox-2.0.0.9 (the current one)
+
+$ nix-env --preserve-installed -i firefox-2.0.0.11
+installing `firefox-2.0.0.11'
+building path(s) `/nix/store/myy0y59q3ig70dgq37jqwg1j0rsapzsl-user-environment'
+Collission between `/nix/store/...-firefox-2.0.0.11/bin/firefox'
+ and `/nix/store/...-firefox-2.0.0.9/bin/firefox'.
+(i.e., can’t have two active at the same time)
+
+$ nix-env --set-flag active false firefox
+setting flag on `firefox-2.0.0.9'
+
+$ nix-env --preserve-installed -i firefox-2.0.0.11
+installing `firefox-2.0.0.11'
+
+$ nix-env -q \*
+firefox-2.0.0.11 (the enabled one)
+firefox-2.0.0.9 (the disabled one)
+
+
+
+To make files from binutils take precedence
+over files from gcc:
+
+
+$ nix-env --set-flag priority 5 binutils
+$ nix-env --set-flag priority 10 gcc
+
+
+
+
+
+
+
+
+
Operation
@@ -598,7 +746,12 @@ $ nix-env -e '*' (remove everything)
-
+
+
+
+
+
+
@@ -621,6 +774,7 @@ $ nix-env -e '*' (remove everything)
+
@@ -707,6 +861,16 @@ user environment elements, etc. -->
+ /
+
+ Show only derivations for which a substitute is
+ registered, i.e., there is a pre-built binary available that can
+ be downloaded in lieu of building the derivation. Thus, this
+ shows all packages that probably can be installed
+ quickly.
+
+
+
@@ -726,8 +890,8 @@ user environment elements, etc. -->
-
-
+
+ Print the attribute path of
the derivation, which can be used to unambiguously select it using
@@ -750,35 +914,35 @@ user environment elements, etc. -->
Compare installed versions to available versions,
or vice versa (if is given). This is
useful for quickly seeing whether upgrades for installed
- components are available in a Nix expression. A column is added
+ packages are available in a Nix expression. A column is added
with the following meaning:
<version
- A newer version of the component is available
+ A newer version of the package is available
or installed.=version
- At most the same version of the component is
+ At most the same version of the package is
available or installed.>version
- Only older versions of the component are
+ Only older versions of the package are
available or installed.- ?
- No version of the component is available or
+ No version of the package is available or
installed.
@@ -819,6 +983,14 @@ user environment elements, etc. -->
+
+
+ Print all of the meta-attributes of the
+ derivation. This option is only available with
+ .
+
+
+
diff --git a/doc/manual/nix-store.xml b/doc/manual/nix-store.xml
index a168be024..da3eae2ec 100644
--- a/doc/manual/nix-store.xml
+++ b/doc/manual/nix-store.xml
@@ -779,4 +779,178 @@ archive is read from standard input.
+
+
+Operation
+
+
+ Synopsis
+
+ nix-store
+
+ paths
+
+
+
+Description
+
+The operation writes a serialisation
+of the specified store paths to standard output in a format that can
+be imported into another Nix store with nix-store --import. This
+is like nix-store
+--dump, except that the NAR archive produced by that command
+doesn’t contain the necessary meta-information to allow it to be
+imported into another Nix store (namely, the set of references of the
+path).
+
+This command does not produce a closure of
+the specified paths, so if a store path references other store paths
+that are missing in the target Nix store, the import will fail. To
+copy a whole closure, do something like
+
+
+$ nix-store --export $(nix-store -qR paths) > out
+
+
+
+For an example of how and
+ can be used, see the source of the nix-copy-closure
+command.
+
+
+
+
+
+
+
+
+
+Operation
+
+
+ Synopsis
+
+ nix-store
+
+
+
+
+Description
+
+The operation reads a serialisation of
+a set of store paths produced by nix-store --import from
+standard input and adds those store paths to the Nix store. Paths
+that already exist in the Nix store are ignored. If a path refers to
+another path that doesn’t exist in the Nix store, the import
+fails.
+
+
+
+
+
+
+
+
+
+Operation
+
+
+ Synopsis
+
+ nix-store
+
+
+
+
+Description
+
+The operation reduces Nix store disk
+space usage by finding identical files in the store and hard-linking
+them to each other. It typically reduces the size of the store by
+something like 25-35%. Only regular files and symlinks are
+hard-linked in this manner. Files are considered identical when they
+have the same NAR archive serialisation: that is, regular files must
+have the same contents and permission (executable or non-executable),
+and symlinks must have the same contents.
+
+After completion, or when the command is interrupted, a report
+on the achieved savings is printed on standard error.
+
+Use or to get some
+progress indication.
+
+
+
+Example
+
+
+$ nix-store --optimise
+hashing files in `/nix/store/qhqx7l2f1kmwihc9bnxs7rc159hsxnf3-gcc-4.1.1'
+...
+541838819 bytes (516.74 MiB) freed by hard-linking 54143 files;
+there are 114486 files with equal contents out of 215894 files in total
+
+
+
+
+
+
+
+
+
+
+Operation
+
+
+ Synopsis
+
+ nix-store
+
+
+
+
+ paths
+
+
+
+Description
+
+The operation prints the build log
+of the specified store paths on standard output. The build log is
+whatever the builder of a derivation wrote to standard output and
+standard error. If a store path is not a derivation, the deriver of
+the store path is used.
+
+Build logs are kept in
+/nix/var/log/nix/drvs. However, there is no
+guarantee that a build log is available for any particular store
+path. For instance, if the path was downloaded as a pre-built binary
+through a substitute, then the log is unavailable.
+
+
+
+Example
+
+
+$ nix-store -l $(which ktorrent)
+building /nix/store/dhc73pvzpnzxhdgpimsd9sw39di66ph1-ktorrent-2.2.1
+unpacking sources
+unpacking source archive /nix/store/p8n1jpqs27mgkjw07pb5269717nzf5f8-ktorrent-2.2.1.tar.gz
+ktorrent-2.2.1/
+ktorrent-2.2.1/NEWS
+...
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/manual/opt-common.xml b/doc/manual/opt-common.xml
index 7dfb7b8f8..316ad6658 100644
--- a/doc/manual/opt-common.xml
+++ b/doc/manual/opt-common.xml
@@ -268,6 +268,17 @@
+namevalue
+
+ This option is like , only the
+ value is not a Nix expression but a string. So instead of
+ --arg system \"i686-linux\" (the outer quotes are
+ to keep the shell happy) you can say --argstr system
+ i686-linux.
+
+
+
+
/
attrPath
diff --git a/doc/manual/opt-inst-syn.xml b/doc/manual/opt-inst-syn.xml
index 1c32325e5..e8c3f1ec6 100644
--- a/doc/manual/opt-inst-syn.xml
+++ b/doc/manual/opt-inst-syn.xml
@@ -1,5 +1,12 @@
+
+
+
+
+
+
+
diff --git a/doc/manual/package-management.xml b/doc/manual/package-management.xml
index a24ca0a69..9ab181692 100644
--- a/doc/manual/package-management.xml
+++ b/doc/manual/package-management.xml
@@ -6,9 +6,9 @@
This chapter discusses how to do package management with Nix,
-i.e., how to obtain, install, upgrade, and erase components. This is
+i.e., how to obtain, install, upgrade, and erase packages. This is
the “user’s” perspective of the Nix system — people
-who want to create components should consult
+who want to create packages should consult
.
@@ -16,8 +16,8 @@ who want to create components should consult
The main command for package management is nix-env. You can use
-it to install, upgrade, and erase components, and to query what
-components are installed or are available for installation.
+it to install, upgrade, and erase packages, and to query what
+packages are installed or are available for installation.
In Nix, different users can have different “views”
on the set of installed applications. That is, there might be lots of
@@ -30,10 +30,10 @@ environment, which is just a directory tree consisting of
symlinks to the files of the active applications. Components are installed from a set of Nix
-expressions that tell Nix how to build those components,
+expressions that tell Nix how to build those packages,
including, if necessary, their dependencies. There is a collection of
Nix expressions called the Nix Package collection that contains
-components ranging from basic development stuff such as GCC and Glibc,
+packages ranging from basic development stuff such as GCC and Glibc,
to end-user applications like Mozilla Firefox. (Nix is however not
tied to the Nix Package collection; you could write your own Nix
expressions based on it, or completely new ones.) You can download
@@ -41,7 +41,7 @@ the latest version from .Assuming that you have downloaded and unpacked a release of Nix
-Packages, you can view the set of available components in the release:
+Packages, you can view the set of available packages in the release:
$ nix-env -qaf nixpkgs-version '*'
@@ -74,7 +74,7 @@ gcc-4.1.1It is also possible to see the status of
-available components, i.e., whether they are installed into the user
+available packages, i.e., whether they are installed into the user
environment and/or present in the system:
@@ -86,24 +86,24 @@ IPS bison-1.875d
...
The first character (I) indicates whether the
-component is installed in your current user environment. The second
+package is installed in your current user environment. The second
(P) indicates whether it is present on your system
(in which case installing it into your user environment would be a
very quick operation). The last one (S) indicates
whether there is a so-called substitute for the
-component, which is Nix’s mechanism for doing binary deployment. It
-just means that Nix knows that it can fetch a pre-built component from
+package, which is Nix’s mechanism for doing binary deployment. It
+just means that Nix knows that it can fetch a pre-built package from
somewhere (typically a network server) instead of building it
locally.So now that we have a set of Nix expressions we can build the
-components contained in them. This is done using nix-env
+packages contained in them. This is done using nix-env
-i. For instance,
$ nix-env -f nixpkgs-version -i subversion
-will install the component called subversion (which
+will install the package called subversion (which
is, of course, the Subversion version
management system).
@@ -112,7 +112,7 @@ management system).
Subversion and all its dependencies. This will take quite a while —
typically an hour or two on modern machines. Fortunately, there is a
faster way (so do a Ctrl-C on that install operation!): you just need
-to tell Nix that pre-built binaries of all those components are
+to tell Nix that pre-built binaries of all those packages are
available somewhere. This is done using the
nix-pull command, which must be supplied with a URL
containing a manifest describing what binaries
@@ -153,7 +153,7 @@ expressions, use -i instead of
-u; -i will remove
whatever version is already installed.
-You can also upgrade all components for which there are newer
+You can also upgrade all packages for which there are newer
versions:
@@ -199,19 +199,19 @@ set.
implementing the ability to allow different users to have different
configurations, and to do atomic upgrades and rollbacks. To
understand how they work, it’s useful to know a bit about how Nix
-works. In Nix, components are stored in unique locations in the
+works. In Nix, packages are stored in unique locations in the
Nix store (typically,
/nix/store). For instance, a particular version
-of the Subversion component might be stored in a directory
+of the Subversion package might be stored in a directory
/nix/store/dpmvp969yhdqs7lm2r1a3gng7pyq6vy4-subversion-1.1.3/,
while another version might be stored in
/nix/store/5mq2jcn36ldlmh93yj1n8s9c95pj7c5s-subversion-1.1.2.
The long strings prefixed to the directory names are cryptographic
hashes160-bit truncations of SHA-256 hashes encoded in
a base-32 notation, to be precise. of
-all inputs involved in building the component —
+all inputs involved in building the package —
sources, dependencies, compiler flags, and so on. So if two
-components differ in any way, they end up in different locations in
+packages differ in any way, they end up in different locations in
the file system, so they don’t interfere with each other. shows a part of a typical Nix
store.
@@ -231,12 +231,12 @@ $ /nix/store/dpmvp969yhdq...-subversion-1.1.3/bin/svn
every time you want to run Subversion. Of course we could set up the
PATH environment variable to include the
-bin directory of every component we want to use,
+bin directory of every package we want to use,
but this is not very convenient since changing PATH
doesn’t take effect for already existing processes. The solution Nix
uses is to create directory trees of symlinks to
-activated components. These are called
-user environments and they are components
+activated packages. These are called
+user environments and they are packages
themselves (though automatically generated by
nix-env), so they too reside in the Nix store. For
instance, in the user
@@ -285,8 +285,8 @@ operation, a new user environment and generation link are created
based on the current one, and finally the default
symlink is made to point at the new generation. This last step is
atomic on Unix, which explains how we can do atomic upgrades. (Note
-that the building/installing of new components doesn’t interfere in
-any way with old components, since they are stored in different
+that the building/installing of new packages doesn’t interfere in
+any way with old packages, since they are stored in different
locations in the Nix store.)
If you find that you want to undo a nix-env
@@ -352,18 +352,18 @@ This will not change the
nix-env operations such as upgrades
() and uninstall () never
-actually delete components from the system. All they do (as shown
+actually delete packages from the system. All they do (as shown
above) is to create a new user environment that no longer contains
-symlinks to the “deleted” components.
+symlinks to the “deleted” packages.
-Of course, since disk space is not infinite, unused components
+Of course, since disk space is not infinite, unused packages
should be removed at some point. You can do this by running the Nix
-garbage collector. It will remove from the Nix store any component
+garbage collector. It will remove from the Nix store any package
not used (directly or indirectly) by any generation of any
profile.Note however that as long as old generations reference a
-component, it will not be deleted. After all, we wouldn’t be able to
+package, it will not be deleted. After all, we wouldn’t be able to
do a rollback otherwise. So in order for garbage collection to be
effective, you should also delete (some) old generations. Of course,
this should only be done if you are certain that you will not need to
@@ -486,7 +486,7 @@ makes the union of each channel’s Nix expressions the default for
$ nix-env -u '*'
-to upgrade all components in your profile to the latest versions
+to upgrade all packages in your profile to the latest versions
available in the subscribed channels.
diff --git a/doc/manual/quick-start.xml b/doc/manual/quick-start.xml
index c4065ace1..b51f2b167 100644
--- a/doc/manual/quick-start.xml
+++ b/doc/manual/quick-start.xml
@@ -11,7 +11,7 @@ to the following chapters.Download a source tarball or RPM from . Build source
+xlink:href='http://nix.cs.uu.nl/'/>. Build source
distributions using the regular sequence:
@@ -22,8 +22,9 @@ $ make install (as root)
This will install Nix in /nix. You shouldn't
change the prefix if at all possible since that will make it
-impossible to use our pre-built components. Alternatively, you could
-grab an RPM if you're on an RPM-based system. You should also add
+impossible to use pre-built binaries from the Nixpkgs channel and
+other channels. Alternatively, you could grab an RPM if you're on an
+RPM-based system. You should also add
/nix/etc/profile.d/nix.sh to your
~/.bashrc (or some other login
file).
@@ -40,14 +41,14 @@ $ nix-channel --add \
$ nix-channel --update
-Note that this in itself doesn't download any components, it just
+Note that this in itself doesn't download any packages, it just
downloads the Nix expressions that build them and stores them
somewhere (under ~/.nix-defexpr, in case you're
curious). Also, it registers the fact that pre-built binaries are
available remotely.
-See what installable components are currently
-available in the channel:
+See what installable packages are currently available
+in the channel:
$ nix-env -qa ’*’ (mind the quotes!)
@@ -59,13 +60,13 @@ libxslt-1.1.0
-Install some components from the channel:
+Install some packages from the channel:
$ nix-env -i hello firefox ...
-This should download the pre-built components; it should not build
-them locally (if it does, something went wrong).
+This should download pre-built packages; it should not build them
+locally (if it does, something went wrong).Test that they work:
@@ -92,8 +93,8 @@ $ nix-env -e hello
$ nix-channel --update
$ nix-env -u '*'
-The latter command will upgrade each installed component for which
-there is a “newer” version (as determined by comparing the version
+The latter command will upgrade each installed package for which there
+is a “newer” version (as determined by comparing the version
numbers).You can also install specific packages directly from
@@ -107,7 +108,7 @@ appear asking you whether it’s okay to install the package. Say
installed.If you're unhappy with the result of a
-nix-env action (e.g., an upgraded component turned
+nix-env action (e.g., an upgraded package turned
out not to work properly), you can go back:
@@ -124,7 +125,7 @@ $ nix-collect-garbage -d
diff --git a/doc/manual/release-notes.xml b/doc/manual/release-notes.xml
index 727a3e4a6..656a28fca 100644
--- a/doc/manual/release-notes.xml
+++ b/doc/manual/release-notes.xml
@@ -8,36 +8,222 @@
-Release 0.11 (TBA)
+Release 0.11 (December 31,
+2007)
+
+Nix 0.11 has many improvements over the previous stable release.
+The most important improvement is secure multi-user support. It also
+features many usability enhancements and language extensions, many of
+them prompted by NixOS, the purely functional Linux distribution based
+on Nix. Here is an (incomplete) list:
+
- TODO: multi-user support. The old setuid method for
- sharing a store between multiple users has been
- removed.
+ Secure multi-user support. A single Nix store can
+ now be shared between multiple (possible untrusted) users. This is
+ an important feature for NixOS, where it allows non-root users to
+ install software. The old setuid method for sharing a store between
+ multiple users has been removed. Details for setting up a
+ multi-user store can be found in the manual.The new command nix-copy-closure
gives you an easy and efficient way to exchange software between
machines. It copies the missing parts of the closure of a set of
- store path to or from a remote machine.
+ store path to or from a remote machine via
+ ssh.
- nix-prefetch-url now by default
- computes the SHA-256 hash of the file instead of the MD5 hash. In
- calls to fetchurl you should pass an
- sha256 attribute instead of
- md5. You can pass either a hexadecimal or a
- base-32 encoding of the hash.
+ A new kind of string literal: strings between double
+ single-quotes ('') have indentation
+ “intelligently” removed. This allows large strings (such as shell
+ scripts or configuration file fragments in NixOS) to cleanly follow
+ the indentation of the surrounding expression. It also requires
+ much less escaping, since '' is less common in
+ most languages than ".
+
+
+ nix-env
+ modifies the current generation of a profile so that it contains
+ exactly the specified derivation, and nothing else. For example,
+ nix-env -p /nix/var/nix/profiles/browser --set
+ firefox lets the profile named
+ browser contain just Firefox.
+
+
+ nix-env now maintains
+ meta-information about installed packages in profiles. The
+ meta-information is the contents of the meta
+ attribute of derivations, such as description or
+ homepage. The command nix-env -q --xml
+ --meta shows all meta-information.
+ nix-env now uses the
+ meta.priority attribute of derivations to resolve
+ filename collisions between packages. Lower priority values denote
+ a higher priority. For instance, the GCC wrapper package and the
+ Binutils package in Nixpkgs both have a file
+ bin/ld, so previously if you tried to install
+ both you would get a collision. Now, on the other hand, the GCC
+ wrapper declares a higher priority than Binutils, so the former’s
+ bin/ld is symlinked in the user
+ environment.
+
+
+ nix-env -i / -u: instead of
+ breaking package ties by version, break them by priority and version
+ number. That is, if there are multiple packages with the same name,
+ then pick the package with the highest priority, and only use the
+ version if there are multiple packages with the same
+ priority.
+
+ This makes it possible to mark specific versions/variant in
+ Nixpkgs more or less desirable than others. A typical example would
+ be a beta version of some package (e.g.,
+ gcc-4.2.0rc1) which should not be installed even
+ though it is the highest version, except when it is explicitly
+ selected (e.g., nix-env -i
+ gcc-4.2.0rc1).
+
+
+ nix-env --set-flag allows meta
+ attributes of installed packages to be modified. There are several
+ attributes that can be usefully modified, because they affect the
+ behaviour of nix-env or the user environment
+ build script:
+
+
+
+ meta.priority can be changed
+ to resolve filename clashes (see above).
+
+ meta.keep can be set to
+ true to prevent the package from being
+ upgraded or replaced. Useful if you want to hang on to an older
+ version of a package.
+
+ meta.active can be set to
+ false to “disable” the package. That is, no
+ symlinks will be generated to the files of the package, but it
+ remains part of the profile (so it won’t be garbage-collected).
+ Set it back to true to re-enable the
+ package.
+
+
+
+
+
+
+ nix-env -q now has a flag
+ () that causes
+ nix-env to show only those derivations whose
+ output is already in the Nix store or that can be substituted (i.e.,
+ downloaded from somewhere). In other words, it shows the packages
+ that can be installed “quickly”, i.e., don’t need to be built from
+ source. The flag is also available in
+ nix-env -i and nix-env -u to
+ filter out derivations for which no pre-built binary is
+ available.
+
+
+ The new option (in
+ nix-env, nix-instantiate and
+ nix-build) is like , except
+ that the value is a string. For example, --argstr system
+ i686-linux is equivalent to --arg system
+ \"i686-linux\" (note that
+ prevents annoying quoting around shell arguments).
+
+
nix-store has a new operation
()
paths that shows the build log of the given
paths.
+
+
+
+ Nix now uses Berkeley DB 4.5. The database is
+ upgraded automatically, but you should be careful not to use old
+ versions of Nix that still use Berkeley DB 4.4.
+
+
+
+
+
+ The option
+ (corresponding to the configuration setting
+ build-max-silent-time) allows you to set a
+ timeout on builds — if a build produces no output on
+ stdout or stderr for the given
+ number of seconds, it is terminated. This is useful for recovering
+ automatically from builds that are stuck in an infinite
+ loop.
+
+
+ nix-channel: each subscribed
+ channel is its own attribute in the top-level expression generated
+ for the channel. This allows disambiguation (e.g. nix-env
+ -i -A nixpkgs_unstable.firefox).
+
+
+ The substitutes table has been removed from the
+ database. This makes operations such as nix-pull
+ and nix-channel --update much, much
+ faster.
+
+
+ nix-pull now supports
+ bzip2-compressed manifests. This speeds up
+ channels.
+
+
+ nix-prefetch-url now has a
+ limited form of caching. This is used by
+ nix-channel to prevent unnecessary downloads when
+ the channel hasn’t changed.
+
+
+ nix-prefetch-url now by default
+ computes the SHA-256 hash of the file instead of the MD5 hash. In
+ calls to fetchurl you should pass the
+ sha256 attribute instead of
+ md5. You can pass either a hexadecimal or a
+ base-32 encoding of the hash.
+
+
+ Nix can now perform builds in an automatically
+ generated “chroot”. This prevents a builder from accessing stuff
+ outside of the Nix store, and thus helps ensure purity. This is an
+ experimental feature.
+
+
+ The new command nix-store
+ --optimise reduces Nix store disk space usage by finding
+ identical files in the store and hard-linking them to each other.
+ It typically reduces the size of the store by something like
+ 25-35%.
+
+
+ ~/.nix-defexpr can now be a
+ directory, in which case the Nix expressions in that directory are
+ combined into an attribute set, with the file names used as the
+ names of the attributes. The command nix-env
+ --import (which set the
+ ~/.nix-defexpr symlink) is
+ removed.
+
+
Derivations can specify the new special attribute
allowedReferences to enforce that the references
in the output of a derivation are a subset of a declared set of
@@ -47,17 +233,6 @@
for booting Linux don’t have any dependencies.
- TODO: semantic cleanups of string concatenation
- etc. (mostly in r6740).
-
-
- TODO: now using Berkeley DB 4.5.
-
-
- TODO: option in
- nix-store --register-validity.
-
-
The new attribute
exportReferencesGraph allows builders access to
the references graph of their inputs. This is used in NixOS for
@@ -65,72 +240,27 @@
populated with the closure of certain paths.
- TODO: option ,
- configuration setting
- build-max-silent-time.
+ Fixed-output derivations (like
+ fetchurl) can define the attribute
+ impureEnvVars to allow external environment
+ variables to be passed to builders. This is used in Nixpkgs to
+ support proxy configuration, among other things.
- TODO: nix-env
- .
-
-
- TODO: .
-
-
- TODO: nix-env now maintains meta
- info about installed packages in user environments. to show all meta info.
-
-
- TODO: nix-env
- . Specific flags:
- active, priority,
- keep.
-
-
- TODO: nix-env
- / take package priorities into
- account.
-
-
- nix-env -q now has a flag
- () that causes
- nix-env to show only those derivations whose
- output is already in the Nix store or that can be substituted (i.e.,
- downloaded from somewhere). In other words, it shows the packages
- that can be installed “quickly”, i.e., don’t need to be built from
- source. TODO: flag is also available in nix-env -i /
- -u.
-
-
- TODO: new built-ins
+ Several new built-in functions:
builtins.attrNames,
builtins.filterSource,
- builtins.sub,
+ builtins.isAttrs,
+ builtins.isFunction,
+ builtins.listToAttrs,
builtins.stringLength,
- builtins.substring.
+ builtins.sub,
+ builtins.substring,
+ throw,
+ builtins.trace,
+ builtins.readFile.
- TODO: each subscribed channel is its own attribute
- in the top-level expression generated for the channel, this allows
- disambiguation (nix-env -qaA).
-
-
- The substitutes table has been removed from the
- database. This makes operations such as nix-pull
- and nix-channel --update
- much faster.
-
-
- nix-prefetch-url now has a
- limited form of caching. This is used by
- nix-channel to prevent unnecessary downloads when
- the channel hasn’t changed.
-
-
- TODO: chroot support.
-
-
diff --git a/doc/manual/troubleshooting.xml b/doc/manual/troubleshooting.xml
index e1e6c08c8..ddff0f297 100644
--- a/doc/manual/troubleshooting.xml
+++ b/doc/manual/troubleshooting.xml
@@ -4,7 +4,9 @@
Troubleshooting
-This section provides solutions for some common problems.
+This section provides solutions for some common problems. See
+the Nix
+bug tracker for a list of currently known issues.Berkeley DB: Cannot allocate memory
@@ -77,6 +79,46 @@ $ nix-store --verify
+Berkeley DB out of locks
+
+It is possible, especially in nix-store
+--verify or when running the garbage collector, to run out
+of Berkeley DB locks, like this:
+
+
+$ nix-store --verify
+checking path existence
+checking path realisability
+checking the derivers table
+checking the references table
+Berkeley DB error: Lock table is out of available object entries
+error: Db::get: Cannot allocate memory
+
+
+
+A workaround is to increase the number of locks that Berkeley DB
+allocates. (The real solution would be for Nix to not use so many
+locks.) This can be done by putting the following in the file
+/nix/var/nix/db/DB_CONFIG:
+
+
+set_lk_max_locks 100000
+set_lk_max_lockers 100000
+set_lk_max_objects 100000
+
+
+(Increase these numbers if necessary.) Then make sure that there are
+no running Nix processes and delete the Berkeley DB environment:
+
+
+$ rm /nix/var/nix/db/__db.*
+
+The Berkeley DB environment is automatically recreated with the new
+limits when you run any Nix command.
+
+
+
Collisions in nix-env
diff --git a/doc/manual/writing-nix-expressions.xml b/doc/manual/writing-nix-expressions.xml
index 5fa9e423d..840eb120d 100644
--- a/doc/manual/writing-nix-expressions.xml
+++ b/doc/manual/writing-nix-expressions.xml
@@ -7,7 +7,7 @@
This chapter shows you how to write Nix expressions, which are
-the things that tell Nix how to build components. It starts with a
+the things that tell Nix how to build packages. It starts with a
simple example (a Nix expression for GNU Hello), and then moves
on to a more in-depth look at the Nix expression language.
@@ -19,29 +19,28 @@ xlink:href='http://www.gnu.org/software/hello/hello.html'>GNU Hello
package to the Nix Packages collection. Hello is a program
that prints out the text Hello, world!.
-To add a component to the Nix Packages collection, you generally
+To add a package to the Nix Packages collection, you generally
need to do three things:
- Write a Nix expression for the component. This is a
- file that describes all the inputs involved in building the
- component, such as dependencies (other components required by the
- component), sources, and so on.
+ Write a Nix expression for the package. This is a
+ file that describes all the inputs involved in building the package,
+ such as dependencies, sources, and so on.Write a builder. This is a
shell scriptIn fact, it can be written in any
language, but typically it's a bash shell
- script. that actually builds the component from
+ script. that actually builds the package from
the inputs.
- Add the component to the file
+ Add the package to the file
pkgs/top-level/all-packages.nix. The Nix
expression written in the first step is a
- function; it requires other components in order
+ function; it requires other packages in order
to build it. In this step you put it all together, i.e., you call
the function with the right arguments to build the actual
- component.
+ package.
@@ -83,8 +82,8 @@ the single Nix expression in that directory
arguments: stdenv, fetchurl,
and perl. They are needed to build Hello, but
we don't know how to build them here; that's why they are function
- arguments. stdenv is a component that is used
- by almost all Nix Packages components; it provides a
+ arguments. stdenv is a package that is used
+ by almost all Nix Packages packages; it provides a
standard environment consisting of the things you
would expect in a basic Unix environment: a C/C++ compiler (GCC,
to be precise), the Bash shell, fundamental Unix tools such as
@@ -99,19 +98,19 @@ the single Nix expression in that directory
e is the body of the function. So
here, the entire remainder of the file is the body of the
function; when given the required arguments, the body should
- describe how to build an instance of the Hello component.
+ describe how to build an instance of the Hello package.
- So we have to build a component. Building something from
+ So we have to build a package. Building something from
other stuff is called a derivation in Nix (as
opposed to sources, which are built by humans instead of
computers). We perform a derivation by calling
stdenv.mkDerivation.
mkDerivation is a function provided by
- stdenv that builds a component from a set of
+ stdenv that builds a package from a set of
attributes. An attribute set is just a list
of key/value pairs where each value is an arbitrary Nix
expression. They take the general form
@@ -125,10 +124,10 @@ the single Nix expression in that directory
The attribute name specifies the symbolic
- name and version of the component. Nix doesn't really care about
+ name and version of the package. Nix doesn't really care about
these things, but they are used by for instance nix-env
-q to show a human-readable name for
- components. This attribute is required by
+ packages. This attribute is required by
mkDerivation.
@@ -149,7 +148,7 @@ the single Nix expression in that directory
- The builder has to know what the sources of the component
+ The builder has to know what the sources of the package
are. Here, the attribute src is bound to the
result of a call to the fetchurl function.
Given a URL and an MD5 hash of the expected contents of the file
@@ -246,7 +245,7 @@ steps:Since Hello needs Perl, we have to make sure that Perl is in
the PATH. The perl environment
- variable points to the location of the Perl component (since it
+ variable points to the location of the Perl package (since it
was passed in as an attribute to the derivation), so
$perl/bin is the
directory containing the Perl interpreter.
@@ -276,7 +275,7 @@ steps:GNU Hello is a typical Autoconf-based package, so we first
have to run its configure script. In Nix
- every component is stored in a separate location in the Nix store,
+ every package is stored in a separate location in the Nix store,
for instance
/nix/store/9a54ba97fb71b65fda531012d0443ce2-hello-2.1.1.
Nix computes this path by cryptographically hashing all attributes
@@ -338,7 +337,7 @@ rec {
function; it is missing some arguments that have to be filled in
somewhere. In the Nix Packages collection this is done in the file
pkgs/top-level/all-packages.nix, where all
-Nix expressions for components are imported and called with the
+Nix expressions for packages are imported and called with the
appropriate arguments. shows
some fragments of
all-packages.nix.
@@ -352,7 +351,7 @@ some fragments of
mutually recursive set of attributes. That
is, the attributes can refer to each other. This is precisely
what we want since we want to plug the
- various components into each other.
+ various packages into each other.
@@ -522,8 +521,8 @@ genericBuild The buildInputs variable tells
- setup to use the indicated components as
- inputs. This means that if a component provides a
+ setup to use the indicated packages as
+ inputs. This means that if a package provides a
bin subdirectory, it's added to
PATH; if it has a include
subdirectory, it's added to GCC's header search path; and so
@@ -594,9 +593,9 @@ Laziness means that arguments to functions are evaluated only when
they are needed. Functional means that functions are
normal values that can be passed around and manipulated
in interesting ways. The language is not a full-featured, general
-purpose language. It's main job is to describe components,
-compositions of components, and the variability within
-components.
+purpose language. It's main job is to describe packages,
+compositions of packages, and the variability within
+packages.
This section presents the various features of the
language.
@@ -613,7 +612,10 @@ language.
- Strings are enclosed between double
+ Strings can be written in three
+ ways.
+
+ The most common way is to enclose the string between double
quotes, e.g., "foo bar". Strings can span
multiple lines. The special characters " and
\ and the character sequence
@@ -659,8 +661,73 @@ configureFlags = "
some of which in turn contain expressions (e.g.,
${mesa}).
- As a convenience, URIs as defined in
- appendix B of The second way to write string literals is as an
+ indented string, which is enclosed between
+ pairs of double single-quotes, like so:
+
+
+''
+ This is the first line.
+ This is the second line.
+ This is the third line.
+''
+
+ This kind of string literal intelligently strips indentation from
+ the start of each line. To be precise, it strips from each line a
+ number of spaces equal to the minimal indentation of the string as
+ a whole (disregarding the indentation of empty lines). For
+ instance, the first and second line are indented two space, while
+ the third line is indented three spaces. Thus, two spaces are
+ stripped from each line, so the resulting string is
+
+
+"This is the first line.\nThis is the second line.\n This is the third line.\n"
+
+
+
+ Note that the whitespace and newline following the opening
+ '' is ignored if there is no non-whitespace
+ text on the initial line.
+
+ Antiquotation
+ (${expr}}) is
+ supported in indented strings.
+
+ Since ${ and '' have
+ special meaning in indented strings, you need a way to quote them.
+ ${ can be escaped by prefixing it with
+ '', i.e., ''${.
+ '' can be escaped by prefixing it with
+ ', i.e., '''. Finally,
+ linefeed, carriage-return and tab characters can be writted as
+ ''\n, ''\r,
+ ''\t.
+
+ Indented strings are primarily useful in that they allow
+ multi-line string literals to follow the indentation of the
+ enclosing Nix expression, and that less escaping is typically
+ necessary for strings representing languages such as shell scripts
+ and configuration files because '' is much less
+ common than ". Example:
+
+
+stdenv.mkDerivation {
+ ...
+ postInstall =
+ ''
+ mkdir $out/bin $out/etc
+ cp foo $out/bin
+ echo "Hello World" > $out/etc/foo.conf
+ ${if enableBar then "cp bar $out/bin" else ""}
+ '';
+ ...
+}
+
+
+
+
+ Finally, as a convenience, URIs as
+ defined in appendix B of RFC 2396
can be written as is, without quotes. For
instance, the string
@@ -1191,7 +1258,7 @@ set, the attributes of which specify the inputs of the build.There must be an attribute named
name whose value must be a string. This is used
- as a symbolic name for the component by nix-env,
+ as a symbolic name for the package by nix-env,
and it is appended to the hash in the output path of the
derivation.
@@ -1579,7 +1646,7 @@ impureEnvVars = ["http_proxy" "https_proxy" ...];
The standard build environment in the Nix Packages collection
provides a basic environment for building Unix packages. It consists
-of the following components:
+of the following packages:
@@ -1645,13 +1712,13 @@ following:
- All input components specified in the
+ All input packages specified in the
buildInputs environment variable have their
/bin subdirectory added to PATH,
their /include subdirectory added to the C/C++
header file search path, and their /lib
subdirectory added to the linker search path. This can be extended.
- For instance, when the pkgconfig component is
+ For instance, when the pkgconfig package is
used, the subdirectory /lib/pkgconfig of each
input is added to the PKG_CONFIG_PATH environment
variable.
@@ -1668,8 +1735,8 @@ following:
The setup script also exports a function
called genericBuild that knows how to build
-typical Autoconf-style components. It can be customised to perform
-builds for any type of component. It is advisable to use
+typical Autoconf-style packages. It can be customised to perform
+builds for any type of package. It is advisable to use
genericBuild since it provides facilities that
are almost always useful such as unpacking of sources, patching of
sources, nested logging, etc.
diff --git a/install_full.sh b/install_full.sh
index f180111a8..aa1cfba14 100755
--- a/install_full.sh
+++ b/install_full.sh
@@ -1,6 +1,6 @@
#! /bin/sh -e
-make clean
+make clean # comment this out when needed !!!
export nixstatepath=/nixstate2/nix
export ACLOCAL_PATH=/home/wouterdb/.nix-profile/share/aclocal
diff --git a/mergeTrunkBackIn.sh b/mergeTrunkBackIn.sh
index 9b400ea7d..95c8c6e19 100755
--- a/mergeTrunkBackIn.sh
+++ b/mergeTrunkBackIn.sh
@@ -1,4 +1,4 @@
-svn merge -r 9584:9751 https://svn.cs.uu.nl:12443/repos/trace/nix/trunk
+svn merge -r 9751:10133 https://svn.cs.uu.nl:12443/repos/trace/nix/trunk
#already done:
# 8628
@@ -28,3 +28,4 @@ svn merge -r 9584:9751 https://svn.cs.uu.nl:12443/repos/trace/nix/trunk
# 9561
# 9584
# 9751
+# 10133 TODO
diff --git a/misc/vim/syntax/nix.vim b/misc/vim/syntax/nix.vim
new file mode 100644
index 000000000..6e47a2171
--- /dev/null
+++ b/misc/vim/syntax/nix.vim
@@ -0,0 +1,35 @@
+" Vim syntax file
+" Language: nix
+" Maintainer: Marc Weber
+" Modify and commit if you feel that way
+" Last Change: 2007 Dec
+
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
+ finish
+endif
+
+syn keyword nixKeyword let throw inherit import true false null with
+syn keyword nixConditional if else then
+syn keyword nixBrace ( ) { } =
+syn keyword nixBuiltin __currentSystem __currentTime __isFunction __getEnv __trace __toPath __pathExists
+ \ __readFile __toXML __toFile __filterSource __attrNames __getAttr __hasAttr __isAttrs __listToAttrs __isList
+ \ __head __tail __add __sub __lessThan __substring __stringLength
+
+syn match nixAttr "\w\+\ze\s*="
+syn match nixFuncArg "\zs\w\+\ze\s*:"
+syn region nixStringParam start=+\${+ end=+}+
+syn region nixMultiLineComment start=+/\*+ skip=+\\"+ end=+\*/+
+syn match nixEndOfLineComment "#.*$"
+syn region nixString start=+"+ skip=+\\"+ end=+"+ contains=nixStringParam
+
+hi def link nixKeyword Keyword
+hi def link nixConditional Conditional
+hi def link nixBrace Special
+hi def link nixString String
+hi def link nixBuiltin Special
+hi def link nixStringParam Macro
+hi def link nixMultiLineComment Comment
+hi def link nixEndOfLineComment Comment
+hi def link nixAttr Identifier
+hi def link nixFuncArg Identifier
diff --git a/scripts/nix-push.in b/scripts/nix-push.in
index 6250f8b0a..137e3112b 100644
--- a/scripts/nix-push.in
+++ b/scripts/nix-push.in
@@ -116,9 +116,9 @@ print NIX "]";
close NIX;
-# Instantiate store expressions from the Nix expression.
+# Instantiate store derivations from the Nix expression.
my @storeExprs;
-print STDERR "instantiating store expressions...\n";
+print STDERR "instantiating store derivations...\n";
my $pid = open(READ, "$binDir/nix-instantiate $nixExpr|")
or die "cannot run nix-instantiate";
while () {
diff --git a/src/bsdiff-4.3/bspatch.c b/src/bsdiff-4.3/bspatch.c
index 741d4de0e..f9d33ddd6 100644
--- a/src/bsdiff-4.3/bspatch.c
+++ b/src/bsdiff-4.3/bspatch.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59:
#include
#include
#include
+#include
static off_t offtin(u_char *buf)
{
diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l
index 9f0f0b335..cf90f2939 100644
--- a/src/libexpr/lexer.l
+++ b/src/libexpr/lexer.l
@@ -4,6 +4,7 @@
%x STRING
+%x IND_STRING
%{
@@ -122,6 +123,26 @@ inherit { return INHERIT; }
\" { BEGIN(INITIAL); return '"'; }
. return yytext[0]; /* just in case: shouldn't be reached */
+\'\'(\ *\n)? { BEGIN(IND_STRING); return IND_STRING_OPEN; }
+([^\$\']|\$[^\{\']|\'[^\'])+ {
+ yylval->t = makeIndStr(toATerm(yytext));
+ return IND_STR;
+ }
+\'\'\$ {
+ yylval->t = makeIndStr(toATerm("$"));
+ return IND_STR;
+ }
+\'\'\' {
+ yylval->t = makeIndStr(toATerm("''"));
+ return IND_STR;
+ }
+\'\'\\. {
+ yylval->t = unescapeStr(yytext + 2);
+ return IND_STR;
+ }
+\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; }
+\'\' { BEGIN(INITIAL); return IND_STRING_CLOSE; }
+. return yytext[0]; /* just in case: shouldn't be reached */
{PATH} { yylval->t = toATerm(yytext); return PATH; /* !!! alloc */ }
{URI} { yylval->t = toATerm(yytext); return URI; /* !!! alloc */ }
@@ -148,4 +169,10 @@ void backToString(yyscan_t scanner)
BEGIN(STRING);
}
+void backToIndString(yyscan_t scanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t *) scanner;
+ BEGIN(IND_STRING);
+}
+
}
diff --git a/src/libexpr/nixexpr-ast.def b/src/libexpr/nixexpr-ast.def
index c7029e927..a06d34311 100644
--- a/src/libexpr/nixexpr-ast.def
+++ b/src/libexpr/nixexpr-ast.def
@@ -46,6 +46,9 @@ Int | int | Expr |
Str | string ATermList | Expr |
Str | string | Expr | ObsoleteStr
+# Internal to the parser, doesn't occur in ASTs.
+IndStr | string | Expr |
+
# A path is a reference to a file system object that is to be copied
# to the Nix store when used as a derivation attribute. When it is
# concatenated to a string (i.e., `str + path'), it is also copied and
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index 82b24cd07..cd3ba88aa 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -68,9 +68,100 @@ static Expr fixAttrs(int recursive, ATermList as)
}
-void backToString(yyscan_t scanner);
+static Expr stripIndentation(ATermList es)
+{
+ if (es == ATempty) return makeStr("");
+
+ /* Figure out the minimum indentation. Note that by design
+ whitespace-only final lines are not taken into account. (So
+ the " " in "\n ''" is ignored, but the " " in "\n foo''" is.) */
+ bool atStartOfLine = true; /* = seen only whitespace in the current line */
+ unsigned int minIndent = 1000000;
+ unsigned int curIndent = 0;
+ ATerm e;
+ for (ATermIterator i(es); i; ++i) {
+ if (!matchIndStr(*i, e)) {
+ /* Anti-quotations end the current start-of-line whitespace. */
+ if (atStartOfLine) {
+ atStartOfLine = false;
+ if (curIndent < minIndent) minIndent = curIndent;
+ }
+ continue;
+ }
+ string s = aterm2String(e);
+ for (unsigned int j = 0; j < s.size(); ++j) {
+ if (atStartOfLine) {
+ if (s[j] == ' ')
+ curIndent++;
+ else if (s[j] == '\n') {
+ /* Empty line, doesn't influence minimum
+ indentation. */
+ curIndent = 0;
+ } else {
+ atStartOfLine = false;
+ if (curIndent < minIndent) minIndent = curIndent;
+ }
+ } else if (s[j] == '\n') {
+ atStartOfLine = true;
+ curIndent = 0;
+ }
+ }
+ }
+
+ /* Strip spaces from each line. */
+ ATermList es2 = ATempty;
+ atStartOfLine = true;
+ unsigned int curDropped = 0;
+ unsigned int n = ATgetLength(es);
+ for (ATermIterator i(es); i; ++i, --n) {
+ if (!matchIndStr(*i, e)) {
+ atStartOfLine = false;
+ curDropped = 0;
+ es2 = ATinsert(es2, *i);
+ continue;
+ }
+
+ string s = aterm2String(e);
+ string s2;
+ for (unsigned int j = 0; j < s.size(); ++j) {
+ if (atStartOfLine) {
+ if (s[j] == ' ') {
+ if (curDropped++ >= minIndent)
+ s2 += s[j];
+ }
+ else if (s[j] == '\n') {
+ curDropped = 0;
+ s2 += s[j];
+ } else {
+ atStartOfLine = false;
+ curDropped = 0;
+ s2 += s[j];
+ }
+ } else {
+ s2 += s[j];
+ if (s[j] == '\n') atStartOfLine = true;
+ }
+ }
+
+ /* Remove the last line if it is empty and consists only of
+ spaces. */
+ if (n == 1) {
+ unsigned int p = s2.find_last_of('\n');
+ if (p != string::npos && s2.find_first_not_of(' ', p + 1) == string::npos)
+ s2 = string(s2, 0, p + 1);
+ }
+
+ es2 = ATinsert(es2, makeStr(s2));
+ }
+
+ return makeConcatStrings(ATreverse(es2));
+}
+
+
+void backToString(yyscan_t scanner);
+void backToIndString(yyscan_t scanner);
+
-
static Pos makeCurPos(YYLTYPE * loc, ParseData * data)
{
return makePos(toATerm(data->path),
@@ -121,10 +212,11 @@ static void freeAndUnprotect(void * p)
%type start expr expr_function expr_if expr_op
%type expr_app expr_select expr_simple bind inheritsrc formal
-%type binds ids expr_list formals string_parts
-%token ID INT STR PATH URI
+%type binds ids expr_list formals string_parts ind_string_parts
+%token ID INT STR IND_STR PATH URI
%token IF THEN ELSE ASSERT WITH LET IN REC INHERIT EQ NEQ AND OR IMPL
%token DOLLAR_CURLY /* == ${ */
+%token IND_STRING_OPEN IND_STRING_CLOSE
%nonassoc IMPL
%left OR
@@ -199,6 +291,9 @@ expr_simple
else if (ATgetNext($2) == ATempty) $$ = ATgetFirst($2);
else $$ = makeConcatStrings(ATreverse($2));
}
+ | IND_STRING_OPEN ind_string_parts IND_STRING_CLOSE {
+ $$ = stripIndentation(ATreverse($2));
+ }
| PATH { $$ = makePath(toATerm(absPath(aterm2String($1), data->basePath))); }
| URI { $$ = makeStr($1, ATempty); }
| '(' expr ')' { $$ = $2; }
@@ -219,6 +314,12 @@ string_parts
| { $$ = ATempty; }
;
+ind_string_parts
+ : ind_string_parts IND_STR { $$ = ATinsert($1, $2); }
+ | ind_string_parts DOLLAR_CURLY expr '}' { backToIndString(scanner); $$ = ATinsert($1, $3); }
+ | { $$ = ATempty; }
+ ;
+
binds
: binds bind { $$ = ATinsert($1, $2); }
| { $$ = ATempty; }
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index c082d3979..e0c4c070d 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -769,6 +769,17 @@ static Expr prim_dirOf(EvalState & state, const ATermVector & args)
}
+/* Return the contents of a file as a string. */
+static Expr prim_readFile(EvalState & state, const ATermVector & args)
+{
+ PathSet context;
+ Path path = coerceToPath(state, args[0], context);
+ if (!context.empty())
+ throw EvalError(format("string `%1%' cannot refer to other paths") % path);
+ return makeStr(readFile(path));
+}
+
+
/*************************************************************
* Creating files
*************************************************************/
@@ -1054,8 +1065,8 @@ static Expr prim_toString(EvalState & state, const ATermVector & args)
}
-/* `substr start len str' returns the substring of `str' starting at
- character position `min(start, stringLength str)' inclusive and
+/* `substring start len str' returns the substring of `str' starting
+ at character position `min(start, stringLength str)' inclusive and
ending at `min(start + len, stringLength str)'. `start' must be
non-negative. */
static Expr prim_substring(EvalState & state, const ATermVector & args)
@@ -1079,6 +1090,14 @@ static Expr prim_stringLength(EvalState & state, const ATermVector & args)
}
+static Expr prim_unsafeDiscardStringContext(EvalState & state, const ATermVector & args)
+{
+ PathSet context;
+ string s = coerceToString(state, args[0], context);
+ return makeStr(s, PathSet());
+}
+
+
/*************************************************************
* Primop registration
*************************************************************/
@@ -1116,6 +1135,7 @@ void EvalState::addPrimOps()
addPrimOp("__pathExists", 1, prim_pathExists);
addPrimOp("baseNameOf", 1, prim_baseNameOf);
addPrimOp("dirOf", 1, prim_dirOf);
+ addPrimOp("__readFile", 1, prim_readFile);
// Creating files
addPrimOp("__toXML", 1, prim_toXML);
@@ -1145,6 +1165,8 @@ void EvalState::addPrimOps()
addPrimOp("toString", 1, prim_toString);
addPrimOp("__substring", 3, prim_substring);
addPrimOp("__stringLength", 1, prim_stringLength);
+ addPrimOp("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext);
+
}
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 1b505d67b..913fba207 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -1671,6 +1671,44 @@ void DerivationGoal::startBuilder()
makeValidityRegistration(refs, false));
}
+ // The same for derivations
+ s = drv.env["exportBuildReferencesGraph"];
+ ss = tokenizeString(s);
+ if (ss.size() % 2 != 0)
+ throw BuildError(format("odd number of tokens in `exportReferencesGraph': `%1%'") % s);
+ for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
+ string fileName = *i++;
+ checkStoreName(fileName); /* !!! abuse of this function */
+
+ /* Check that the store path is valid. */
+ Path storePath = *i++;
+ if (!isInStore(storePath))
+ throw BuildError(format("`exportReferencesGraph' contains a non-store path `%1%'")
+ % storePath);
+ storePath = toStorePath(storePath);
+ if (!store->isValidPath(storePath))
+ throw BuildError(format("`exportReferencesGraph' contains an invalid path `%1%'")
+ % storePath);
+
+ /* Write closure info to `fileName'. */
+ PathSet refs1,refs;
+ computeFSClosure(storePath, refs1, true, false, 0); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO COPY STATE
+ for (PathSet::iterator j = refs1.begin(); j != refs1.end() ; j++) {
+ refs.insert (*j);
+ if (isDerivation (*j)) {
+ Derivation deriv = derivationFromPath (*j);
+ for (DerivationOutputs::iterator k=deriv.outputs.begin();
+ k != deriv.outputs.end(); k++) {
+ refs.insert(k->second.path);
+ }
+ }
+ }
+ /* !!! in secure Nix, the writing should be done on the
+ build uid for security (maybe). */
+ writeStringToFile(tmpDir + "/" + fileName,
+ makeValidityRegistration(refs, false));
+ }
+
/* If `build-users-group' is not empty, then we have to build as
one of the members of that group. */
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 0be0eda83..5d80b4b6e 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -26,7 +26,7 @@ static string gcLockName = "gc.lock";
static string tempRootsDir = "temproots";
static string gcRootsDir = "gcroots";
-const unsigned int defaultGcLevel = 1000;
+static const int defaultGcLevel = 1000;
/* Acquire the global GC lock. This is used to prevent new Nix
@@ -450,7 +450,7 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
queryBoolSetting("gc-keep-outputs", false);
bool gcKeepDerivations =
queryBoolSetting("gc-keep-derivations", true);
- unsigned int gcKeepOutputsThreshold =
+ int gcKeepOutputsThreshold =
queryIntSetting ("gc-keep-outputs-threshold", defaultGcLevel);
//printMsg(lvlError, format("gcKeepOutputs %1% gcKeepDerivations: %2%") % gcKeepOutputs % gcKeepDerivations);
@@ -536,7 +536,7 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
else if (store->isValidStatePath(j->second.path))
computeFSClosure(j->second.path, livePaths, true, true, 0);
=======
-*/
+
string gcLevelStr = drv.env["__gcLevel"];
int gcLevel;
@@ -550,6 +550,20 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
if (store->isValidPath(j->second.path) || store->isValidStatePath(j->second.path))
computeFSClosure(j->second.path, livePaths, true, true, 0);
}
+=======
+*/
+
+ string gcLevelStr = drv.env["__gcLevel"];
+ int gcLevel;
+ if (!string2Int(gcLevelStr, gcLevel))
+ gcLevel = defaultGcLevel;
+
+ if (gcLevel >= gcKeepOutputsThreshold)
+ for (DerivationOutputs::iterator j = drv.outputs.begin();
+ j != drv.outputs.end(); ++j)
+ if (store->isValidPath(j->second.path) || store->isValidStatePath(j->second.path))
+ computeFSClosure(j->second.path, livePaths, true, true, 0);
+ }
}
if (action == gcReturnLive) {
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 1cc12907e..ab701a11b 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -92,6 +92,25 @@ Path toStoreOrStatePath(const Path & path)
return Path(path, 0, slash);
}
+Path followLinksToStore(const Path & _path)
+{
+ Path path = absPath(_path);
+ while (!isInStore(path)) {
+ if (!isLink(path)) break;
+ string target = readLink(path);
+ path = absPath(target, dirOf(path));
+ }
+ if (!isInStore(path))
+ throw Error(format("path `%1%' is not in the Nix store") % path);
+ return path;
+}
+
+
+Path followLinksToStorePath(const Path & path)
+{
+ return toStorePath(followLinksToStore(path));
+}
+
void checkStoreName(const string & name)
{
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 0998a22ab..75fce9558 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -259,11 +259,21 @@ bool isStatePath(const Path & path);
void checkStoreName(const string & name);
+
/* Chop off the parts after the top-level store name, e.g.,
/nix/store/abcd-foo/bar => /nix/store/abcd-foo. */
Path toStorePath(const Path & path);
Path toStoreOrStatePath(const Path & path);
+/* Follow symlinks until we end up with a path in the Nix store. */
+Path followLinksToStore(const Path & path);
+
+
+/* Same as followLinksToStore(), but apply toStorePath() to the
+ result. */
+Path followLinksToStorePath(const Path & path);
+
+
/* Constructs a unique store path name. */
Path makeStorePath(const string & type,
const Hash & hash, const string & suffix);
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index c56e4229b..50a8cb3d3 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
@@ -106,8 +107,7 @@ Path canonPath(const Path & path, bool resolveSymlinks)
/* If s points to a symlink, resolve it and restart (since
the symlink target might contain new symlinks). */
if (resolveSymlinks && isLink(s)) {
- followCount++;
- if (followCount >= maxFollow)
+ if (++followCount >= maxFollow)
throw Error(format("infinite symlink recursion in path `%1%'") % path);
temp = absPath(readLink(s), dirOf(s))
+ string(i, end);
@@ -1031,8 +1031,15 @@ string statusToString(int status)
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
if (WIFEXITED(status))
return (format("failed with exit code %1%") % WEXITSTATUS(status)).str();
- else if (WIFSIGNALED(status))
- return (format("failed due to signal %1%") % WTERMSIG(status)).str();
+ else if (WIFSIGNALED(status)) {
+ int sig = WTERMSIG(status);
+#if HAVE_STRSIGNAL
+ const char * description = strsignal(sig);
+ return (format("failed due to signal %1% (%2%)") % sig % description).str();
+#else
+ return (format("failed due to signal %1%") % sig).str();
+#endif
+ }
else
return "died abnormally";
} else return "succeeded";
diff --git a/src/nix-env/help.txt b/src/nix-env/help.txt
index e0697be88..605bf2810 100644
--- a/src/nix-env/help.txt
+++ b/src/nix-env/help.txt
@@ -9,6 +9,7 @@ Operations:
--set: create a user environment containing a single derivation
--uninstall / -e: remove derivations from the user environment
--query / -q: perform a query on an environment or Nix expression
+ --set-flag NAME VALUE: set derivation meta-attribute to given value
The previous operations take a list of derivation names. The special
name `*' may be used to indicate all derivations.
@@ -20,8 +21,6 @@ name `*' may be used to indicate all derivations.
--delete-generations GENERATIONS...: deleted listed generations,
`old' for all non-current generations
- --import / -I FILE: set default Nix expression
-
--version: output version information
--help: display help
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index 7f2e606ab..b8e07df6b 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -430,7 +430,7 @@ static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems,
/* Check that all selectors have been used. */
for (DrvNames::iterator i = selectors.begin();
i != selectors.end(); ++i)
- if (i->hits == 0)
+ if (i->hits == 0 && i->fullName != "*")
throw Error(format("selector `%1%' matches no derivations")
% i->fullName);
@@ -438,13 +438,18 @@ static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems,
}
+static bool isPath(const string & s)
+{
+ return s.find('/') != string::npos;
+}
+
+
static void queryInstSources(EvalState & state,
const InstallSourceInfo & instSource, const Strings & args,
DrvInfos & elems, bool newestOnly)
{
InstallSourceType type = instSource.type;
-
- if (type == srcUnknown && args.size() > 0 && args.front()[0] == '/')
+ if (type == srcUnknown && args.size() > 0 && isPath(args.front()))
type = srcStorePaths;
switch (type) {
@@ -496,25 +501,24 @@ static void queryInstSources(EvalState & state,
for (Strings::const_iterator i = args.begin();
i != args.end(); ++i)
{
- assertStorePath(*i);
+ Path path = followLinksToStorePath(*i);
DrvInfo elem;
elem.attrs = boost::shared_ptr(new ATermMap(0)); /* ugh... */
- string name = baseNameOf(*i);
+ string name = baseNameOf(path);
string::size_type dash = name.find('-');
if (dash != string::npos)
name = string(name, dash + 1);
- if (isDerivation(*i)) {
- elem.setDrvPath(*i);
- elem.setOutPath(findOutput(derivationFromPath(*i), "out"));
+ if (isDerivation(path)) {
+ elem.setDrvPath(path);
+ elem.setOutPath(findOutput(derivationFromPath(path), "out"));
if (name.size() >= drvExtension.size() &&
string(name, name.size() - drvExtension.size()) == drvExtension)
name = string(name, 0, name.size() - drvExtension.size());
}
- else
- elem.setOutPath(*i);
+ else elem.setOutPath(path);
elem.name = name;
@@ -964,7 +968,7 @@ static void opSet(Globals & globals,
}
-static void uninstallDerivations(Globals & globals, DrvNames & selectors,
+static void uninstallDerivations(Globals & globals, Strings & selectors,
Path & profile)
{
PathLocks lock;
@@ -977,11 +981,13 @@ static void uninstallDerivations(Globals & globals, DrvNames & selectors,
{
DrvName drvName(i->name);
bool found = false;
- for (DrvNames::iterator j = selectors.begin();
- j != selectors.end(); ++j)
- if (j->matches(drvName)) {
- printMsg(lvlInfo,
- format("uninstalling `%1%'") % i->name);
+ for (Strings::iterator j = selectors.begin(); j != selectors.end(); ++j)
+ /* !!! the repeated calls to followLinksToStorePath() are
+ expensive, should pre-compute them. */
+ if ((isPath(*j) && i->queryOutPath(globals.state) == followLinksToStorePath(*j))
+ || DrvName(*j).matches(drvName))
+ {
+ printMsg(lvlInfo, format("uninstalling `%1%'") % i->name);
found = true;
break;
}
@@ -1000,11 +1006,7 @@ static void opUninstall(Globals & globals,
{
if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
-
- DrvNames drvNames = drvNamesFromArgs(opArgs);
-
- uninstallDerivations(globals, drvNames,
- globals.profile);
+ uninstallDerivations(globals, opArgs, globals.profile);
}
diff --git a/src/nix-store/help.txt b/src/nix-store/help.txt
index a338fe7d1..40934966c 100644
--- a/src/nix-store/help.txt
+++ b/src/nix-store/help.txt
@@ -16,8 +16,13 @@ Operations:
--gc: run the garbage collector
- --dump: dump a path as a Nix archive
- --restore: restore a path from a Nix archive
+ --dump: dump a path as a Nix archive, forgetting dependencies
+ --restore: restore a path from a Nix archive, without
+ registering validity
+
+ --export: export a path as a Nix archive, marking dependencies
+ --import: import a path from a Nix archive, and register as
+ valid
--init: initialise the Nix database
--verify: verify Nix structures
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index d7d046d75..ce46796a6 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -29,7 +29,9 @@ static Path gcRoot;
static int rootNr = 0;
static bool indirectRoot = false;
+/*
//Fixes the path and checks if it is a store path , see also toStorePath
+<<<<<<< .working
static Path fixPath(Path path)
{
path = absPath(path);
@@ -55,6 +57,9 @@ static Path fixStoreOrStatePath(Path path)
return toStoreOrStatePath(path);
}
+=======
+>>>>>>> .merge-right.r10133
+*/
static Path useDeriver(Path path)
{
@@ -99,7 +104,7 @@ static void opRealise(Strings opFlags, Strings opArgs)
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
- *i = fixPath(*i);
+ *i = followLinksToStorePath(*i);
if (opArgs.size() > 1) {
PathSet drvPaths;
@@ -292,7 +297,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
{
- *i = fixPath(*i);
+ *i = followLinksToStorePath(*i);
if (forceRealise) realisePath(*i);
Derivation drv = derivationFromPathTxn(noTxn, *i);
cout << format("%1%\n") % findOutput(drv, "out");
@@ -313,8 +318,10 @@ static void opQuery(Strings opFlags, Strings opArgs)
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
{
- Path path = maybeUseOutput(fixStoreOrStatePath(*i), useOutput, forceRealise);
- if (query == qRequisites) store->storePathRequisites(path, includeOutputs, paths, true, false, revision);
+ Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
+
+ if (query == qRequisites)
+ store->storePathRequisites(path, includeOutputs, paths, true, false, revision);
else if (query == qRequisitesState) store->storePathRequisites(path, includeOutputs, paths, false, true, revision);
else if (query == qRequisitesFull) store->storePathRequisites(path, includeOutputs, paths, true, true, revision);
else if (query == qReferences) store->queryStoreReferences(path, paths, revision);
@@ -335,7 +342,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
{
- Path deriver = store->queryDeriver(fixPath(*i));
+ Path deriver = store->queryDeriver(followLinksToStorePath(*i));
cout << format("%1%\n") %
(deriver == "" ? "unknown-deriver" : deriver);
}
@@ -345,7 +352,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
{
- Path path = useDeriver(fixPath(*i));
+ Path path = useDeriver(followLinksToStorePath(*i));
Derivation drv = derivationFromPathTxn(noTxn, path);
StringPairs::iterator j = drv.env.find(bindingName);
if (j == drv.env.end())
@@ -359,7 +366,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
{
- Path path = maybeUseOutput(fixPath(*i), useOutput, forceRealise);
+ Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
Hash hash = store->queryPathHash(path);
assert(hash.type == htSHA256);
cout << format("sha256:%1%\n") % printHash32(hash);
@@ -370,7 +377,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
PathSet done;
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
- printTree(fixPath(*i), "", "", done);
+ printTree(followLinksToStorePath(*i), "", "", done);
break;
}
@@ -378,7 +385,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
PathSet roots;
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
- roots.insert(maybeUseOutput(fixPath(*i), useOutput, forceRealise));
+ roots.insert(maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise));
printDotGraph(roots);
break;
}
@@ -386,7 +393,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
case qResolve: {
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
- cout << format("%1%\n") % fixPath(*i);
+ cout << format("%1%\n") % followLinksToStorePath(*i);
break;
}
@@ -403,7 +410,7 @@ static void opReadLog(Strings opFlags, Strings opArgs)
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
{
- Path path = useDeriver(fixPath(*i));
+ Path path = useDeriver(followLinksToStorePath(*i));
Path logPath = (format("%1%/%2%/%3%") %
nixLogDir % drvsLogDir % baseNameOf(path)).str();
@@ -460,7 +467,7 @@ static void opCheckValidity(Strings opFlags, Strings opArgs)
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
{
- Path path = fixPath(*i);
+ Path path = followLinksToStorePath(*i);
if (!store->isValidPath(path))
if (printInvalid)
cout << format("%1%\n") % path;
@@ -535,7 +542,7 @@ static void opDelete(Strings opFlags, Strings opArgs)
PathSet pathsToDelete;
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
- pathsToDelete.insert(fixPath(*i));
+ pathsToDelete.insert(followLinksToStorePath(*i));
PathSet dummy;
PrintFreed freed(true, false);
diff --git a/tests/dummy b/tests/dummy
deleted file mode 100644
index 557db03de..000000000
--- a/tests/dummy
+++ /dev/null
@@ -1 +0,0 @@
-Hello World
diff --git a/tests/hash.sh b/tests/hash.sh
index b3f3fa5bf..5022ea246 100644
--- a/tests/hash.sh
+++ b/tests/hash.sh
@@ -1,7 +1,7 @@
source common.sh
try () {
- echo -n "$2" > $TEST_ROOT/vector
+ printf "%s" "$2" > $TEST_ROOT/vector
hash=$($nixhash $EXTRA --flat --type "$1" $TEST_ROOT/vector)
if test "$hash" != "$3"; then
echo "hash $1, expected $3, got $hash"
diff --git a/tests/init.sh b/tests/init.sh
index b3470f4de..b5b9ac9b0 100644
--- a/tests/init.sh
+++ b/tests/init.sh
@@ -79,6 +79,20 @@ 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
+# binaries sets DYLD_LIBRARY_PATH so that Perl finds Nix's (completely
+# different) libutil --- so it barfs. So generate a shell wrapper
+# around download-using-manifests that clears DYLD_LIBRARY_PATH.
+mv $NIX_BIN_DIR/nix/download-using-manifests.pl $NIX_BIN_DIR/nix/download-using-manifests.pl.real
+cat > $NIX_BIN_DIR/nix/download-using-manifests.pl < ./dummy
+outPath="$(NIX_STORE_DIR=/foo $nixinstantiate --readonly-mode hash-check.nix)"
+if test "$outPath" != "/foo/lfy1s6ca46rm5r6w4gg9hc0axiakjcnm-dependencies.drv"; then
+ echo "hashDerivationModulo appears broken, got $outPath"
+ exit 1
fi
diff --git a/tests/user-envs.sh b/tests/user-envs.sh
index 614c30ceb..edb6da0bf 100644
--- a/tests/user-envs.sh
+++ b/tests/user-envs.sh
@@ -2,6 +2,8 @@ source common.sh
clearProfiles
+set -x
+
# Query installed: should be empty.
test "$($nixenv -p $profiles/test -q '*' | wc -l)" -eq 0
@@ -71,6 +73,15 @@ echo $outPath10
$nixenv -p $profiles/test -i "$outPath10"
$nixenv -p $profiles/test -q '*' | grep -q foo-1.0
+# Uninstall foo-1.0, using a symlink to its store path.
+ln -sfn $outPath10/bin/foo $TEST_ROOT/symlink
+$nixenv -p $profiles/test -e $TEST_ROOT/symlink
+if $nixenv -p $profiles/test -q '*' | grep -q foo; then false; fi
+
+# Install foo-1.0, now using a symlink to its store path.
+$nixenv -p $profiles/test -i $TEST_ROOT/symlink
+$nixenv -p $profiles/test -q '*' | grep -q foo
+
# Delete all old generations.
$nixenv -p $profiles/test --delete-generations old