1 <chapter xmlns="http://docbook.org/ns/docbook"
2 xmlns:xlink="http://www.w3.org/1999/xlink"
3 xml:id="chap-conventions">
5 <title>Coding conventions</title>
8 <section><title>Syntax</title>
12 <listitem><para>Use 2 spaces of indentation per indentation level in
13 Nix expressions, 4 spaces in shell scripts.</para></listitem>
15 <listitem><para>Do not use tab characters, i.e. configure your
16 editor to use soft tabs. For instance, use <literal>(setq-default
17 indent-tabs-mode nil)</literal> in Emacs. Everybody has different
18 tab settings so it’s asking for trouble.</para></listitem>
20 <listitem><para>Use <literal>lowerCamelCase</literal> for variable
21 names, not <literal>UpperCamelCase</literal>. TODO: naming of
23 <filename>all-packages.nix</filename>?</para></listitem>
25 <listitem><para>Function calls with attribute set arguments are
49 if it's a short call.</para></listitem>
51 <listitem><para>In attribute sets or lists that span multiple lines,
52 the attribute names or list elements should be aligned:
62 # A long attribute set.
66 if true then big_expr else big_expr;
73 if true then big_expr else big_expr;
79 <listitem><para>Short lists or attribute sets can be written on one
84 list = [ elem1 elem2 elem3 ];
87 attrs = { x = 1280; y = 1024; };
92 <listitem><para>Breaking in the middle of a function argument can
93 give hard-to-read code, like
96 someFunction { x = 1280;
101 (especially if the argument is very large, spanning multiple
108 { x = 1280; y = 1024; }
116 let res = { x = 1280; y = 1024; };
117 in someFunction res otherArg yetAnotherArg
122 <listitem><para>The bodies of functions, asserts, and withs are not
123 indented to prevent a lot of superfluous indentation levels, i.e.
127 assert system == "i686-linux";
128 stdenv.mkDerivation { ...
135 assert system == "i686-linux";
136 stdenv.mkDerivation { ...
141 <listitem><para>Function formal arguments are written as:
144 { arg1, arg2, arg3 }:
147 but if they don't fit on one line they're written as:
159 <listitem><para>Functions should list their expected arguments as
160 precisely as possible. That is, write
163 { stdenv, fetchurl, perl }: <replaceable>...</replaceable>
169 args: with args; <replaceable>...</replaceable>
175 { stdenv, fetchurl, perl, ... }: <replaceable>...</replaceable>
180 <para>For functions that are truly generic in the number of
181 arguments (such as wrappers around <varname>mkDerivation</varname>)
182 that have some required arguments, you should write them using an
183 <literal>@</literal>-pattern:
186 { stdenv, doCoverageAnalysis ? false, ... } @ args:
188 stdenv.mkDerivation (args // {
189 <replaceable>...</replaceable> if doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable>
198 args.stdenv.mkDerivation (args // {
199 <replaceable>...</replaceable> if args ? doCoverageAnalysis && args.doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable>
210 <section><title>Package naming</title>
212 <para>In Nixpkgs, there are generally three different names associated with a package:
216 <listitem><para>The <varname>name</varname> attribute of the
217 derivation (excluding the version part). This is what most users
218 see, in particular when using
219 <command>nix-env</command>.</para></listitem>
221 <listitem><para>The variable name used for the instantiated package
222 in <filename>all-packages.nix</filename>, and when passing it as a
223 dependency to other functions. This is what Nix expression authors
224 see. It can also be used when installing using <command>nix-env
225 -iA</command>.</para></listitem>
227 <listitem><para>The filename for (the directory containing) the Nix
228 expression.</para></listitem>
232 Most of the time, these are the same. For instance, the package
233 <literal>e2fsprogs</literal> has a <varname>name</varname> attribute
234 <literal>"e2fsprogs-<replaceable>version</replaceable>"</literal>, is
235 bound to the variable name <varname>e2fsprogs</varname> in
236 <filename>all-packages.nix</filename>, and the Nix expression is in
237 <filename>pkgs/os-specific/linux/e2fsprogs/default.nix</filename>.
238 However, identifiers in the Nix language don’t allow certain
239 characters (e.g. dashes), so sometimes a different variable name
240 should be used. For instance, the
241 <literal>module-init-tools</literal> package is bound to the
242 <literal>module_init_tools</literal> variable in
243 <filename>all-packages.nix</filename>.</para>
245 <para>There are a few naming guidelines:
249 <listitem><para>Generally, try to stick to the upstream package
250 name.</para></listitem>
252 <listitem><para>Don’t use uppercase letters in the
253 <literal>name</literal> attribute — e.g.,
254 <literal>"mplayer-1.0rc2"</literal> instead of
255 <literal>"MPlayer-1.0rc2"</literal>.</para></listitem>
257 <listitem><para>The version part of the <literal>name</literal>
258 attribute <emphasis>must</emphasis> start with a digit (following a
259 dash) — e.g., <literal>"hello-0.3-pre-r3910"</literal> instead of
260 <literal>"hello-svn-r3910"</literal>, as the latter would be seen as
261 a package named <literal>hello-svn</literal> by
262 <command>nix-env</command>.</para></listitem>
264 <listitem><para>Dashes in the package name should be changed to
265 underscores in variable names, rather than to camel case — e.g.,
266 <varname>module_init_tools</varname> instead of
267 <varname>moduleInitTools</varname>.</para></listitem>
269 <listitem><para>If there are multiple versions of a package, this
270 should be reflected in the variable names in
271 <filename>all-packages.nix</filename>,
272 e.g. <varname>hello_0_3</varname> and <varname>hello_0_4</varname>.
273 If there is an obvious “default” version, make an attribute like
274 <literal>hello = hello_0_4;</literal>.</para></listitem>
283 <section xml:id="sec-organisation"><title>File naming and organisation</title>
285 <para>Names of files and directories should be in lowercase, with
286 dashes between words — not in camel case. For instance, it should be
287 <filename>all-packages.nix</filename>, not
288 <filename>allPackages.nix</filename> or
289 <filename>AllPackages.nix</filename>.</para>
291 <section><title>Hierachy</title>
293 <para>Each package should be stored in its own directory somewhere in
294 the <filename>pkgs/</filename> tree, i.e. in
295 <filename>pkgs/<replaceable>category</replaceable>/<replaceable>subcategory</replaceable>/<replaceable>...</replaceable>/<replaceable>pkgname</replaceable></filename>.
296 Below are some rules for picking the right category for a package.
297 Many packages fall under several categories; what matters is the
298 <emphasis>primary</emphasis> purpose of a package. For example, the
299 <literal>libxml2</literal> package builds both a library and some
300 tools; but it’s a library foremost, so it goes under
301 <filename>pkgs/development/libraries</filename>.</para>
303 <para>When in doubt, consider refactoring the
304 <filename>pkgs/</filename> tree, e.g. creating new categories or
305 splitting up an existing category.</para>
309 <term>If it’s used to support <emphasis>software development</emphasis>:</term>
313 <term>If it’s a <emphasis>library</emphasis> used by other packages:</term>
315 <para><filename>development/libraries</filename> (e.g. <filename>libxml2</filename>)</para>
319 <term>If it’s a <emphasis>compiler</emphasis>:</term>
321 <para><filename>development/compilers</filename> (e.g. <filename>gcc</filename>)</para>
325 <term>If it’s an <emphasis>interpreter</emphasis>:</term>
327 <para><filename>development/interpreters</filename> (e.g. <filename>guile</filename>)</para>
331 <term>If it’s a (set of) development <emphasis>tool(s)</emphasis>:</term>
335 <term>If it’s a <emphasis>parser generator</emphasis> (including lexers):</term>
337 <para><filename>development/tools/parsing</filename> (e.g. <filename>bison</filename>, <filename>flex</filename>)</para>
341 <term>If it’s a <emphasis>build manager</emphasis>:</term>
343 <para><filename>development/tools/build-managers</filename> (e.g. <filename>gnumake</filename>)</para>
349 <para><filename>development/tools/misc</filename> (e.g. <filename>binutils</filename>)</para>
358 <para><filename>development/misc</filename></para>
365 <term>If it’s a (set of) <emphasis>tool(s)</emphasis>:</term>
367 <para>(A tool is a relatively small program, especially one intented
368 to be used non-interactively.)</para>
371 <term>If it’s for <emphasis>networking</emphasis>:</term>
373 <para><filename>tools/networking</filename> (e.g. <filename>wget</filename>)</para>
377 <term>If it’s for <emphasis>text processing</emphasis>:</term>
379 <para><filename>tools/text</filename> (e.g. <filename>diffutils</filename>)</para>
383 <term>If it’s a <emphasis>system utility</emphasis>, i.e.,
384 something related or essential to the operation of a
387 <para><filename>tools/system</filename> (e.g. <filename>cron</filename>)</para>
391 <term>If it’s an <emphasis>archiver</emphasis> (which may
392 include a compression function):</term>
394 <para><filename>tools/archivers</filename> (e.g. <filename>zip</filename>, <filename>tar</filename>)</para>
398 <term>If it’s a <emphasis>compression</emphasis> program:</term>
400 <para><filename>tools/compression</filename> (e.g. <filename>gzip</filename>, <filename>bzip2</filename>)</para>
404 <term>If it’s a <emphasis>security</emphasis>-related program:</term>
406 <para><filename>tools/security</filename> (e.g. <filename>nmap</filename>, <filename>gnupg</filename>)</para>
412 <para><filename>tools/misc</filename></para>
419 <term>If it’s a <emphasis>shell</emphasis>:</term>
421 <para><filename>shells</filename> (e.g. <filename>bash</filename>)</para>
425 <term>If it’s a <emphasis>server</emphasis>:</term>
429 <term>If it’s a web server:</term>
431 <para><filename>servers/http</filename> (e.g. <filename>apache-httpd</filename>)</para>
435 <term>If it’s an implementation of the X Windowing System:</term>
437 <para><filename>servers/x11</filename> (e.g. <filename>xorg</filename> — this includes the client libraries and programs)</para>
443 <para><filename>servers/misc</filename></para>
450 <term>If it’s a <emphasis>desktop environment</emphasis>
451 (including <emphasis>window managers</emphasis>):</term>
453 <para><filename>desktops</filename> (e.g. <filename>kde</filename>, <filename>gnome</filename>, <filename>enlightenment</filename>)</para>
457 <term>If it’s an <emphasis>application</emphasis>:</term>
459 <para>A (typically large) program with a distinct user
460 interface, primarily used interactively.</para>
463 <term>If it’s a <emphasis>version management system</emphasis>:</term>
465 <para><filename>applications/version-management</filename> (e.g. <filename>subversion</filename>)</para>
469 <term>If it’s for <emphasis>video playback / editing</emphasis>:</term>
471 <para><filename>applications/video</filename> (e.g. <filename>vlc</filename>)</para>
475 <term>If it’s for <emphasis>graphics viewing / editing</emphasis>:</term>
477 <para><filename>applications/graphics</filename> (e.g. <filename>gimp</filename>)</para>
481 <term>If it’s for <emphasis>networking</emphasis>:</term>
485 <term>If it’s a <emphasis>mailreader</emphasis>:</term>
487 <para><filename>applications/networking/mailreaders</filename> (e.g. <filename>thunderbird</filename>)</para>
491 <term>If it’s a <emphasis>newsreader</emphasis>:</term>
493 <para><filename>applications/networking/newsreaders</filename> (e.g. <filename>pan</filename>)</para>
497 <term>If it’s a <emphasis>web browser</emphasis>:</term>
499 <para><filename>applications/networking/browsers</filename> (e.g. <filename>firefox</filename>)</para>
505 <para><filename>applications/networking/misc</filename></para>
514 <para><filename>applications/misc</filename></para>
521 <term>If it’s <emphasis>data</emphasis> (i.e., does not have a
522 straight-forward executable semantics):</term>
526 <term>If it’s a <emphasis>font</emphasis>:</term>
528 <para><filename>data/fonts</filename></para>
532 <term>If it’s related to <emphasis>SGML/XML processing</emphasis>:</term>
536 <term>If it’s an <emphasis>XML DTD</emphasis>:</term>
538 <para><filename>data/sgml+xml/schemas/xml-dtd</filename> (e.g. <filename>docbook</filename>)</para>
542 <term>If it’s an <emphasis>XSLT stylesheet</emphasis>:</term>
544 <para>(Okay, these are executable...)</para>
545 <para><filename>data/sgml+xml/stylesheets/xslt</filename> (e.g. <filename>docbook-xsl</filename>)</para>
555 <term>If it’s a <emphasis>game</emphasis>:</term>
557 <para><filename>games</filename></para>
563 <para><filename>misc</filename></para>
570 <section><title>Versioning</title>
572 <para>Because every version of a package in Nixpkgs creates a
573 potential maintenance burden, old versions of a package should not be
574 kept unless there is a good reason to do so. For instance, Nixpkgs
575 contains several versions of GCC because other packages don’t build
576 with the latest version of GCC. Other examples are having both the
577 latest stable and latest pre-release version of a package, or to keep
578 several major releases of an application that differ significantly in
579 functionality.</para>
581 <para>If there is only one version of a package, its Nix expression
582 should be named <filename>e2fsprogs/default.nix</filename>. If there
583 are multiple versions, this should be reflected in the filename,
584 e.g. <filename>e2fsprogs/1.41.8.nix</filename> and
585 <filename>e2fsprogs/1.41.9.nix</filename>. The version in the
586 filename should leave out unnecessary detail. For instance, if we
587 keep the latest Firefox 2.0.x and 3.5.x versions in Nixpkgs, they
588 should be named <filename>firefox/2.0.nix</filename> and
589 <filename>firefox/3.5.nix</filename>, respectively (which, at a given
590 point, might contain versions <literal>2.0.0.20</literal> and
591 <literal>3.5.4</literal>). If a version requires many auxiliary
592 files, you can use a subdirectory for each version,
593 e.g. <filename>firefox/2.0/default.nix</filename> and
594 <filename>firefox/3.5/default.nix</filename>.</para>
596 <para>All versions of a package <emphasis>must</emphasis> be included
597 in <filename>all-packages.nix</filename> to make sure that they
598 evaluate correctly.</para>