Fix for r29513
[NixPkgs.git] / doc / coding-conventions.xml
blobe55f86ae3d31f92719bba105b4a38a0cdc0f57b0
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>
10 <itemizedlist>
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
22   attributes in
23   <filename>all-packages.nix</filename>?</para></listitem>
25   <listitem><para>Function calls with attribute set arguments are
26   written as
28 <programlisting>
29 foo {
30   arg = ...;
32 </programlisting>
34   not
36 <programlisting>
37 foo
39   arg = ...;
41 </programlisting>
43   Also fine is
45 <programlisting>
46 foo { arg = ...; }
47 </programlisting>
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:
54 <programlisting>
55 # A long list.
56 list =
57   [ elem1
58     elem2
59     elem3
60   ];
62 # A long attribute set.
63 attrs =
64   { attr1 = short_expr;
65     attr2 =
66       if true then big_expr else big_expr;
67   };
69 # Alternatively:
70 attrs = {
71   attr1 = short_expr;
72   attr2 =
73     if true then big_expr else big_expr;
75 </programlisting>
77   </para></listitem>
79   <listitem><para>Short lists or attribute sets can be written on one
80   line:
82 <programlisting>
83 # A short list.
84 list = [ elem1 elem2 elem3 ];
86 # A short set.
87 attrs = { x = 1280; y = 1024; };
88 </programlisting>
90   </para></listitem>
92   <listitem><para>Breaking in the middle of a function argument can
93   give hard-to-read code, like
95 <programlisting>
96 someFunction { x = 1280;
97   y = 1024; } otherArg
98   yetAnotherArg
99 </programlisting>
101   (especially if the argument is very large, spanning multiple
102   lines).</para>
104   <para>Better:
106 <programlisting>
107 someFunction
108   { x = 1280; y = 1024; }
109   otherArg
110   yetAnotherArg
111 </programlisting>
113   or
115 <programlisting>
116 let res = { x = 1280; y = 1024; };
117 in someFunction res otherArg yetAnotherArg
118 </programlisting>
120   </para></listitem>
122   <listitem><para>The bodies of functions, asserts, and withs are not
123   indented to prevent a lot of superfluous indentation levels, i.e.
125 <programlisting>
126 { arg1, arg2 }:
127 assert system == "i686-linux";
128 stdenv.mkDerivation { ...
129 </programlisting>
131   not
133 <programlisting>
134 { arg1, arg2 }:
135   assert system == "i686-linux";
136     stdenv.mkDerivation { ...
137 </programlisting>
139   </para></listitem>
141   <listitem><para>Function formal arguments are written as:
143 <programlisting>
144 { arg1, arg2, arg3 }:
145 </programlisting>
147   but if they don't fit on one line they're written as:
149 <programlisting>
150 { arg1, arg2, arg3
151 , arg4, ...
152 , # Some comment...
153   argN
155 </programlisting>
157   </para></listitem>
159   <listitem><para>Functions should list their expected arguments as
160   precisely as possible.  That is, write
162 <programlisting>
163 { stdenv, fetchurl, perl }: <replaceable>...</replaceable>
164 </programlisting>
166   instead of
168 <programlisting>
169 args: with args; <replaceable>...</replaceable>
170 </programlisting>
172   or 
173   
174 <programlisting>
175 { stdenv, fetchurl, perl, ... }: <replaceable>...</replaceable>
176 </programlisting>
178   </para>
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:
185 <programlisting>
186 { stdenv, doCoverageAnalysis ? false, ... } @ args:
188 stdenv.mkDerivation (args // {
189   <replaceable>...</replaceable> if doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable>
191 </programlisting>
193   instead of
195 <programlisting>
196 args:
198 args.stdenv.mkDerivation (args // {
199   <replaceable>...</replaceable> if args ? doCoverageAnalysis &amp;&amp; args.doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable>
201 </programlisting>
203   </para></listitem>
205 </itemizedlist>
207 </section>
210 <section><title>Package naming</title>
212 <para>In Nixpkgs, there are generally three different names associated with a package:
214 <itemizedlist>
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>
230 </itemizedlist>
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:
247 <itemizedlist>
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>
276 </itemizedlist>
278 </para>
280 </section>
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>
307 <variablelist>
308   <varlistentry>
309     <term>If it’s used to support <emphasis>software development</emphasis>:</term>
310     <listitem>
311       <variablelist>
312         <varlistentry>
313           <term>If it’s a <emphasis>library</emphasis> used by other packages:</term>
314           <listitem>
315             <para><filename>development/libraries</filename> (e.g. <filename>libxml2</filename>)</para>
316           </listitem>
317         </varlistentry>
318         <varlistentry>
319           <term>If it’s a <emphasis>compiler</emphasis>:</term>
320           <listitem>
321             <para><filename>development/compilers</filename> (e.g. <filename>gcc</filename>)</para>
322           </listitem>
323         </varlistentry>
324         <varlistentry>
325           <term>If it’s an <emphasis>interpreter</emphasis>:</term>
326           <listitem>
327             <para><filename>development/interpreters</filename> (e.g. <filename>guile</filename>)</para>
328           </listitem>
329         </varlistentry>
330         <varlistentry>
331           <term>If it’s a (set of) development <emphasis>tool(s)</emphasis>:</term>
332           <listitem>
333             <variablelist>
334               <varlistentry>
335                 <term>If it’s a <emphasis>parser generator</emphasis> (including lexers):</term>
336                 <listitem>
337                   <para><filename>development/tools/parsing</filename> (e.g. <filename>bison</filename>, <filename>flex</filename>)</para>
338                 </listitem>
339               </varlistentry>
340               <varlistentry>
341                 <term>If it’s a <emphasis>build manager</emphasis>:</term>
342                 <listitem>
343                   <para><filename>development/tools/build-managers</filename> (e.g. <filename>gnumake</filename>)</para>
344                 </listitem>
345               </varlistentry>
346               <varlistentry>
347                 <term>Else:</term>
348                 <listitem>
349                   <para><filename>development/tools/misc</filename> (e.g. <filename>binutils</filename>)</para>
350                 </listitem>
351               </varlistentry>
352             </variablelist>
353           </listitem>
354         </varlistentry>
355         <varlistentry>
356           <term>Else:</term>
357           <listitem>
358             <para><filename>development/misc</filename></para>
359           </listitem>
360         </varlistentry>
361       </variablelist>
362     </listitem>
363   </varlistentry>
364   <varlistentry>
365     <term>If it’s a (set of) <emphasis>tool(s)</emphasis>:</term>
366     <listitem>
367       <para>(A tool is a relatively small program, especially one intented
368       to be used non-interactively.)</para>
369       <variablelist>
370         <varlistentry>
371           <term>If it’s for <emphasis>networking</emphasis>:</term>
372           <listitem>
373             <para><filename>tools/networking</filename> (e.g. <filename>wget</filename>)</para>
374           </listitem>
375         </varlistentry>
376         <varlistentry>
377           <term>If it’s for <emphasis>text processing</emphasis>:</term>
378           <listitem>
379             <para><filename>tools/text</filename> (e.g. <filename>diffutils</filename>)</para>
380           </listitem>
381         </varlistentry>
382         <varlistentry>
383           <term>If it’s a <emphasis>system utility</emphasis>, i.e.,
384           something related or essential to the operation of a
385           system:</term>
386           <listitem>
387             <para><filename>tools/system</filename> (e.g. <filename>cron</filename>)</para>
388           </listitem>
389         </varlistentry>
390         <varlistentry>
391           <term>If it’s an <emphasis>archiver</emphasis> (which may
392           include a compression function):</term>
393           <listitem>
394             <para><filename>tools/archivers</filename> (e.g. <filename>zip</filename>, <filename>tar</filename>)</para>
395           </listitem>
396         </varlistentry>
397         <varlistentry>
398           <term>If it’s a <emphasis>compression</emphasis> program:</term>
399           <listitem>
400             <para><filename>tools/compression</filename> (e.g. <filename>gzip</filename>, <filename>bzip2</filename>)</para>
401           </listitem>
402         </varlistentry>
403         <varlistentry>
404           <term>If it’s a <emphasis>security</emphasis>-related program:</term>
405           <listitem>
406             <para><filename>tools/security</filename> (e.g. <filename>nmap</filename>, <filename>gnupg</filename>)</para>
407           </listitem>
408         </varlistentry>
409         <varlistentry>
410           <term>Else:</term>
411           <listitem>
412             <para><filename>tools/misc</filename></para>
413           </listitem>
414         </varlistentry>
415       </variablelist>
416     </listitem>
417   </varlistentry>
418   <varlistentry>
419     <term>If it’s a <emphasis>shell</emphasis>:</term>
420     <listitem>
421       <para><filename>shells</filename> (e.g. <filename>bash</filename>)</para>
422     </listitem>
423   </varlistentry>
424   <varlistentry>
425     <term>If it’s a <emphasis>server</emphasis>:</term>
426     <listitem>
427       <variablelist>
428         <varlistentry>
429           <term>If it’s a web server:</term>
430           <listitem>
431             <para><filename>servers/http</filename> (e.g. <filename>apache-httpd</filename>)</para>
432           </listitem>
433         </varlistentry>
434         <varlistentry>
435           <term>If it’s an implementation of the X Windowing System:</term>
436           <listitem>
437             <para><filename>servers/x11</filename> (e.g. <filename>xorg</filename> — this includes the client libraries and programs)</para>
438           </listitem>
439         </varlistentry>
440         <varlistentry>
441           <term>Else:</term>
442           <listitem>
443             <para><filename>servers/misc</filename></para>
444           </listitem>
445         </varlistentry>
446       </variablelist>
447     </listitem>
448   </varlistentry>
449   <varlistentry>
450     <term>If it’s a <emphasis>desktop environment</emphasis>
451     (including <emphasis>window managers</emphasis>):</term>
452     <listitem>
453       <para><filename>desktops</filename> (e.g. <filename>kde</filename>, <filename>gnome</filename>, <filename>enlightenment</filename>)</para>
454     </listitem>
455   </varlistentry>
456   <varlistentry>
457     <term>If it’s an <emphasis>application</emphasis>:</term>
458     <listitem>
459       <para>A (typically large) program with a distinct user
460       interface, primarily used interactively.</para>
461       <variablelist>
462         <varlistentry>
463           <term>If it’s a <emphasis>version management system</emphasis>:</term>
464           <listitem>
465             <para><filename>applications/version-management</filename> (e.g. <filename>subversion</filename>)</para>
466           </listitem>
467         </varlistentry>
468         <varlistentry>
469           <term>If it’s for <emphasis>video playback / editing</emphasis>:</term>
470           <listitem>
471             <para><filename>applications/video</filename> (e.g. <filename>vlc</filename>)</para>
472           </listitem>
473         </varlistentry>
474         <varlistentry>
475           <term>If it’s for <emphasis>graphics viewing / editing</emphasis>:</term>
476           <listitem>
477             <para><filename>applications/graphics</filename> (e.g. <filename>gimp</filename>)</para>
478           </listitem>
479         </varlistentry>
480         <varlistentry>
481           <term>If it’s for <emphasis>networking</emphasis>:</term>
482           <listitem>
483             <variablelist>
484               <varlistentry>
485                 <term>If it’s a <emphasis>mailreader</emphasis>:</term>
486                 <listitem>
487                   <para><filename>applications/networking/mailreaders</filename> (e.g. <filename>thunderbird</filename>)</para>
488                 </listitem>
489               </varlistentry>
490               <varlistentry>
491                 <term>If it’s a <emphasis>newsreader</emphasis>:</term>
492                 <listitem>
493                   <para><filename>applications/networking/newsreaders</filename> (e.g. <filename>pan</filename>)</para>
494                 </listitem>
495               </varlistentry>
496               <varlistentry>
497                 <term>If it’s a <emphasis>web browser</emphasis>:</term>
498                 <listitem>
499                   <para><filename>applications/networking/browsers</filename> (e.g. <filename>firefox</filename>)</para>
500                 </listitem>
501               </varlistentry>
502               <varlistentry>
503                 <term>Else:</term>
504                 <listitem>
505                   <para><filename>applications/networking/misc</filename></para>
506                 </listitem>
507               </varlistentry>
508             </variablelist>
509           </listitem>
510         </varlistentry>
511         <varlistentry>
512           <term>Else:</term>
513           <listitem>
514             <para><filename>applications/misc</filename></para>
515           </listitem>
516         </varlistentry>
517       </variablelist>
518     </listitem>
519   </varlistentry>
520   <varlistentry>
521     <term>If it’s <emphasis>data</emphasis> (i.e., does not have a
522     straight-forward executable semantics):</term>
523     <listitem>
524       <variablelist>
525         <varlistentry>
526           <term>If it’s a <emphasis>font</emphasis>:</term>
527           <listitem>
528             <para><filename>data/fonts</filename></para>
529           </listitem>
530         </varlistentry>
531         <varlistentry>
532           <term>If it’s related to <emphasis>SGML/XML processing</emphasis>:</term>
533           <listitem>
534             <variablelist>
535               <varlistentry>
536                 <term>If it’s an <emphasis>XML DTD</emphasis>:</term>
537                 <listitem>
538                   <para><filename>data/sgml+xml/schemas/xml-dtd</filename> (e.g. <filename>docbook</filename>)</para>
539                 </listitem>
540               </varlistentry>
541               <varlistentry>
542                 <term>If it’s an <emphasis>XSLT stylesheet</emphasis>:</term>
543                 <listitem>
544                   <para>(Okay, these are executable...)</para>
545                   <para><filename>data/sgml+xml/stylesheets/xslt</filename> (e.g. <filename>docbook-xsl</filename>)</para>
546                 </listitem>
547               </varlistentry>
548             </variablelist>
549           </listitem>
550         </varlistentry>
551       </variablelist>
552     </listitem>
553   </varlistentry>
554   <varlistentry>
555     <term>If it’s a <emphasis>game</emphasis>:</term>
556     <listitem>
557       <para><filename>games</filename></para>
558     </listitem>
559   </varlistentry>
560   <varlistentry>
561     <term>Else:</term>
562     <listitem>
563       <para><filename>misc</filename></para>
564     </listitem>
565   </varlistentry>
566 </variablelist>
568 </section>
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>
600 </section>
602 </section>
605 </chapter>