1# Coding conventions {#chap-conventions}
2
3## Syntax {#sec-syntax}
4
5- Use 2 spaces of indentation per indentation level in Nix expressions, 4 spaces in shell scripts.
6
7- Do not use tab characters, i.e. configure your editor to use soft tabs. For instance, use `(setq-default indent-tabs-mode nil)` in Emacs. Everybody has different tab settings so it’s asking for trouble.
8
9- Use `lowerCamelCase` for variable names, not `UpperCamelCase`. Note, this rule does not apply to package attribute names, which instead follow the rules in [](#sec-package-naming).
10
11- Function calls with attribute set arguments are written as
12
13 ```nix
14 foo {
15 arg = ...;
16 }
17 ```
18
19 not
20
21 ```nix
22 foo
23 {
24 arg = ...;
25 }
26 ```
27
28 Also fine is
29
30 ```nix
31 foo { arg = ...; }
32 ```
33
34 if it's a short call.
35
36- In attribute sets or lists that span multiple lines, the attribute names or list elements should be aligned:
37
38 ```nix
39 # A long list.
40 list = [
41 elem1
42 elem2
43 elem3
44 ];
45
46 # A long attribute set.
47 attrs = {
48 attr1 = short_expr;
49 attr2 =
50 if true then big_expr else big_expr;
51 };
52
53 # Combined
54 listOfAttrs = [
55 {
56 attr1 = 3;
57 attr2 = "fff";
58 }
59 {
60 attr1 = 5;
61 attr2 = "ggg";
62 }
63 ];
64 ```
65
66- Short lists or attribute sets can be written on one line:
67
68 ```nix
69 # A short list.
70 list = [ elem1 elem2 elem3 ];
71
72 # A short set.
73 attrs = { x = 1280; y = 1024; };
74 ```
75
76- Breaking in the middle of a function argument can give hard-to-read code, like
77
78 ```nix
79 someFunction { x = 1280;
80 y = 1024; } otherArg
81 yetAnotherArg
82 ```
83
84 (especially if the argument is very large, spanning multiple lines).
85
86 Better:
87
88 ```nix
89 someFunction
90 { x = 1280; y = 1024; }
91 otherArg
92 yetAnotherArg
93 ```
94
95 or
96
97 ```nix
98 let res = { x = 1280; y = 1024; };
99 in someFunction res otherArg yetAnotherArg
100 ```
101
102- The bodies of functions, asserts, and withs are not indented to prevent a lot of superfluous indentation levels, i.e.
103
104 ```nix
105 { arg1, arg2 }:
106 assert system == "i686-linux";
107 stdenv.mkDerivation { ...
108 ```
109
110 not
111
112 ```nix
113 { arg1, arg2 }:
114 assert system == "i686-linux";
115 stdenv.mkDerivation { ...
116 ```
117
118- Function formal arguments are written as:
119
120 ```nix
121 { arg1, arg2, arg3 }:
122 ```
123
124 but if they don't fit on one line they're written as:
125
126 ```nix
127 { arg1, arg2, arg3
128 , arg4, ...
129 , # Some comment...
130 argN
131 }:
132 ```
133
134- Functions should list their expected arguments as precisely as possible. That is, write
135
136 ```nix
137 { stdenv, fetchurl, perl }: ...
138 ```
139
140 instead of
141
142 ```nix
143 args: with args; ...
144 ```
145
146 or
147
148 ```nix
149 { stdenv, fetchurl, perl, ... }: ...
150 ```
151
152 For functions that are truly generic in the number of arguments (such as wrappers around `mkDerivation`) that have some required arguments, you should write them using an `@`-pattern:
153
154 ```nix
155 { stdenv, doCoverageAnalysis ? false, ... } @ args:
156
157 stdenv.mkDerivation (args // {
158 ... if doCoverageAnalysis then "bla" else "" ...
159 })
160 ```
161
162 instead of
163
164 ```nix
165 args:
166
167 args.stdenv.mkDerivation (args // {
168 ... if args ? doCoverageAnalysis && args.doCoverageAnalysis then "bla" else "" ...
169 })
170 ```
171
172- Unnecessary string conversions should be avoided. Do
173
174 ```nix
175 rev = version;
176 ```
177
178 instead of
179
180 ```nix
181 rev = "${version}";
182 ```
183
184- Building lists conditionally _should_ be done with `lib.optional(s)` instead of using `if cond then [ ... ] else null` or `if cond then [ ... ] else [ ]`.
185
186 ```nix
187 buildInputs = lib.optional stdenv.isDarwin iconv;
188 ```
189
190 instead of
191
192 ```nix
193 buildInputs = if stdenv.isDarwin then [ iconv ] else null;
194 ```
195
196 As an exception, an explicit conditional expression with null can be used when fixing a important bug without triggering a mass rebuild.
197 If this is done a follow up pull request _should_ be created to change the code to `lib.optional(s)`.
198
199- Arguments should be listed in the order they are used, with the exception of `lib`, which always goes first.
200
201## Package naming {#sec-package-naming}
202
203The key words _must_, _must not_, _required_, _shall_, _shall not_, _should_, _should not_, _recommended_, _may_, and _optional_ in this section are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). Only _emphasized_ words are to be interpreted in this way.
204
205In Nixpkgs, there are generally three different names associated with a package:
206
207- The `name` attribute of the derivation (excluding the version part). This is what most users see, in particular when using `nix-env`.
208
209- The variable name used for the instantiated package in `all-packages.nix`, and when passing it as a dependency to other functions. Typically this is called the _package attribute name_. This is what Nix expression authors see. It can also be used when installing using `nix-env -iA`.
210
211- The filename for (the directory containing) the Nix expression.
212
213Most of the time, these are the same. For instance, the package `e2fsprogs` has a `name` attribute `"e2fsprogs-version"`, is bound to the variable name `e2fsprogs` in `all-packages.nix`, and the Nix expression is in `pkgs/os-specific/linux/e2fsprogs/default.nix`.
214
215There are a few naming guidelines:
216
217- The `name` attribute _should_ be identical to the upstream package name.
218
219- The `name` attribute _must not_ contain uppercase letters — e.g., `"mplayer-1.0rc2"` instead of `"MPlayer-1.0rc2"`.
220
221- The version part of the `name` attribute _must_ start with a digit (following a dash) — e.g., `"hello-0.3.1rc2"`.
222
223- If a package is not a release but a commit from a repository, then the version part of the name _must_ be the date of that (fetched) commit. The date _must_ be in `"YYYY-MM-DD"` format. Also append `"unstable"` to the name - e.g., `"pkgname-unstable-2014-09-23"`.
224
225- Dashes in the package name _should_ be preserved in new variable names, rather than converted to underscores or camel cased — e.g., `http-parser` instead of `http_parser` or `httpParser`. The hyphenated style is preferred in all three package names.
226
227- If there are multiple versions of a package, this _should_ be reflected in the variable names in `all-packages.nix`, e.g. `json-c-0-9` and `json-c-0-11`. If there is an obvious “default” version, make an attribute like `json-c = json-c-0-9;`. See also [](#sec-versioning)
228
229## File naming and organisation {#sec-organisation}
230
231Names of files and directories should be in lowercase, with dashes between words — not in camel case. For instance, it should be `all-packages.nix`, not `allPackages.nix` or `AllPackages.nix`.
232
233### Hierarchy {#sec-hierarchy}
234
235Each package should be stored in its own directory somewhere in the `pkgs/` tree, i.e. in `pkgs/category/subcategory/.../pkgname`. Below are some rules for picking the right category for a package. Many packages fall under several categories; what matters is the _primary_ purpose of a package. For example, the `libxml2` package builds both a library and some tools; but it’s a library foremost, so it goes under `pkgs/development/libraries`.
236
237When in doubt, consider refactoring the `pkgs/` tree, e.g. creating new categories or splitting up an existing category.
238
239**If it’s used to support _software development_:**
240
241- **If it’s a _library_ used by other packages:**
242
243 - `development/libraries` (e.g. `libxml2`)
244
245- **If it’s a _compiler_:**
246
247 - `development/compilers` (e.g. `gcc`)
248
249- **If it’s an _interpreter_:**
250
251 - `development/interpreters` (e.g. `guile`)
252
253- **If it’s a (set of) development _tool(s)_:**
254
255 - **If it’s a _parser generator_ (including lexers):**
256
257 - `development/tools/parsing` (e.g. `bison`, `flex`)
258
259 - **If it’s a _build manager_:**
260
261 - `development/tools/build-managers` (e.g. `gnumake`)
262
263 - **Else:**
264
265 - `development/tools/misc` (e.g. `binutils`)
266
267- **Else:**
268
269 - `development/misc`
270
271**If it’s a (set of) _tool(s)_:**
272
273(A tool is a relatively small program, especially one intended to be used non-interactively.)
274
275- **If it’s for _networking_:**
276
277 - `tools/networking` (e.g. `wget`)
278
279- **If it’s for _text processing_:**
280
281 - `tools/text` (e.g. `diffutils`)
282
283- **If it’s a _system utility_, i.e., something related or essential to the operation of a system:**
284
285 - `tools/system` (e.g. `cron`)
286
287- **If it’s an _archiver_ (which may include a compression function):**
288
289 - `tools/archivers` (e.g. `zip`, `tar`)
290
291- **If it’s a _compression_ program:**
292
293 - `tools/compression` (e.g. `gzip`, `bzip2`)
294
295- **If it’s a _security_-related program:**
296
297 - `tools/security` (e.g. `nmap`, `gnupg`)
298
299- **Else:**
300
301 - `tools/misc`
302
303**If it’s a _shell_:**
304
305- `shells` (e.g. `bash`)
306
307**If it’s a _server_:**
308
309- **If it’s a web server:**
310
311 - `servers/http` (e.g. `apache-httpd`)
312
313- **If it’s an implementation of the X Windowing System:**
314
315 - `servers/x11` (e.g. `xorg` — this includes the client libraries and programs)
316
317- **Else:**
318
319 - `servers/misc`
320
321**If it’s a _desktop environment_:**
322
323- `desktops` (e.g. `kde`, `gnome`, `enlightenment`)
324
325**If it’s a _window manager_:**
326
327- `applications/window-managers` (e.g. `awesome`, `stumpwm`)
328
329**If it’s an _application_:**
330
331A (typically large) program with a distinct user interface, primarily used interactively.
332
333- **If it’s a _version management system_:**
334
335 - `applications/version-management` (e.g. `subversion`)
336
337- **If it’s a _terminal emulator_:**
338
339 - `applications/terminal-emulators` (e.g. `alacritty` or `rxvt` or `termite`)
340
341- **If it’s for _video playback / editing_:**
342
343 - `applications/video` (e.g. `vlc`)
344
345- **If it’s for _graphics viewing / editing_:**
346
347 - `applications/graphics` (e.g. `gimp`)
348
349- **If it’s for _networking_:**
350
351 - **If it’s a _mailreader_:**
352
353 - `applications/networking/mailreaders` (e.g. `thunderbird`)
354
355 - **If it’s a _newsreader_:**
356
357 - `applications/networking/newsreaders` (e.g. `pan`)
358
359 - **If it’s a _web browser_:**
360
361 - `applications/networking/browsers` (e.g. `firefox`)
362
363 - **Else:**
364
365 - `applications/networking/misc`
366
367- **Else:**
368
369 - `applications/misc`
370
371**If it’s _data_ (i.e., does not have a straight-forward executable semantics):**
372
373- **If it’s a _font_:**
374
375 - `data/fonts`
376
377- **If it’s an _icon theme_:**
378
379 - `data/icons`
380
381- **If it’s related to _SGML/XML processing_:**
382
383 - **If it’s an _XML DTD_:**
384
385 - `data/sgml+xml/schemas/xml-dtd` (e.g. `docbook`)
386
387 - **If it’s an _XSLT stylesheet_:**
388
389 (Okay, these are executable...)
390
391 - `data/sgml+xml/stylesheets/xslt` (e.g. `docbook-xsl`)
392
393- **If it’s a _theme_ for a _desktop environment_, a _window manager_ or a _display manager_:**
394
395 - `data/themes`
396
397**If it’s a _game_:**
398
399- `games`
400
401**Else:**
402
403- `misc`
404
405### Versioning {#sec-versioning}
406
407Because 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.
408
409If there is only one version of a package, its Nix expression should be named `e2fsprogs/default.nix`. If there are multiple versions, this should be reflected in the filename, e.g. `e2fsprogs/1.41.8.nix` and `e2fsprogs/1.41.9.nix`. 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 `firefox/2.0.nix` and `firefox/3.5.nix`, respectively (which, at a given point, might contain versions `2.0.0.20` and `3.5.4`). If a version requires many auxiliary files, you can use a subdirectory for each version, e.g. `firefox/2.0/default.nix` and `firefox/3.5/default.nix`.
410
411All versions of a package _must_ be included in `all-packages.nix` to make sure that they evaluate correctly.
412
413## Fetching Sources {#sec-sources}
414
415There are multiple ways to fetch a package source in nixpkgs. The general guideline is that you should package reproducible sources with a high degree of availability. Right now there is only one fetcher which has mirroring support and that is `fetchurl`. Note that you should also prefer protocols which have a corresponding proxy environment variable.
416
417You can find many source fetch helpers in `pkgs/build-support/fetch*`.
418
419In the file `pkgs/top-level/all-packages.nix` you can find fetch helpers, these have names on the form `fetchFrom*`. The intention of these are to provide snapshot fetches but using the same api as some of the version controlled fetchers from `pkgs/build-support/`. As an example going from bad to good:
420
421- Bad: Uses `git://` which won't be proxied.
422
423 ```nix
424 src = fetchgit {
425 url = "git://github.com/NixOS/nix.git";
426 rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
427 sha256 = "1cw5fszffl5pkpa6s6wjnkiv6lm5k618s32sp60kvmvpy7a2v9kg";
428 }
429 ```
430
431- Better: This is ok, but an archive fetch will still be faster.
432
433 ```nix
434 src = fetchgit {
435 url = "https://github.com/NixOS/nix.git";
436 rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
437 sha256 = "1cw5fszffl5pkpa6s6wjnkiv6lm5k618s32sp60kvmvpy7a2v9kg";
438 }
439 ```
440
441- Best: Fetches a snapshot archive and you get the rev you want.
442
443 ```nix
444 src = fetchFromGitHub {
445 owner = "NixOS";
446 repo = "nix";
447 rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
448 sha256 = "1i2yxndxb6yc9l6c99pypbd92lfq5aac4klq7y2v93c9qvx2cgpc";
449 }
450 ```
451
452 Find the value to put as `sha256` by running `nix run -f '<nixpkgs>' nix-prefetch-github -c nix-prefetch-github --rev 1f795f9f44607cc5bec70d1300150bfefcef2aae NixOS nix` or `nix-prefetch-url --unpack https://github.com/NixOS/nix/archive/1f795f9f44607cc5bec70d1300150bfefcef2aae.tar.gz`.
453
454## Obtaining source hash {#sec-source-hashes}
455
456Preferred source hash type is sha256. There are several ways to get it.
457
4581. Prefetch URL (with `nix-prefetch-XXX URL`, where `XXX` is one of `url`, `git`, `hg`, `cvs`, `bzr`, `svn`). Hash is printed to stdout.
459
4602. Prefetch by package source (with `nix-prefetch-url '<nixpkgs>' -A PACKAGE.src`, where `PACKAGE` is package attribute name). Hash is printed to stdout.
461
462 This works well when you've upgraded existing package version and want to find out new hash, but is useless if package can't be accessed by attribute or package has multiple sources (`.srcs`, architecture-dependent sources, etc).
463
4643. Upstream provided hash: use it when upstream provides `sha256` or `sha512` (when upstream provides `md5`, don't use it, compute `sha256` instead).
465
466 A little nuance is that `nix-prefetch-*` tools produce hash encoded with `base32`, but upstream usually provides hexadecimal (`base16`) encoding. Fetchers understand both formats. Nixpkgs does not standardize on any one format.
467
468 You can convert between formats with nix-hash, for example:
469
470 ```ShellSession
471 $ nix-hash --type sha256 --to-base32 HASH
472 ```
473
4744. Extracting hash from local source tarball can be done with `sha256sum`. Use `nix-prefetch-url file:///path/to/tarball` if you want base32 hash.
475
4765. Fake hash: set fake hash in package expression, perform build and extract correct hash from error Nix prints.
477
478 For package updates it is enough to change one symbol to make hash fake. For new packages, you can use `lib.fakeSha256`, `lib.fakeSha512` or any other fake hash.
479
480 This is last resort method when reconstructing source URL is non-trivial and `nix-prefetch-url -A` isn’t applicable (for example, [one of `kodi` dependencies](https://github.com/NixOS/nixpkgs/blob/d2ab091dd308b99e4912b805a5eb088dd536adb9/pkgs/applications/video/kodi/default.nix#L73)). The easiest way then would be replace hash with a fake one and rebuild. Nix build will fail and error message will contain desired hash.
481
482::: {.warning}
483This method has security problems. Check below for details.
484:::
485
486### Obtaining hashes securely {#sec-source-hashes-security}
487
488Let's say Man-in-the-Middle (MITM) sits close to your network. Then instead of fetching source you can fetch malware, and instead of source hash you get hash of malware. Here are security considerations for this scenario:
489
490- `http://` URLs are not secure to prefetch hash from;
491
492- hashes from upstream (in method 3) should be obtained via secure protocol;
493
494- `https://` URLs are secure in methods 1, 2, 3;
495
496- `https://` URLs are not secure in method 5. When obtaining hashes with fake hash method, TLS checks are disabled. So refetch source hash from several different networks to exclude MITM scenario. Alternatively, use fake hash method to make Nix error, but instead of extracting hash from error, extract `https://` URL and prefetch it with method 1.
497
498## Patches {#sec-patches}
499
500Patches available online should be retrieved using `fetchpatch`.
501
502```nix
503patches = [
504 (fetchpatch {
505 name = "fix-check-for-using-shared-freetype-lib.patch";
506 url = "http://git.ghostscript.com/?p=ghostpdl.git;a=patch;h=8f5d285";
507 sha256 = "1f0k043rng7f0rfl9hhb89qzvvksqmkrikmm38p61yfx51l325xr";
508 })
509];
510```
511
512Otherwise, you can add a `.patch` file to the `nixpkgs` repository. In the interest of keeping our maintenance burden to a minimum, only patches that are unique to `nixpkgs` should be added in this way.
513
514```nix
515patches = [ ./0001-changes.patch ];
516```
517
518If you do need to do create this sort of patch file, one way to do so is with git:
519
5201. Move to the root directory of the source code you're patching.
521
522 ```ShellSession
523 $ cd the/program/source
524 ```
525
5262. If a git repository is not already present, create one and stage all of the source files.
527
528 ```ShellSession
529 $ git init
530 $ git add .
531 ```
532
5333. Edit some files to make whatever changes need to be included in the patch.
534
5354. Use git to create a diff, and pipe the output to a patch file:
536
537 ```ShellSession
538 $ git diff -a > nixpkgs/pkgs/the/package/0001-changes.patch
539 ```
540
541If a patch is available online but does not cleanly apply, it can be modified in some fixed ways by using additional optional arguments for `fetchpatch`:
542
543- `stripLen`: Remove the first `stripLen` components of pathnames in the patch.
544- `extraPrefix`: Prefix pathnames by this string.
545- `excludes`: Exclude files matching this pattern.
546- `includes`: Include only files matching this pattern.
547- `revert`: Revert the patch.
548
549Note that because the checksum is computed after applying these effects, using or modifying these arguments will have no effect unless the `sha256` argument is changed as well.
550
551## Package tests {#sec-package-tests}
552
553Tests are important to ensure quality and make reviews and automatic updates easy.
554
555The following types of tests exists:
556
557* [NixOS **module tests**](https://nixos.org/manual/nixos/stable/#sec-nixos-tests), which spawn one or more NixOS VMs. They exercise both NixOS modules and the packaged programs used within them. For example, a NixOS module test can start a web server VM running the `nginx` module, and a client VM running `curl` or a graphical `firefox`, and test that they can talk to each other and display the correct content.
558* Nix **package tests** are a lightweight alternative to NixOS module tests. They should be used to create simple integration tests for packages, but cannot test NixOS services, and some programs with graphical user interfaces may also be difficult to test with them.
559* The **`checkPhase` of a package**, which should execute the unit tests that are included in the source code of a package.
560
561Here in the nixpkgs manual we describe mostly _package tests_; for _module tests_ head over to the corresponding [section in the NixOS manual](https://nixos.org/manual/nixos/stable/#sec-nixos-tests).
562
563### Writing inline package tests {#ssec-inline-package-tests-writing}
564
565For very simple tests, they can be written inline:
566
567```nix
568{ …, yq-go }:
569
570buildGoModule rec {
571 …
572
573 passthru.tests = {
574 simple = runCommand "${pname}-test" {} ''
575 echo "test: 1" | ${yq-go}/bin/yq eval -j > $out
576 [ "$(cat $out | tr -d $'\n ')" = '{"test":1}' ]
577 '';
578 };
579}
580```
581
582### Writing larger package tests {#ssec-package-tests-writing}
583
584This is an example using the `phoronix-test-suite` package with the current best practices.
585
586Add the tests in `passthru.tests` to the package definition like this:
587
588```nix
589{ stdenv, lib, fetchurl, callPackage }:
590
591stdenv.mkDerivation {
592 …
593
594 passthru.tests = {
595 simple-execution = callPackage ./tests.nix { };
596 };
597
598 meta = { … };
599}
600```
601
602Create `tests.nix` in the package directory:
603
604```nix
605{ runCommand, phoronix-test-suite }:
606
607let
608 inherit (phoronix-test-suite) pname version;
609in
610
611runCommand "${pname}-tests" { meta.timeout = 60; }
612 ''
613 # automatic initial setup to prevent interactive questions
614 ${phoronix-test-suite}/bin/phoronix-test-suite enterprise-setup >/dev/null
615 # get version of installed program and compare with package version
616 if [[ `${phoronix-test-suite}/bin/phoronix-test-suite version` != *"${version}"* ]]; then
617 echo "Error: program version does not match package version"
618 exit 1
619 fi
620 # run dummy command
621 ${phoronix-test-suite}/bin/phoronix-test-suite dummy_module.dummy-command >/dev/null
622 # needed for Nix to register the command as successful
623 touch $out
624 ''
625```
626
627### Running package tests {#ssec-package-tests-running}
628
629You can run these tests with:
630
631```ShellSession
632$ cd path/to/nixpkgs
633$ nix-build -A phoronix-test-suite.tests
634```
635
636### Examples of package tests {#ssec-package-tests-examples}
637
638Here are examples of package tests:
639
640- [Jasmin compile test](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/compilers/jasmin/test-assemble-hello-world/default.nix)
641- [Lobster compile test](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/compilers/lobster/test-can-run-hello-world.nix)
642- [Spacy annotation test](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/spacy/annotation-test/default.nix)
643- [Libtorch test](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/libraries/science/math/libtorch/test/default.nix)
644- [Multiple tests for nanopb](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/libraries/nanopb/default.nix)
645
646### Linking NixOS module tests to a package {#ssec-nixos-tests-linking}
647
648Like [package tests](#ssec-package-tests-writing) as shown above, [NixOS module tests](https://nixos.org/manual/nixos/stable/#sec-nixos-tests) can also be linked to a package, so that the tests can be easily run when changing the related package.
649
650For example, assuming we're packaging `nginx`, we can link its module test via `passthru.tests`:
651
652```nix
653{ stdenv, lib, nixosTests }:
654
655stdenv.mkDerivation {
656 ...
657
658 passthru.tests = {
659 nginx = nixosTests.nginx;
660 };
661
662 ...
663}
664```