at 15.09-beta 23 kB view raw
1<chapter xmlns="http://docbook.org/ns/docbook" 2 xmlns:xlink="http://www.w3.org/1999/xlink" 3 xml:id="chap-conventions"> 4 5<title>Coding conventions</title> 6 7 8<section xml:id="sec-syntax"><title>Syntax</title> 9 10<itemizedlist> 11 12 <listitem><para>Use 2 spaces of indentation per indentation level in 13 Nix expressions, 4 spaces in shell scripts.</para></listitem> 14 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> 19 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> 24 25 <listitem><para>Function calls with attribute set arguments are 26 written as 27 28<programlisting> 29foo { 30 arg = ...; 31} 32</programlisting> 33 34 not 35 36<programlisting> 37foo 38{ 39 arg = ...; 40} 41</programlisting> 42 43 Also fine is 44 45<programlisting> 46foo { arg = ...; } 47</programlisting> 48 49 if it's a short call.</para></listitem> 50 51 <listitem><para>In attribute sets or lists that span multiple lines, 52 the attribute names or list elements should be aligned: 53 54<programlisting> 55# A long list. 56list = 57 [ elem1 58 elem2 59 elem3 60 ]; 61 62# A long attribute set. 63attrs = 64 { attr1 = short_expr; 65 attr2 = 66 if true then big_expr else big_expr; 67 }; 68 69# Alternatively: 70attrs = { 71 attr1 = short_expr; 72 attr2 = 73 if true then big_expr else big_expr; 74}; 75</programlisting> 76 77 </para></listitem> 78 79 <listitem><para>Short lists or attribute sets can be written on one 80 line: 81 82<programlisting> 83# A short list. 84list = [ elem1 elem2 elem3 ]; 85 86# A short set. 87attrs = { x = 1280; y = 1024; }; 88</programlisting> 89 90 </para></listitem> 91 92 <listitem><para>Breaking in the middle of a function argument can 93 give hard-to-read code, like 94 95<programlisting> 96someFunction { x = 1280; 97 y = 1024; } otherArg 98 yetAnotherArg 99</programlisting> 100 101 (especially if the argument is very large, spanning multiple 102 lines).</para> 103 104 <para>Better: 105 106<programlisting> 107someFunction 108 { x = 1280; y = 1024; } 109 otherArg 110 yetAnotherArg 111</programlisting> 112 113 or 114 115<programlisting> 116let res = { x = 1280; y = 1024; }; 117in someFunction res otherArg yetAnotherArg 118</programlisting> 119 120 </para></listitem> 121 122 <listitem><para>The bodies of functions, asserts, and withs are not 123 indented to prevent a lot of superfluous indentation levels, i.e. 124 125<programlisting> 126{ arg1, arg2 }: 127assert system == "i686-linux"; 128stdenv.mkDerivation { ... 129</programlisting> 130 131 not 132 133<programlisting> 134{ arg1, arg2 }: 135 assert system == "i686-linux"; 136 stdenv.mkDerivation { ... 137</programlisting> 138 139 </para></listitem> 140 141 <listitem><para>Function formal arguments are written as: 142 143<programlisting> 144{ arg1, arg2, arg3 }: 145</programlisting> 146 147 but if they don't fit on one line they're written as: 148 149<programlisting> 150{ arg1, arg2, arg3 151, arg4, ... 152, # Some comment... 153 argN 154}: 155</programlisting> 156 157 </para></listitem> 158 159 <listitem><para>Functions should list their expected arguments as 160 precisely as possible. That is, write 161 162<programlisting> 163{ stdenv, fetchurl, perl }: <replaceable>...</replaceable> 164</programlisting> 165 166 instead of 167 168<programlisting> 169args: with args; <replaceable>...</replaceable> 170</programlisting> 171 172 or 173 174<programlisting> 175{ stdenv, fetchurl, perl, ... }: <replaceable>...</replaceable> 176</programlisting> 177 178 </para> 179 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: 184 185<programlisting> 186{ stdenv, doCoverageAnalysis ? false, ... } @ args: 187 188stdenv.mkDerivation (args // { 189 <replaceable>...</replaceable> if doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable> 190}) 191</programlisting> 192 193 instead of 194 195<programlisting> 196args: 197 198args.stdenv.mkDerivation (args // { 199 <replaceable>...</replaceable> if args ? doCoverageAnalysis &amp;&amp; args.doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable> 200}) 201</programlisting> 202 203 </para></listitem> 204 205</itemizedlist> 206 207</section> 208 209 210<section xml:id="sec-package-naming"><title>Package naming</title> 211 212<para>In Nixpkgs, there are generally three different names associated with a package: 213 214<itemizedlist> 215 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> 220 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> 226 227 <listitem><para>The filename for (the directory containing) the Nix 228 expression.</para></listitem> 229 230</itemizedlist> 231 232Most 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 235bound 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</para> 239 240<para>There are a few naming guidelines: 241 242<itemizedlist> 243 244 <listitem><para>Generally, try to stick to the upstream package 245 name.</para></listitem> 246 247 <listitem><para>Don’t use uppercase letters in the 248 <literal>name</literal> attribute — e.g., 249 <literal>"mplayer-1.0rc2"</literal> instead of 250 <literal>"MPlayer-1.0rc2"</literal>.</para></listitem> 251 252 <listitem><para>The version part of the <literal>name</literal> 253 attribute <emphasis>must</emphasis> start with a digit (following a 254 dash) — e.g., <literal>"hello-0.3-pre-r3910"</literal> instead of 255 <literal>"hello-svn-r3910"</literal>, as the latter would be seen as 256 a package named <literal>hello-svn</literal> by 257 <command>nix-env</command>.</para></listitem> 258 259 <listitem><para>If package is fetched from git's commit then 260 the version part of the name <emphasis>must</emphasis> be the date of that 261 (fetched) commit. The date must be in <literal>"YYYY-MM-DD"</literal> format. 262 Also add <literal>"git"</literal> to the name - e.g., 263 <literal>"pkgname-git-2014-09-23"</literal>.</para></listitem> 264 265 <listitem><para>Dashes in the package name should be preserved 266 in new variable names, rather than converted to underscores 267 (which was convention up to around 2013 and most names 268 still have underscores instead of dashes) — e.g., 269 <varname>http-parser</varname> instead of 270 <varname>http_parser</varname>.</para></listitem> 271 272 <listitem><para>If there are multiple versions of a package, this 273 should be reflected in the variable names in 274 <filename>all-packages.nix</filename>, 275 e.g. <varname>json-c-0-9</varname> and <varname>json-c-0-11</varname>. 276 If there is an obvious “default” version, make an attribute like 277 <literal>json-c = json-c-0-9;</literal>. 278 See also <xref linkend="sec-versioning" /></para></listitem> 279 280</itemizedlist> 281 282</para> 283 284</section> 285 286 287<section xml:id="sec-organisation"><title>File naming and organisation</title> 288 289<para>Names of files and directories should be in lowercase, with 290dashes between words — not in camel case. For instance, it should be 291<filename>all-packages.nix</filename>, not 292<filename>allPackages.nix</filename> or 293<filename>AllPackages.nix</filename>.</para> 294 295<section xml:id="sec-hierarchy"><title>Hierarchy</title> 296 297<para>Each package should be stored in its own directory somewhere in 298the <filename>pkgs/</filename> tree, i.e. in 299<filename>pkgs/<replaceable>category</replaceable>/<replaceable>subcategory</replaceable>/<replaceable>...</replaceable>/<replaceable>pkgname</replaceable></filename>. 300Below are some rules for picking the right category for a package. 301Many packages fall under several categories; what matters is the 302<emphasis>primary</emphasis> purpose of a package. For example, the 303<literal>libxml2</literal> package builds both a library and some 304tools; but it’s a library foremost, so it goes under 305<filename>pkgs/development/libraries</filename>.</para> 306 307<para>When in doubt, consider refactoring the 308<filename>pkgs/</filename> tree, e.g. creating new categories or 309splitting up an existing category.</para> 310 311<variablelist> 312 <varlistentry> 313 <term>If it’s used to support <emphasis>software development</emphasis>:</term> 314 <listitem> 315 <variablelist> 316 <varlistentry> 317 <term>If it’s a <emphasis>library</emphasis> used by other packages:</term> 318 <listitem> 319 <para><filename>development/libraries</filename> (e.g. <filename>libxml2</filename>)</para> 320 </listitem> 321 </varlistentry> 322 <varlistentry> 323 <term>If it’s a <emphasis>compiler</emphasis>:</term> 324 <listitem> 325 <para><filename>development/compilers</filename> (e.g. <filename>gcc</filename>)</para> 326 </listitem> 327 </varlistentry> 328 <varlistentry> 329 <term>If it’s an <emphasis>interpreter</emphasis>:</term> 330 <listitem> 331 <para><filename>development/interpreters</filename> (e.g. <filename>guile</filename>)</para> 332 </listitem> 333 </varlistentry> 334 <varlistentry> 335 <term>If it’s a (set of) development <emphasis>tool(s)</emphasis>:</term> 336 <listitem> 337 <variablelist> 338 <varlistentry> 339 <term>If it’s a <emphasis>parser generator</emphasis> (including lexers):</term> 340 <listitem> 341 <para><filename>development/tools/parsing</filename> (e.g. <filename>bison</filename>, <filename>flex</filename>)</para> 342 </listitem> 343 </varlistentry> 344 <varlistentry> 345 <term>If it’s a <emphasis>build manager</emphasis>:</term> 346 <listitem> 347 <para><filename>development/tools/build-managers</filename> (e.g. <filename>gnumake</filename>)</para> 348 </listitem> 349 </varlistentry> 350 <varlistentry> 351 <term>Else:</term> 352 <listitem> 353 <para><filename>development/tools/misc</filename> (e.g. <filename>binutils</filename>)</para> 354 </listitem> 355 </varlistentry> 356 </variablelist> 357 </listitem> 358 </varlistentry> 359 <varlistentry> 360 <term>Else:</term> 361 <listitem> 362 <para><filename>development/misc</filename></para> 363 </listitem> 364 </varlistentry> 365 </variablelist> 366 </listitem> 367 </varlistentry> 368 <varlistentry> 369 <term>If it’s a (set of) <emphasis>tool(s)</emphasis>:</term> 370 <listitem> 371 <para>(A tool is a relatively small program, especially one intented 372 to be used non-interactively.)</para> 373 <variablelist> 374 <varlistentry> 375 <term>If it’s for <emphasis>networking</emphasis>:</term> 376 <listitem> 377 <para><filename>tools/networking</filename> (e.g. <filename>wget</filename>)</para> 378 </listitem> 379 </varlistentry> 380 <varlistentry> 381 <term>If it’s for <emphasis>text processing</emphasis>:</term> 382 <listitem> 383 <para><filename>tools/text</filename> (e.g. <filename>diffutils</filename>)</para> 384 </listitem> 385 </varlistentry> 386 <varlistentry> 387 <term>If it’s a <emphasis>system utility</emphasis>, i.e., 388 something related or essential to the operation of a 389 system:</term> 390 <listitem> 391 <para><filename>tools/system</filename> (e.g. <filename>cron</filename>)</para> 392 </listitem> 393 </varlistentry> 394 <varlistentry> 395 <term>If it’s an <emphasis>archiver</emphasis> (which may 396 include a compression function):</term> 397 <listitem> 398 <para><filename>tools/archivers</filename> (e.g. <filename>zip</filename>, <filename>tar</filename>)</para> 399 </listitem> 400 </varlistentry> 401 <varlistentry> 402 <term>If it’s a <emphasis>compression</emphasis> program:</term> 403 <listitem> 404 <para><filename>tools/compression</filename> (e.g. <filename>gzip</filename>, <filename>bzip2</filename>)</para> 405 </listitem> 406 </varlistentry> 407 <varlistentry> 408 <term>If it’s a <emphasis>security</emphasis>-related program:</term> 409 <listitem> 410 <para><filename>tools/security</filename> (e.g. <filename>nmap</filename>, <filename>gnupg</filename>)</para> 411 </listitem> 412 </varlistentry> 413 <varlistentry> 414 <term>Else:</term> 415 <listitem> 416 <para><filename>tools/misc</filename></para> 417 </listitem> 418 </varlistentry> 419 </variablelist> 420 </listitem> 421 </varlistentry> 422 <varlistentry> 423 <term>If it’s a <emphasis>shell</emphasis>:</term> 424 <listitem> 425 <para><filename>shells</filename> (e.g. <filename>bash</filename>)</para> 426 </listitem> 427 </varlistentry> 428 <varlistentry> 429 <term>If it’s a <emphasis>server</emphasis>:</term> 430 <listitem> 431 <variablelist> 432 <varlistentry> 433 <term>If it’s a web server:</term> 434 <listitem> 435 <para><filename>servers/http</filename> (e.g. <filename>apache-httpd</filename>)</para> 436 </listitem> 437 </varlistentry> 438 <varlistentry> 439 <term>If it’s an implementation of the X Windowing System:</term> 440 <listitem> 441 <para><filename>servers/x11</filename> (e.g. <filename>xorg</filename> — this includes the client libraries and programs)</para> 442 </listitem> 443 </varlistentry> 444 <varlistentry> 445 <term>Else:</term> 446 <listitem> 447 <para><filename>servers/misc</filename></para> 448 </listitem> 449 </varlistentry> 450 </variablelist> 451 </listitem> 452 </varlistentry> 453 <varlistentry> 454 <term>If it’s a <emphasis>desktop environment</emphasis>:</term> 455 <listitem> 456 <para><filename>desktops</filename> (e.g. <filename>kde</filename>, <filename>gnome</filename>, <filename>enlightenment</filename>)</para> 457 </listitem> 458 </varlistentry> 459 <varlistentry> 460 <term>If it’s a <emphasis>window manager</emphasis>:</term> 461 <listitem> 462 <para><filename>applications/window-managers</filename> (e.g. <filename>awesome</filename>, <filename>compiz</filename>, <filename>stumpwm</filename>)</para> 463 </listitem> 464 </varlistentry> 465 <varlistentry> 466 <term>If it’s an <emphasis>application</emphasis>:</term> 467 <listitem> 468 <para>A (typically large) program with a distinct user 469 interface, primarily used interactively.</para> 470 <variablelist> 471 <varlistentry> 472 <term>If it’s a <emphasis>version management system</emphasis>:</term> 473 <listitem> 474 <para><filename>applications/version-management</filename> (e.g. <filename>subversion</filename>)</para> 475 </listitem> 476 </varlistentry> 477 <varlistentry> 478 <term>If it’s for <emphasis>video playback / editing</emphasis>:</term> 479 <listitem> 480 <para><filename>applications/video</filename> (e.g. <filename>vlc</filename>)</para> 481 </listitem> 482 </varlistentry> 483 <varlistentry> 484 <term>If it’s for <emphasis>graphics viewing / editing</emphasis>:</term> 485 <listitem> 486 <para><filename>applications/graphics</filename> (e.g. <filename>gimp</filename>)</para> 487 </listitem> 488 </varlistentry> 489 <varlistentry> 490 <term>If it’s for <emphasis>networking</emphasis>:</term> 491 <listitem> 492 <variablelist> 493 <varlistentry> 494 <term>If it’s a <emphasis>mailreader</emphasis>:</term> 495 <listitem> 496 <para><filename>applications/networking/mailreaders</filename> (e.g. <filename>thunderbird</filename>)</para> 497 </listitem> 498 </varlistentry> 499 <varlistentry> 500 <term>If it’s a <emphasis>newsreader</emphasis>:</term> 501 <listitem> 502 <para><filename>applications/networking/newsreaders</filename> (e.g. <filename>pan</filename>)</para> 503 </listitem> 504 </varlistentry> 505 <varlistentry> 506 <term>If it’s a <emphasis>web browser</emphasis>:</term> 507 <listitem> 508 <para><filename>applications/networking/browsers</filename> (e.g. <filename>firefox</filename>)</para> 509 </listitem> 510 </varlistentry> 511 <varlistentry> 512 <term>Else:</term> 513 <listitem> 514 <para><filename>applications/networking/misc</filename></para> 515 </listitem> 516 </varlistentry> 517 </variablelist> 518 </listitem> 519 </varlistentry> 520 <varlistentry> 521 <term>Else:</term> 522 <listitem> 523 <para><filename>applications/misc</filename></para> 524 </listitem> 525 </varlistentry> 526 </variablelist> 527 </listitem> 528 </varlistentry> 529 <varlistentry> 530 <term>If it’s <emphasis>data</emphasis> (i.e., does not have a 531 straight-forward executable semantics):</term> 532 <listitem> 533 <variablelist> 534 <varlistentry> 535 <term>If it’s a <emphasis>font</emphasis>:</term> 536 <listitem> 537 <para><filename>data/fonts</filename></para> 538 </listitem> 539 </varlistentry> 540 <varlistentry> 541 <term>If it’s related to <emphasis>SGML/XML processing</emphasis>:</term> 542 <listitem> 543 <variablelist> 544 <varlistentry> 545 <term>If it’s an <emphasis>XML DTD</emphasis>:</term> 546 <listitem> 547 <para><filename>data/sgml+xml/schemas/xml-dtd</filename> (e.g. <filename>docbook</filename>)</para> 548 </listitem> 549 </varlistentry> 550 <varlistentry> 551 <term>If it’s an <emphasis>XSLT stylesheet</emphasis>:</term> 552 <listitem> 553 <para>(Okay, these are executable...)</para> 554 <para><filename>data/sgml+xml/stylesheets/xslt</filename> (e.g. <filename>docbook-xsl</filename>)</para> 555 </listitem> 556 </varlistentry> 557 </variablelist> 558 </listitem> 559 </varlistentry> 560 </variablelist> 561 </listitem> 562 </varlistentry> 563 <varlistentry> 564 <term>If it’s a <emphasis>game</emphasis>:</term> 565 <listitem> 566 <para><filename>games</filename></para> 567 </listitem> 568 </varlistentry> 569 <varlistentry> 570 <term>Else:</term> 571 <listitem> 572 <para><filename>misc</filename></para> 573 </listitem> 574 </varlistentry> 575</variablelist> 576 577</section> 578 579<section xml:id="sec-versioning"><title>Versioning</title> 580 581<para>Because every version of a package in Nixpkgs creates a 582potential maintenance burden, old versions of a package should not be 583kept unless there is a good reason to do so. For instance, Nixpkgs 584contains several versions of GCC because other packages don’t build 585with the latest version of GCC. Other examples are having both the 586latest stable and latest pre-release version of a package, or to keep 587several major releases of an application that differ significantly in 588functionality.</para> 589 590<para>If there is only one version of a package, its Nix expression 591should be named <filename>e2fsprogs/default.nix</filename>. If there 592are multiple versions, this should be reflected in the filename, 593e.g. <filename>e2fsprogs/1.41.8.nix</filename> and 594<filename>e2fsprogs/1.41.9.nix</filename>. The version in the 595filename should leave out unnecessary detail. For instance, if we 596keep the latest Firefox 2.0.x and 3.5.x versions in Nixpkgs, they 597should be named <filename>firefox/2.0.nix</filename> and 598<filename>firefox/3.5.nix</filename>, respectively (which, at a given 599point, might contain versions <literal>2.0.0.20</literal> and 600<literal>3.5.4</literal>). If a version requires many auxiliary 601files, you can use a subdirectory for each version, 602e.g. <filename>firefox/2.0/default.nix</filename> and 603<filename>firefox/3.5/default.nix</filename>.</para> 604 605<para>All versions of a package <emphasis>must</emphasis> be included 606in <filename>all-packages.nix</filename> to make sure that they 607evaluate correctly.</para> 608 609</section> 610 611</section> 612<section xml:id="sec-sources"><title>Fetching Sources</title> 613 <para>There are multiple ways to fetch a package source in nixpkgs. The 614 general guidline is that you should package sources with a high degree of 615 availability. Right now there is only one fetcher which has mirroring 616 support and that is <literal>fetchurl</literal>. Note that you should also 617 prefer protocols which have a corresponding proxy environment variable. 618 </para> 619 <para>You can find many source fetch helpers in <literal>pkgs/build-support/fetch*</literal>. 620 </para> 621 <para>In the file <literal>pkgs/top-level/all-packages.nix</literal> you can 622 find fetch helpers, these have names on the form 623 <literal>fetchFrom*</literal>. The intention of these are to provide 624 snapshot fetches but using the same api as some of the version controlled 625 fetchers from <literal>pkgs/build-support/</literal>. As an example going 626 from bad to good: 627 <itemizedlist> 628 <listitem> 629 <para>Uses <literal>git://</literal> which won't be proxied. 630<programlisting> 631src = fetchgit { 632 url = "git://github.com/NixOS/nix.git"; 633 rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae"; 634 sha256 = "1cw5fszffl5pkpa6s6wjnkiv6lm5k618s32sp60kvmvpy7a2v9kg"; 635} 636</programlisting> 637 </para> 638 </listitem> 639 <listitem> 640 <para>This is ok, but an archive fetch will still be faster. 641<programlisting> 642src = fetchgit { 643 url = "https://github.com/NixOS/nix.git"; 644 rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae"; 645 sha256 = "1cw5fszffl5pkpa6s6wjnkiv6lm5k618s32sp60kvmvpy7a2v9kg"; 646} 647</programlisting> 648 </para> 649 </listitem> 650 <listitem> 651 <para>Fetches a snapshot archive and you get the rev you want. 652<programlisting> 653src = fetchFromGitHub { 654 owner = "NixOS"; 655 repo = "nix"; 656 rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae"; 657 sha256 = "04yri911rj9j19qqqn6m82266fl05pz98inasni0vxr1cf1gdgv9"; 658} 659</programlisting> 660 </para> 661 </listitem> 662 </itemizedlist> 663 </para> 664</section> 665</chapter>