<chapter xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xml:id="chap-meta">

<title>Meta-attributes</title>

<para>Nix packages can declare <emphasis>meta-attributes</emphasis>
that contain information about a package such as a description, its
homepage, its license, and so on.  For instance, the GNU Hello package
has a <varname>meta</varname> declaration like this:

<programlisting>
meta = {
  description = "A program that produces a familiar, friendly greeting";
  longDescription = ''
    GNU Hello is a program that prints "Hello, world!" when you run it.
    It is fully customizable.
  '';
  homepage = http://www.gnu.org/software/hello/manual/;
  license = stdenv.lib.licenses.gpl3Plus;
  maintainers = [ stdenv.lib.maintainers.eelco ];
  platforms = stdenv.lib.platforms.all;
};
</programlisting>

</para>

<para>Meta-attributes are not passed to the builder of the package.
Thus, a change to a meta-attribute doesn’t trigger a recompilation of
the package.  The value of a meta-attribute must be a string.</para>

<para>The meta-attributes of a package can be queried from the
command-line using <command>nix-env</command>:

<screen>
$ nix-env -qa hello --json
{
    "hello": {
        "meta": {
            "description": "A program that produces a familiar, friendly greeting",
            "homepage": "http://www.gnu.org/software/hello/manual/",
            "license": {
                "fullName": "GNU General Public License version 3 or later",
                "shortName": "GPLv3+",
                "url": "http://www.fsf.org/licensing/licenses/gpl.html"
            },
            "longDescription": "GNU Hello is a program that prints \"Hello, world!\" when you run it.\nIt is fully customizable.\n",
            "maintainers": [
                "Ludovic Court\u00e8s &lt;ludo@gnu.org>"
            ],
            "platforms": [
                "i686-linux",
                "x86_64-linux",
                "armv5tel-linux",
                "armv7l-linux",
                "mips64el-linux",
                "x86_64-darwin",
                "i686-cygwin",
                "i686-freebsd",
                "x86_64-freebsd",
                "i686-openbsd",
                "x86_64-openbsd"
            ],
            "position": "/home/user/dev/nixpkgs/pkgs/applications/misc/hello/default.nix:14"
        },
        "name": "hello-2.9",
        "system": "x86_64-linux"
    }
}


</screen>

<command>nix-env</command> knows about the
<varname>description</varname> field specifically:

<screen>
$ nix-env -qa hello --description
hello-2.3  A program that produces a familiar, friendly greeting
</screen>

</para>


<section xml:id="sec-standard-meta-attributes"><title>Standard
meta-attributes</title>

<para>It is expected that each meta-attribute is one of the following:</para>

<variablelist>

  <varlistentry>
    <term><varname>description</varname></term>
    <listitem><para>A short (one-line) description of the package.
    This is shown by <command>nix-env -q --description</command> and
    also on the Nixpkgs release pages.</para>

    <para>Don’t include a period at the end.  Don’t include newline
    characters.  Capitalise the first character.  For brevity, don’t
    repeat the name of package — just describe what it does.</para>

    <para>Wrong: <literal>"libpng is a library that allows you to decode PNG images."</literal></para>

    <para>Right: <literal>"A library for decoding PNG images"</literal></para>

    </listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>longDescription</varname></term>
    <listitem><para>An arbitrarily long description of the
    package.</para></listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>branch</varname></term>
    <listitem><para>Release branch. Used to specify that a package is not
    going to receive updates that are not in this branch; for example, Linux
    kernel 3.0 is supposed to be updated to 3.0.X, not 3.1.</para></listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>homepage</varname></term>
    <listitem><para>The package’s homepage.  Example:
    <literal>http://www.gnu.org/software/hello/manual/</literal></para></listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>downloadPage</varname></term>
    <listitem><para>The page where a link to the current version can be found.  Example:
    <literal>http://ftp.gnu.org/gnu/hello/</literal></para></listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>license</varname></term>
    <listitem>
      <para>
        The license, or licenses, for the package. One from the attribute set
        defined in <link
          xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/licenses.nix">
          <filename>nixpkgs/lib/licenses.nix</filename></link>. At this moment
        using both a list of licenses and a single license is valid. If the
        license field is in the form of a list representation, then it means
        that parts of the package are licensed differently.  Each license
        should preferably be referenced by their attribute. The non-list
        attribute value can also be a space delimited string representation of
        the contained attribute shortNames or spdxIds. The following are all valid
        examples:
        <itemizedlist>
          <listitem><para>Single license referenced by attribute (preferred)
              <literal>stdenv.lib.licenses.gpl3</literal>.
          </para></listitem>
          <listitem><para>Single license referenced by its attribute shortName (frowned upon)
              <literal>"gpl3"</literal>.
          </para></listitem>
          <listitem><para>Single license referenced by its attribute spdxId (frowned upon)
              <literal>"GPL-3.0"</literal>.
          </para></listitem>
          <listitem><para>Multiple licenses referenced by attribute (preferred)
              <literal>with stdenv.lib.licenses; [ asl20 free ofl ]</literal>.
          </para></listitem>
          <listitem><para>Multiple licenses referenced as a space delimited string of attribute shortNames (frowned upon)
              <literal>"asl20 free ofl"</literal>.
          </para></listitem>
        </itemizedlist>
        For details, see <xref linkend='sec-meta-license'/>.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>maintainers</varname></term>
    <listitem><para>A list of names and e-mail addresses of the
    maintainers of this Nix expression. If
    you would like to be a maintainer of a package, you may want to add
    yourself to <link
    xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/maintainers.nix"><filename>nixpkgs/lib/maintainers.nix</filename></link>
    and write something like <literal>[ stdenv.lib.maintainers.alice
    stdenv.lib.maintainers.bob ]</literal>.</para></listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>priority</varname></term>
    <listitem><para>The <emphasis>priority</emphasis> of the package,
    used by <command>nix-env</command> to resolve file name conflicts
    between packages.  See the Nix manual page for
    <command>nix-env</command> for details.  Example:
    <literal>"10"</literal> (a low-priority
    package).</para></listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>platforms</varname></term>
    <listitem><para>The list of Nix platform types on which the
    package is supported. Hydra builds packages according to the
    platform specified. If no platform is specified, the package does
    not have prebuilt binaries. An example is:

<programlisting>
meta.platforms = stdenv.lib.platforms.linux;
</programlisting>

    Attribute Set <varname>stdenv.lib.platforms</varname> defines
    <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/systems/doubles.nix">
    various common lists</link> of platforms types.</para></listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>hydraPlatforms</varname></term>
    <listitem><para>The list of Nix platform types for which the Hydra
    instance at <literal>hydra.nixos.org</literal> will build the
    package.  (Hydra is the Nix-based continuous build system.)  It
    defaults to the value of <varname>meta.platforms</varname>.  Thus,
    the only reason to set <varname>meta.hydraPlatforms</varname> is
    if you want <literal>hydra.nixos.org</literal> to build the
    package on a subset of <varname>meta.platforms</varname>, or not
    at all, e.g.

<programlisting>
meta.platforms = stdenv.lib.platforms.linux;
meta.hydraPlatforms = [];
</programlisting>

    </para></listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>broken</varname></term>
    <listitem><para>If set to <literal>true</literal>, the package is
    marked as “broken”, meaning that it won’t show up in
    <literal>nix-env -qa</literal>, and cannot be built or installed.
    Such packages should be removed from Nixpkgs eventually unless
    they are fixed.</para></listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>updateWalker</varname></term>
    <listitem><para>If set to <literal>true</literal>, the package is
    tested to be updated correctly by the <literal>update-walker.sh</literal>
    script without additional settings. Such packages have
    <varname>meta.version</varname> set and their homepage (or
    the page specified by <varname>meta.downloadPage</varname>) contains
    a direct link to the package tarball.</para></listitem>
  </varlistentry>

</variablelist>


</section>


<section xml:id="sec-meta-license"><title>Licenses</title>

<para>The <varname>meta.license</varname> attribute should preferrably contain
a value from <varname>stdenv.lib.licenses</varname> defined in
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/licenses.nix">
<filename>nixpkgs/lib/licenses.nix</filename></link>,
or in-place license description of the same format if the license is
unlikely to be useful in another expression.</para>

<para>Although it's typically better to indicate the specific license,
a few generic options are available:

<variablelist>

  <varlistentry>
    <term><varname>stdenv.lib.licenses.free</varname>,
    <varname>"free"</varname></term>

    <listitem><para>Catch-all for free software licenses not listed
    above.</para></listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>stdenv.lib.licenses.unfreeRedistributable</varname>,
    <varname>"unfree-redistributable"</varname></term>

    <listitem><para>Unfree package that can be redistributed in binary
    form. That is, it’s legal to redistribute the
    <emphasis>output</emphasis> of the derivation.  This means that
    the package can be included in the Nixpkgs
    channel.</para>

    <para>Sometimes proprietary software can only be redistributed
    unmodified. Make sure the builder doesn’t actually modify the
    original binaries; otherwise we’re breaking the license.  For
    instance, the NVIDIA X11 drivers can be redistributed unmodified,
    but our builder applies <command>patchelf</command> to make them
    work. Thus, its license is <varname>"unfree"</varname> and it
    cannot be included in the Nixpkgs channel.</para></listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>stdenv.lib.licenses.unfree</varname>,
    <varname>"unfree"</varname></term>

    <listitem><para>Unfree package that cannot be redistributed. You
    can build it yourself, but you cannot redistribute the output of
    the derivation. Thus it cannot be included in the Nixpkgs
    channel.</para></listitem>
  </varlistentry>

  <varlistentry>
    <term><varname>stdenv.lib.licenses.unfreeRedistributableFirmware</varname>,
    <varname>"unfree-redistributable-firmware"</varname></term>

    <listitem><para>This package supplies unfree, redistributable
    firmware.  This is a separate value from
    <varname>unfree-redistributable</varname> because not everybody
    cares whether firmware is free.</para></listitem>
  </varlistentry>

</variablelist>

</para>


</section>


</chapter>
