<chapter xmlns="http://docbook.org/ns/docbook"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      xmlns:xi="http://www.w3.org/2001/XInclude"
      version="5.0"
      xml:id="ch-basic-package-mgmt">

<title>Basic Package Management</title>

<para>The main command for package management is <link
linkend="sec-nix-env"><command>nix-env</command></link>.  You can use
it to install, upgrade, and erase packages, and to query what
packages are installed or are available for installation.</para>

<para>In Nix, different users can have different “views”
on the set of installed applications.  That is, there might be lots of
applications present on the system (possibly in many different
versions), but users can have a specific selection of those active —
where “active” just means that it appears in a directory
in the user’s <envar>PATH</envar>.  Such a view on the set of
installed applications is called a <emphasis>user
environment</emphasis>, which is just a directory tree consisting of
symlinks to the files of the active applications.  </para>

<para>Components are installed from a set of <emphasis>Nix
expressions</emphasis> 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
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
the latest version from <link
xlink:href='http://nixos.org/nixpkgs/download.html' />.</para>

<para>Assuming that you have downloaded and unpacked a release of Nix
Packages, you can view the set of available packages in the release:

<screen>
$ nix-env -qaf nixpkgs-<replaceable>version</replaceable> '*'
ant-blackdown-1.4.2
aterm-2.2
bash-3.0
binutils-2.15
bison-1.875d
blackdown-1.4.2
bzip2-1.0.2
...</screen>

where <literal>nixpkgs-<replaceable>version</replaceable></literal> is
where you’ve unpacked the release.  The flag <option>-q</option>
specifies a query operation; <option>-a</option> means that you want
to show the “available” (i.e., installable) packages, as opposed to
the installed packages; and <option>-f</option>
<filename>nixpkgs-<replaceable>version</replaceable></filename>
specifies the source of the packages.  The argument
<literal>'*'</literal> shows all installable packages. (The quotes are
necessary to prevent shell expansion.)  You can also select specific
packages by name:

<screen>
$ nix-env -qaf nixpkgs-<replaceable>version</replaceable> gcc
gcc-3.4.6
gcc-4.0.3
gcc-4.1.1</screen>

</para>

<para>It is also possible to see the <emphasis>status</emphasis> of
available packages, i.e., whether they are installed into the user
environment and/or present in the system:

<screen>
$ nix-env -qasf nixpkgs-<replaceable>version</replaceable> '*'
...
-PS bash-3.0
--S binutils-2.15
IPS bison-1.875d
...</screen>

The first character (<literal>I</literal>) indicates whether the
package is installed in your current user environment.  The second
(<literal>P</literal>) 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 (<literal>S</literal>) indicates
whether there is a so-called <emphasis>substitute</emphasis> for the
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.</para>

<para>So now that we have a set of Nix expressions we can build the
packages contained in them.  This is done using <literal>nix-env
-i</literal>.  For instance,

<screen>
$ nix-env -f nixpkgs-<replaceable>version</replaceable> -i subversion</screen>

will install the package called <literal>subversion</literal> (which
is, of course, the <link
xlink:href='http://subversion.tigris.org/'>Subversion version
management system</link>).</para>

<para>When you do this for the first time, Nix will start building
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 packages are
available somewhere.  This is done using the
<command>nix-pull</command> command, which must be supplied with a URL
containing a <emphasis>manifest</emphasis> describing what binaries
are available.  This URL should correspond to the Nix Packages release
that you’re using.  For instance, if you obtained a release from <link
xlink:href='http://nixos.org/releases/nixpkgs/nixpkgs-0.12pre11712-4lrp7j8x'
/>, then you should do:

<screen>
$ nix-pull http://nixos.org/releases/nixpkgs/nixpkgs-0.12pre11712-4lrp7j8x/MANIFEST</screen>

If you then issue the installation command, it should start
downloading binaries from <systemitem
class='fqdomainname'>nixos.org</systemitem>, instead of building
them from source.  This might still take a while since all
dependencies must be downloaded, but on a reasonably fast connection
such as a DSL line it’s on the order of a few minutes.</para>

<para>Naturally, packages can also be uninstalled:

<screen>
$ nix-env -e subversion</screen>

</para>

<para>Upgrading to a new version is just as easy.  If you have a new
release of Nix Packages, you can do:

<screen>
$ nix-env -f nixpkgs-<replaceable>version</replaceable> -u subversion</screen>

This will <emphasis>only</emphasis> upgrade Subversion if there is a
“newer” version in the new set of Nix expressions, as
defined by some pretty arbitrary rules regarding ordering of version
numbers (which generally do what you’d expect of them).  To just
unconditionally replace Subversion with whatever version is in the Nix
expressions, use <parameter>-i</parameter> instead of
<parameter>-u</parameter>; <parameter>-i</parameter> will remove
whatever version is already installed.</para>

<para>You can also upgrade all packages for which there are newer
versions:

<screen>
$ nix-env -f nixpkgs-<replaceable>version</replaceable> -u '*'</screen>

</para>

<para>Sometimes it’s useful to be able to ask what
<command>nix-env</command> would do, without actually doing it.  For
instance, to find out what packages would be upgraded by
<literal>nix-env -u '*'</literal>, you can do

<screen>
$ nix-env ... -u '*' --dry-run
(dry run; not doing anything)
upgrading `libxslt-1.1.0' to `libxslt-1.1.10'
upgrading `graphviz-1.10' to `graphviz-1.12'
upgrading `coreutils-5.0' to `coreutils-5.2.1'</screen>

</para>

</chapter>