705 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
			
		
		
	
	
			705 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
<chapter xmlns="http://docbook.org/ns/docbook"
 | 
						||
         xmlns:xlink="http://www.w3.org/1999/xlink"
 | 
						||
         xml:id="chap-conventions">
 | 
						||
 | 
						||
<title>Coding conventions</title>
 | 
						||
 | 
						||
 | 
						||
<section xml:id="sec-syntax"><title>Syntax</title>
 | 
						||
 | 
						||
<itemizedlist>
 | 
						||
 | 
						||
  <listitem><para>Use 2 spaces of indentation per indentation level in
 | 
						||
  Nix expressions, 4 spaces in shell scripts.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>Do not use tab characters, i.e. configure your
 | 
						||
  editor to use soft tabs.  For instance, use <literal>(setq-default
 | 
						||
  indent-tabs-mode nil)</literal> in Emacs.  Everybody has different
 | 
						||
  tab settings so it’s asking for trouble.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>Use <literal>lowerCamelCase</literal> for variable
 | 
						||
  names, not <literal>UpperCamelCase</literal>.  Note, this rule does
 | 
						||
  not apply to package attribute names, which instead follow the rules
 | 
						||
  in <xref linkend="sec-package-naming"/>.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>Function calls with attribute set arguments are
 | 
						||
  written as
 | 
						||
 | 
						||
<programlisting>
 | 
						||
foo {
 | 
						||
  arg = ...;
 | 
						||
}
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  not
 | 
						||
 | 
						||
<programlisting>
 | 
						||
foo
 | 
						||
{
 | 
						||
  arg = ...;
 | 
						||
}
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  Also fine is
 | 
						||
 | 
						||
<programlisting>
 | 
						||
foo { arg = ...; }
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  if it's a short call.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>In attribute sets or lists that span multiple lines,
 | 
						||
  the attribute names or list elements should be aligned:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
# A long list.
 | 
						||
list =
 | 
						||
  [ elem1
 | 
						||
    elem2
 | 
						||
    elem3
 | 
						||
  ];
 | 
						||
 | 
						||
# A long attribute set.
 | 
						||
attrs =
 | 
						||
  { attr1 = short_expr;
 | 
						||
    attr2 =
 | 
						||
      if true then big_expr else big_expr;
 | 
						||
  };
 | 
						||
 | 
						||
# Alternatively:
 | 
						||
attrs = {
 | 
						||
  attr1 = short_expr;
 | 
						||
  attr2 =
 | 
						||
    if true then big_expr else big_expr;
 | 
						||
};
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  </para></listitem>
 | 
						||
 | 
						||
  <listitem><para>Short lists or attribute sets can be written on one
 | 
						||
  line:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
# A short list.
 | 
						||
list = [ elem1 elem2 elem3 ];
 | 
						||
 | 
						||
# A short set.
 | 
						||
attrs = { x = 1280; y = 1024; };
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  </para></listitem>
 | 
						||
 | 
						||
  <listitem><para>Breaking in the middle of a function argument can
 | 
						||
  give hard-to-read code, like
 | 
						||
 | 
						||
<programlisting>
 | 
						||
someFunction { x = 1280;
 | 
						||
  y = 1024; } otherArg
 | 
						||
  yetAnotherArg
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  (especially if the argument is very large, spanning multiple
 | 
						||
  lines).</para>
 | 
						||
 | 
						||
  <para>Better:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
someFunction
 | 
						||
  { x = 1280; y = 1024; }
 | 
						||
  otherArg
 | 
						||
  yetAnotherArg
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  or
 | 
						||
 | 
						||
<programlisting>
 | 
						||
let res = { x = 1280; y = 1024; };
 | 
						||
in someFunction res otherArg yetAnotherArg
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  </para></listitem>
 | 
						||
 | 
						||
  <listitem><para>The bodies of functions, asserts, and withs are not
 | 
						||
  indented to prevent a lot of superfluous indentation levels, i.e.
 | 
						||
 | 
						||
<programlisting>
 | 
						||
{ arg1, arg2 }:
 | 
						||
assert system == "i686-linux";
 | 
						||
stdenv.mkDerivation { ...
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  not
 | 
						||
 | 
						||
<programlisting>
 | 
						||
{ arg1, arg2 }:
 | 
						||
  assert system == "i686-linux";
 | 
						||
    stdenv.mkDerivation { ...
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  </para></listitem>
 | 
						||
 | 
						||
  <listitem><para>Function formal arguments are written as:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
{ arg1, arg2, arg3 }:
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  but if they don't fit on one line they're written as:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
{ arg1, arg2, arg3
 | 
						||
, arg4, ...
 | 
						||
, # Some comment...
 | 
						||
  argN
 | 
						||
}:
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  </para></listitem>
 | 
						||
 | 
						||
  <listitem><para>Functions should list their expected arguments as
 | 
						||
  precisely as possible.  That is, write
 | 
						||
 | 
						||
<programlisting>
 | 
						||
{ stdenv, fetchurl, perl }: <replaceable>...</replaceable>
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  instead of
 | 
						||
 | 
						||
<programlisting>
 | 
						||
args: with args; <replaceable>...</replaceable>
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  or
 | 
						||
 | 
						||
<programlisting>
 | 
						||
{ stdenv, fetchurl, perl, ... }: <replaceable>...</replaceable>
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  </para>
 | 
						||
 | 
						||
  <para>For functions that are truly generic in the number of
 | 
						||
  arguments (such as wrappers around <varname>mkDerivation</varname>)
 | 
						||
  that have some required arguments, you should write them using an
 | 
						||
  <literal>@</literal>-pattern:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
{ stdenv, doCoverageAnalysis ? false, ... } @ args:
 | 
						||
 | 
						||
stdenv.mkDerivation (args // {
 | 
						||
  <replaceable>...</replaceable> if doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable>
 | 
						||
})
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  instead of
 | 
						||
 | 
						||
<programlisting>
 | 
						||
args:
 | 
						||
 | 
						||
args.stdenv.mkDerivation (args // {
 | 
						||
  <replaceable>...</replaceable> if args ? doCoverageAnalysis && args.doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable>
 | 
						||
})
 | 
						||
</programlisting>
 | 
						||
 | 
						||
  </para></listitem>
 | 
						||
 | 
						||
</itemizedlist>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<section xml:id="sec-package-naming"><title>Package naming</title>
 | 
						||
 | 
						||
<para>In Nixpkgs, there are generally three different names associated with a package:
 | 
						||
 | 
						||
<itemizedlist>
 | 
						||
 | 
						||
  <listitem><para>The <varname>name</varname> attribute of the
 | 
						||
  derivation (excluding the version part).  This is what most users
 | 
						||
  see, in particular when using
 | 
						||
  <command>nix-env</command>.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>The variable name used for the instantiated package
 | 
						||
  in <filename>all-packages.nix</filename>, and when passing it as a
 | 
						||
  dependency to other functions.  Typically this is called the
 | 
						||
  <emphasis>package attribute name</emphasis>.  This is what Nix
 | 
						||
  expression authors see.  It can also be used when installing using
 | 
						||
  <command>nix-env -iA</command>.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>The filename for (the directory containing) the Nix
 | 
						||
  expression.</para></listitem>
 | 
						||
 | 
						||
</itemizedlist>
 | 
						||
 | 
						||
Most of the time, these are the same.  For instance, the package
 | 
						||
<literal>e2fsprogs</literal> has a <varname>name</varname> attribute
 | 
						||
<literal>"e2fsprogs-<replaceable>version</replaceable>"</literal>, is
 | 
						||
bound to the variable name <varname>e2fsprogs</varname> in
 | 
						||
<filename>all-packages.nix</filename>, and the Nix expression is in
 | 
						||
<filename>pkgs/os-specific/linux/e2fsprogs/default.nix</filename>.
 | 
						||
</para>
 | 
						||
 | 
						||
<para>There are a few naming guidelines:
 | 
						||
 | 
						||
<itemizedlist>
 | 
						||
 | 
						||
  <listitem><para>Generally, try to stick to the upstream package
 | 
						||
  name.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>Don’t use uppercase letters in the
 | 
						||
  <literal>name</literal> attribute — e.g.,
 | 
						||
  <literal>"mplayer-1.0rc2"</literal> instead of
 | 
						||
  <literal>"MPlayer-1.0rc2"</literal>.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>The version part of the <literal>name</literal>
 | 
						||
  attribute <emphasis>must</emphasis> start with a digit (following a
 | 
						||
  dash) — e.g., <literal>"hello-0.3.1rc2"</literal>.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>If a package is not a release but a commit from a repository, then
 | 
						||
  the version part of the name <emphasis>must</emphasis> be the date of that
 | 
						||
  (fetched) commit. The date must be in <literal>"YYYY-MM-DD"</literal> format.
 | 
						||
  Also append <literal>"unstable"</literal> to the name - e.g.,
 | 
						||
  <literal>"pkgname-unstable-2014-09-23"</literal>.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>Dashes in the package name should be preserved in
 | 
						||
  new variable names, rather than converted to underscores or camel
 | 
						||
  cased — e.g., <varname>http-parser</varname> instead of
 | 
						||
  <varname>http_parser</varname> or <varname>httpParser</varname>.  The
 | 
						||
  hyphenated style is preferred in all three package
 | 
						||
  names.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>If there are multiple versions of a package, this
 | 
						||
  should be reflected in the variable names in
 | 
						||
  <filename>all-packages.nix</filename>,
 | 
						||
  e.g. <varname>json-c-0-9</varname> and <varname>json-c-0-11</varname>.
 | 
						||
  If there is an obvious “default” version, make an attribute like
 | 
						||
  <literal>json-c = json-c-0-9;</literal>.
 | 
						||
  See also <xref linkend="sec-versioning" /></para></listitem>
 | 
						||
 | 
						||
</itemizedlist>
 | 
						||
 | 
						||
</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<section xml:id="sec-organisation"><title>File naming and organisation</title>
 | 
						||
 | 
						||
<para>Names of files and directories should be in lowercase, with
 | 
						||
dashes between words — not in camel case.  For instance, it should be
 | 
						||
<filename>all-packages.nix</filename>, not
 | 
						||
<filename>allPackages.nix</filename> or
 | 
						||
<filename>AllPackages.nix</filename>.</para>
 | 
						||
 | 
						||
<section xml:id="sec-hierarchy"><title>Hierarchy</title>
 | 
						||
 | 
						||
<para>Each package should be stored in its own directory somewhere in
 | 
						||
the <filename>pkgs/</filename> tree, i.e. in
 | 
						||
<filename>pkgs/<replaceable>category</replaceable>/<replaceable>subcategory</replaceable>/<replaceable>...</replaceable>/<replaceable>pkgname</replaceable></filename>.
 | 
						||
Below are some rules for picking the right category for a package.
 | 
						||
Many packages fall under several categories; what matters is the
 | 
						||
<emphasis>primary</emphasis> purpose of a package.  For example, the
 | 
						||
<literal>libxml2</literal> package builds both a library and some
 | 
						||
tools; but it’s a library foremost, so it goes under
 | 
						||
<filename>pkgs/development/libraries</filename>.</para>
 | 
						||
 | 
						||
<para>When in doubt, consider refactoring the
 | 
						||
<filename>pkgs/</filename> tree, e.g. creating new categories or
 | 
						||
splitting up an existing category.</para>
 | 
						||
 | 
						||
<variablelist>
 | 
						||
  <varlistentry>
 | 
						||
    <term>If it’s used to support <emphasis>software development</emphasis>:</term>
 | 
						||
    <listitem>
 | 
						||
      <variablelist>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s a <emphasis>library</emphasis> used by other packages:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>development/libraries</filename> (e.g. <filename>libxml2</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s a <emphasis>compiler</emphasis>:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>development/compilers</filename> (e.g. <filename>gcc</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s an <emphasis>interpreter</emphasis>:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>development/interpreters</filename> (e.g. <filename>guile</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s a (set of) development <emphasis>tool(s)</emphasis>:</term>
 | 
						||
          <listitem>
 | 
						||
            <variablelist>
 | 
						||
              <varlistentry>
 | 
						||
                <term>If it’s a <emphasis>parser generator</emphasis> (including lexers):</term>
 | 
						||
                <listitem>
 | 
						||
                  <para><filename>development/tools/parsing</filename> (e.g. <filename>bison</filename>, <filename>flex</filename>)</para>
 | 
						||
                </listitem>
 | 
						||
              </varlistentry>
 | 
						||
              <varlistentry>
 | 
						||
                <term>If it’s a <emphasis>build manager</emphasis>:</term>
 | 
						||
                <listitem>
 | 
						||
                  <para><filename>development/tools/build-managers</filename> (e.g. <filename>gnumake</filename>)</para>
 | 
						||
                </listitem>
 | 
						||
              </varlistentry>
 | 
						||
              <varlistentry>
 | 
						||
                <term>Else:</term>
 | 
						||
                <listitem>
 | 
						||
                  <para><filename>development/tools/misc</filename> (e.g. <filename>binutils</filename>)</para>
 | 
						||
                </listitem>
 | 
						||
              </varlistentry>
 | 
						||
            </variablelist>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>Else:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>development/misc</filename></para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
      </variablelist>
 | 
						||
    </listitem>
 | 
						||
  </varlistentry>
 | 
						||
  <varlistentry>
 | 
						||
    <term>If it’s a (set of) <emphasis>tool(s)</emphasis>:</term>
 | 
						||
    <listitem>
 | 
						||
      <para>(A tool is a relatively small program, especially one intended
 | 
						||
      to be used non-interactively.)</para>
 | 
						||
      <variablelist>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s for <emphasis>networking</emphasis>:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>tools/networking</filename> (e.g. <filename>wget</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s for <emphasis>text processing</emphasis>:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>tools/text</filename> (e.g. <filename>diffutils</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s a <emphasis>system utility</emphasis>, i.e.,
 | 
						||
          something related or essential to the operation of a
 | 
						||
          system:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>tools/system</filename> (e.g. <filename>cron</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s an <emphasis>archiver</emphasis> (which may
 | 
						||
          include a compression function):</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>tools/archivers</filename> (e.g. <filename>zip</filename>, <filename>tar</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s a <emphasis>compression</emphasis> program:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>tools/compression</filename> (e.g. <filename>gzip</filename>, <filename>bzip2</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s a <emphasis>security</emphasis>-related program:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>tools/security</filename> (e.g. <filename>nmap</filename>, <filename>gnupg</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>Else:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>tools/misc</filename></para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
      </variablelist>
 | 
						||
    </listitem>
 | 
						||
  </varlistentry>
 | 
						||
  <varlistentry>
 | 
						||
    <term>If it’s a <emphasis>shell</emphasis>:</term>
 | 
						||
    <listitem>
 | 
						||
      <para><filename>shells</filename> (e.g. <filename>bash</filename>)</para>
 | 
						||
    </listitem>
 | 
						||
  </varlistentry>
 | 
						||
  <varlistentry>
 | 
						||
    <term>If it’s a <emphasis>server</emphasis>:</term>
 | 
						||
    <listitem>
 | 
						||
      <variablelist>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s a web server:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>servers/http</filename> (e.g. <filename>apache-httpd</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s an implementation of the X Windowing System:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>servers/x11</filename> (e.g. <filename>xorg</filename> — this includes the client libraries and programs)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>Else:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>servers/misc</filename></para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
      </variablelist>
 | 
						||
    </listitem>
 | 
						||
  </varlistentry>
 | 
						||
  <varlistentry>
 | 
						||
    <term>If it’s a <emphasis>desktop environment</emphasis>:</term>
 | 
						||
    <listitem>
 | 
						||
      <para><filename>desktops</filename> (e.g. <filename>kde</filename>, <filename>gnome</filename>, <filename>enlightenment</filename>)</para>
 | 
						||
    </listitem>
 | 
						||
  </varlistentry>
 | 
						||
  <varlistentry>
 | 
						||
    <term>If it’s a <emphasis>window manager</emphasis>:</term>
 | 
						||
    <listitem>
 | 
						||
      <para><filename>applications/window-managers</filename> (e.g. <filename>awesome</filename>, <filename>stumpwm</filename>)</para>
 | 
						||
    </listitem>
 | 
						||
  </varlistentry>
 | 
						||
  <varlistentry>
 | 
						||
    <term>If it’s an <emphasis>application</emphasis>:</term>
 | 
						||
    <listitem>
 | 
						||
      <para>A (typically large) program with a distinct user
 | 
						||
      interface, primarily used interactively.</para>
 | 
						||
      <variablelist>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s a <emphasis>version management system</emphasis>:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>applications/version-management</filename> (e.g. <filename>subversion</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s for <emphasis>video playback / editing</emphasis>:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>applications/video</filename> (e.g. <filename>vlc</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s for <emphasis>graphics viewing / editing</emphasis>:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>applications/graphics</filename> (e.g. <filename>gimp</filename>)</para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s for <emphasis>networking</emphasis>:</term>
 | 
						||
          <listitem>
 | 
						||
            <variablelist>
 | 
						||
              <varlistentry>
 | 
						||
                <term>If it’s a <emphasis>mailreader</emphasis>:</term>
 | 
						||
                <listitem>
 | 
						||
                  <para><filename>applications/networking/mailreaders</filename> (e.g. <filename>thunderbird</filename>)</para>
 | 
						||
                </listitem>
 | 
						||
              </varlistentry>
 | 
						||
              <varlistentry>
 | 
						||
                <term>If it’s a <emphasis>newsreader</emphasis>:</term>
 | 
						||
                <listitem>
 | 
						||
                  <para><filename>applications/networking/newsreaders</filename> (e.g. <filename>pan</filename>)</para>
 | 
						||
                </listitem>
 | 
						||
              </varlistentry>
 | 
						||
              <varlistentry>
 | 
						||
                <term>If it’s a <emphasis>web browser</emphasis>:</term>
 | 
						||
                <listitem>
 | 
						||
                  <para><filename>applications/networking/browsers</filename> (e.g. <filename>firefox</filename>)</para>
 | 
						||
                </listitem>
 | 
						||
              </varlistentry>
 | 
						||
              <varlistentry>
 | 
						||
                <term>Else:</term>
 | 
						||
                <listitem>
 | 
						||
                  <para><filename>applications/networking/misc</filename></para>
 | 
						||
                </listitem>
 | 
						||
              </varlistentry>
 | 
						||
            </variablelist>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>Else:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>applications/misc</filename></para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
      </variablelist>
 | 
						||
    </listitem>
 | 
						||
  </varlistentry>
 | 
						||
  <varlistentry>
 | 
						||
    <term>If it’s <emphasis>data</emphasis> (i.e., does not have a
 | 
						||
    straight-forward executable semantics):</term>
 | 
						||
    <listitem>
 | 
						||
      <variablelist>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s a <emphasis>font</emphasis>:</term>
 | 
						||
          <listitem>
 | 
						||
            <para><filename>data/fonts</filename></para>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
        <varlistentry>
 | 
						||
          <term>If it’s related to <emphasis>SGML/XML processing</emphasis>:</term>
 | 
						||
          <listitem>
 | 
						||
            <variablelist>
 | 
						||
              <varlistentry>
 | 
						||
                <term>If it’s an <emphasis>XML DTD</emphasis>:</term>
 | 
						||
                <listitem>
 | 
						||
                  <para><filename>data/sgml+xml/schemas/xml-dtd</filename> (e.g. <filename>docbook</filename>)</para>
 | 
						||
                </listitem>
 | 
						||
              </varlistentry>
 | 
						||
              <varlistentry>
 | 
						||
                <term>If it’s an <emphasis>XSLT stylesheet</emphasis>:</term>
 | 
						||
                <listitem>
 | 
						||
                  <para>(Okay, these are executable...)</para>
 | 
						||
                  <para><filename>data/sgml+xml/stylesheets/xslt</filename> (e.g. <filename>docbook-xsl</filename>)</para>
 | 
						||
                </listitem>
 | 
						||
              </varlistentry>
 | 
						||
            </variablelist>
 | 
						||
          </listitem>
 | 
						||
        </varlistentry>
 | 
						||
      </variablelist>
 | 
						||
    </listitem>
 | 
						||
  </varlistentry>
 | 
						||
  <varlistentry>
 | 
						||
    <term>If it’s a <emphasis>game</emphasis>:</term>
 | 
						||
    <listitem>
 | 
						||
      <para><filename>games</filename></para>
 | 
						||
    </listitem>
 | 
						||
  </varlistentry>
 | 
						||
  <varlistentry>
 | 
						||
    <term>Else:</term>
 | 
						||
    <listitem>
 | 
						||
      <para><filename>misc</filename></para>
 | 
						||
    </listitem>
 | 
						||
  </varlistentry>
 | 
						||
</variablelist>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
<section xml:id="sec-versioning"><title>Versioning</title>
 | 
						||
 | 
						||
<para>Because every version of a package in Nixpkgs creates a
 | 
						||
potential maintenance burden, old versions of a package should not be
 | 
						||
kept unless there is a good reason to do so.  For instance, Nixpkgs
 | 
						||
contains several versions of GCC because other packages don’t build
 | 
						||
with the latest version of GCC.  Other examples are having both the
 | 
						||
latest stable and latest pre-release version of a package, or to keep
 | 
						||
several major releases of an application that differ significantly in
 | 
						||
functionality.</para>
 | 
						||
 | 
						||
<para>If there is only one version of a package, its Nix expression
 | 
						||
should be named <filename>e2fsprogs/default.nix</filename>.  If there
 | 
						||
are multiple versions, this should be reflected in the filename,
 | 
						||
e.g. <filename>e2fsprogs/1.41.8.nix</filename> and
 | 
						||
<filename>e2fsprogs/1.41.9.nix</filename>.  The version in the
 | 
						||
filename should leave out unnecessary detail.  For instance, if we
 | 
						||
keep the latest Firefox 2.0.x and 3.5.x versions in Nixpkgs, they
 | 
						||
should be named <filename>firefox/2.0.nix</filename> and
 | 
						||
<filename>firefox/3.5.nix</filename>, respectively (which, at a given
 | 
						||
point, might contain versions <literal>2.0.0.20</literal> and
 | 
						||
<literal>3.5.4</literal>).  If a version requires many auxiliary
 | 
						||
files, you can use a subdirectory for each version,
 | 
						||
e.g. <filename>firefox/2.0/default.nix</filename> and
 | 
						||
<filename>firefox/3.5/default.nix</filename>.</para>
 | 
						||
 | 
						||
<para>All versions of a package <emphasis>must</emphasis> be included
 | 
						||
in <filename>all-packages.nix</filename> to make sure that they
 | 
						||
evaluate correctly.</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
</section>
 | 
						||
<section xml:id="sec-sources"><title>Fetching Sources</title>
 | 
						||
  <para>There are multiple ways to fetch a package source in nixpkgs. The
 | 
						||
    general guideline is that you should package sources with a high degree of
 | 
						||
    availability. Right now there is only one fetcher which has mirroring
 | 
						||
    support and that is <literal>fetchurl</literal>. Note that you should also
 | 
						||
    prefer protocols which have a corresponding proxy environment variable.
 | 
						||
  </para>
 | 
						||
  <para>You can find many source fetch helpers in <literal>pkgs/build-support/fetch*</literal>.
 | 
						||
  </para>
 | 
						||
  <para>In the file <literal>pkgs/top-level/all-packages.nix</literal> you can
 | 
						||
    find fetch helpers, these have names on the form
 | 
						||
    <literal>fetchFrom*</literal>. The intention of these are to provide
 | 
						||
    snapshot fetches but using the same api as some of the version controlled
 | 
						||
    fetchers from <literal>pkgs/build-support/</literal>. As an example going
 | 
						||
    from bad to good:
 | 
						||
    <itemizedlist>
 | 
						||
      <listitem>
 | 
						||
        <para>Bad: Uses <literal>git://</literal> which won't be proxied.
 | 
						||
<programlisting>
 | 
						||
src = fetchgit {
 | 
						||
  url = "git://github.com/NixOS/nix.git";
 | 
						||
  rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
 | 
						||
  sha256 = "1cw5fszffl5pkpa6s6wjnkiv6lm5k618s32sp60kvmvpy7a2v9kg";
 | 
						||
}
 | 
						||
</programlisting>
 | 
						||
        </para>
 | 
						||
      </listitem>
 | 
						||
      <listitem>
 | 
						||
        <para>Better: This is ok, but an archive fetch will still be faster.
 | 
						||
<programlisting>
 | 
						||
src = fetchgit {
 | 
						||
  url = "https://github.com/NixOS/nix.git";
 | 
						||
  rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
 | 
						||
  sha256 = "1cw5fszffl5pkpa6s6wjnkiv6lm5k618s32sp60kvmvpy7a2v9kg";
 | 
						||
}
 | 
						||
</programlisting>
 | 
						||
        </para>
 | 
						||
      </listitem>
 | 
						||
      <listitem>
 | 
						||
        <para>Best: Fetches a snapshot archive and you get the rev you want.
 | 
						||
<programlisting>
 | 
						||
src = fetchFromGitHub {
 | 
						||
  owner = "NixOS";
 | 
						||
  repo = "nix";
 | 
						||
  rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
 | 
						||
  sha256 = "04yri911rj9j19qqqn6m82266fl05pz98inasni0vxr1cf1gdgv9";
 | 
						||
}
 | 
						||
</programlisting>
 | 
						||
        </para>
 | 
						||
      </listitem>
 | 
						||
    </itemizedlist>
 | 
						||
  </para>
 | 
						||
</section>
 | 
						||
 | 
						||
<section xml:id="sec-patches"><title>Patches</title>
 | 
						||
  <para>Patches available online should be retrieved using
 | 
						||
    <literal>fetchpatch</literal>.</para>
 | 
						||
  <para>
 | 
						||
<programlisting>
 | 
						||
patches = [
 | 
						||
  (fetchpatch {
 | 
						||
    name = "fix-check-for-using-shared-freetype-lib.patch";
 | 
						||
    url = "http://git.ghostscript.com/?p=ghostpdl.git;a=patch;h=8f5d285";
 | 
						||
    sha256 = "1f0k043rng7f0rfl9hhb89qzvvksqmkrikmm38p61yfx51l325xr";
 | 
						||
  })
 | 
						||
];
 | 
						||
</programlisting>
 | 
						||
  </para>
 | 
						||
  <para>Otherwise, you can add a <literal>.patch</literal> file to the
 | 
						||
  <literal>nixpkgs</literal> repository. In the interest of keeping our
 | 
						||
  maintenance burden to a minimum, only patches that are unique
 | 
						||
  to <literal>nixpkgs</literal> should be added in this way.</para>
 | 
						||
<para><programlisting>
 | 
						||
patches = [ ./0001-changes.patch ];
 | 
						||
</programlisting></para>
 | 
						||
  <para>If you do need to do create this sort of patch file,
 | 
						||
  one way to do so is with git:
 | 
						||
  <orderedlist>
 | 
						||
    <listitem><para>Move to the root directory of the source code
 | 
						||
    you're patching.<screen>
 | 
						||
$ cd the/program/source</screen></para></listitem>
 | 
						||
    <listitem><para>If a git repository is not already present,
 | 
						||
    create one and stage all of the source files.<screen>
 | 
						||
$ git init
 | 
						||
$ git add .</screen></para></listitem>
 | 
						||
    <listitem><para>Edit some files to make whatever changes need
 | 
						||
    to be included in the patch.</para></listitem>
 | 
						||
    <listitem><para>Use git to create a diff, and pipe the output
 | 
						||
    to a patch file:<screen>
 | 
						||
$ git diff > nixpkgs/pkgs/the/package/0001-changes.patch</screen>
 | 
						||
    </para></listitem>
 | 
						||
  </orderedlist></para>
 | 
						||
</section>
 | 
						||
 | 
						||
</chapter>
 |