about summary refs log tree commit diff
path: root/doc/coding-conventions.xml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/coding-conventions.xml')
-rw-r--r--doc/coding-conventions.xml1292
1 files changed, 755 insertions, 537 deletions
diff --git a/doc/coding-conventions.xml b/doc/coding-conventions.xml
index d556c7ebe1ed..b3f7f093835c 100644
--- a/doc/coding-conventions.xml
+++ b/doc/coding-conventions.xml
@@ -1,56 +1,59 @@
 <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
-
+ <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
-
+     not
 <programlisting>
 foo
 {
   arg = ...;
 }
 </programlisting>
-
-  Also fine is
-
+     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:
-
+     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 =
@@ -73,12 +76,11 @@ attrs = {
     if true then big_expr else big_expr;
 };
 </programlisting>
-
-  </para></listitem>
-
-  <listitem><para>Short lists or attribute sets can be written on one
-  line:
-
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     Short lists or attribute sets can be written on one line:
 <programlisting>
 # A short list.
 list = [ elem1 elem2 elem3 ];
@@ -86,66 +88,58 @@ 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
-
+    </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:
-
+     (especially if the argument is very large, spanning multiple lines).
+    </para>
+    <para>
+     Better:
 <programlisting>
 someFunction
   { x = 1280; y = 1024; }
   otherArg
   yetAnotherArg
 </programlisting>
-
-  or
-
+     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.
-
+    </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
-
+     not
 <programlisting>
 { arg1, arg2 }:
   assert system == "i686-linux";
     stdenv.mkDerivation { ...
 </programlisting>
-
-  </para></listitem>
-
-  <listitem><para>Function formal arguments are written as:
-
+    </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:
-
+     but if they don't fit on one line they're written as:
 <programlisting>
 { arg1, arg2, arg3
 , arg4, ...
@@ -153,35 +147,28 @@ stdenv.mkDerivation { ...
   argN
 }:
 </programlisting>
-
-  </para></listitem>
-
-  <listitem><para>Functions should list their expected arguments as
-  precisely as possible.  That is, write
-
+    </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
-
+     instead of
 <programlisting>
 args: with args; <replaceable>...</replaceable>
 </programlisting>
-
-  or
-
+     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:
-
+    </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:
 
@@ -189,9 +176,7 @@ stdenv.mkDerivation (args // {
   <replaceable>...</replaceable> if doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable>
 })
 </programlisting>
-
-  instead of
-
+     instead of
 <programlisting>
 args:
 
@@ -199,432 +184,635 @@ args.stdenv.mkDerivation (args // {
   <replaceable>...</replaceable> if args ? doCoverageAnalysis &amp;&amp; args.doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable>
 })
 </programlisting>
+    </para>
+   </listitem>
+  </itemizedlist>
+ </section>
+ <section xml:id="sec-package-naming">
+  <title>Package naming</title>
 
-  </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>
+  <para>
+   In Nixpkgs, there are generally three different names associated with a
+   package:
+   <itemizedlist>
     <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>
+     <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>
-  </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>
+     <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>
-  </varlistentry>
-  <varlistentry>
-    <term>If it’s a <emphasis>shell</emphasis>:</term>
     <listitem>
-      <para><filename>shells</filename> (e.g. <filename>bash</filename>)</para>
+     <para>
+      The filename for (the directory containing) the Nix expression.
+     </para>
     </listitem>
-  </varlistentry>
-  <varlistentry>
-    <term>If it’s a <emphasis>server</emphasis>:</term>
+   </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>
-      <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>
+     <para>
+      Generally, try to stick to the upstream package name.
+     </para>
     </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>
+     <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>
-  </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>
+     <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>
-  </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>
+     <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>
-  </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>
+     <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>
-  </varlistentry>
-  <varlistentry>
-    <term>Else:</term>
     <listitem>
-      <para><filename>misc</filename></para>
+     <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>
-  </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>
+   </itemizedlist>
+  </para>
+ </section>
+ <section xml:id="sec-organisation">
+  <title>File naming and organisation</title>
 
-<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>
+  <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>
+  <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>
 
-</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>
+   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>
+   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.
+
+  <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";
@@ -632,10 +820,11 @@ src = fetchgit {
   sha256 = "1cw5fszffl5pkpa6s6wjnkiv6lm5k618s32sp60kvmvpy7a2v9kg";
 }
 </programlisting>
-        </para>
-      </listitem>
-      <listitem>
-        <para>Better: This is ok, but an archive fetch will still be faster.
+     </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";
@@ -643,10 +832,11 @@ src = fetchgit {
   sha256 = "1cw5fszffl5pkpa6s6wjnkiv6lm5k618s32sp60kvmvpy7a2v9kg";
 }
 </programlisting>
-        </para>
-      </listitem>
-      <listitem>
-        <para>Best: Fetches a snapshot archive and you get the rev you want.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      Best: Fetches a snapshot archive and you get the rev you want.
 <programlisting>
 src = fetchFromGitHub {
   owner = "NixOS";
@@ -655,15 +845,19 @@ src = fetchFromGitHub {
   sha256 = "04yri911rj9j19qqqn6m82266fl05pz98inasni0vxr1cf1gdgv9";
 }
 </programlisting>
-        </para>
-      </listitem>
-    </itemizedlist>
+     </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>
-</section>
 
-<section xml:id="sec-patches"><title>Patches</title>
-  <para>Patches available online should be retrieved using
-    <literal>fetchpatch</literal>.</para>
   <para>
 <programlisting>
 patches = [
@@ -675,30 +869,54 @@ patches = [
 ];
 </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>
+
+  <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>
+</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 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>
-
+     </para>
+    </listitem>
+   </orderedlist>
+  </para>
+ </section>
 </chapter>