Coding conventions
Syntax Use 2 spaces of indentation per indentation level in Nix expressions, 4 spaces in shell scripts. 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. Use lowerCamelCase for variable names, not UpperCamelCase. TODO: naming of attributes in all-packages.nix? Function calls with attribute set arguments are written as foo { arg = ...; } not foo { arg = ...; } Also fine is foo { arg = ...; } if it's a short call. In attribute sets or lists that span multiple lines, the attribute names or list elements should be aligned: # A long list. list = [ elem1 elem2 elem3 ]; # A long attribute set. attrs = { attr1 = short_expr; attr2 = if true then big_expr else big_expr; }; # Alternatively: attrs = { attr1 = short_expr; attr2 = if true then big_expr else big_expr; }; Short lists or attribute sets can be written on one line: # A short list. list = [ elem1 elem2 elem3 ]; # A short set. attrs = { x = 1280; y = 1024; }; Breaking in the middle of a function argument can give hard-to-read code, like someFunction { x = 1280; y = 1024; } otherArg yetAnotherArg (especially if the argument is very large, spanning multiple lines). Better: someFunction { x = 1280; y = 1024; } otherArg yetAnotherArg or let res = { x = 1280; y = 1024; }; in someFunction res otherArg yetAnotherArg The bodies of functions, asserts, and withs are not indented to prevent a lot of superfluous indentation levels, i.e. { arg1, arg2 }: assert system == "i686-linux"; stdenv.mkDerivation { ... not { arg1, arg2 }: assert system == "i686-linux"; stdenv.mkDerivation { ... Function formal arguments are written as: { arg1, arg2, arg3 }: but if they don't fit on one line they're written as: { arg1, arg2, arg3 , arg4, ... , # Some comment... argN }: Functions should list their expected arguments as precisely as possible. That is, write { stdenv, fetchurl, perl }: ... instead of args: with args; ... or { stdenv, fetchurl, perl, ... }: ... 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: { stdenv, doCoverageAnalysis ? false, ... } @ args: stdenv.mkDerivation (args // { ... if doCoverageAnalysis then "bla" else "" ... }) instead of args: args.stdenv.mkDerivation (args // { ... if args ? doCoverageAnalysis && args.doCoverageAnalysis then "bla" else "" ... })
File naming and organisation Names 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. Each 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. When in doubt, consider refactoring the pkgs/ tree, e.g. creating new categories or splitting up an existing category. If it’s used to support software development: If it’s a library used by other packages: development/libraries (e.g. libxml2) If it’s a compiler: development/compilers (e.g. gcc) If it’s an interpreter: development/interpreters (e.g. guile) If it’s a (set of) development tool(s): If it’s a parser generator (including lexers): development/tools/parsing (e.g. bison, flex) If it’s a build manager: development/tools/build-managers (e.g. gnumake) Else: development/tools/misc (e.g. binutils) Else: development/misc If it’s a (set of) tool(s): (A tool is a relatively small program, especially one intented to be used non-interactively.) If it’s for networking: tools/networking (e.g. wget) If it’s for text processing: tools/text (e.g. diffutils) If it’s a system utility, i.e., something related or essential to the operation of a system: tools/system (e.g. cron) If it’s an archiver (which may include a compression function): tools/archivers (e.g. zip, tar) If it’s a compression program: tools/compression (e.g. gzip, bzip2) If it’s a security-related program: tools/security (e.g. nmap, gnupg) Else: tools/misc If it’s a shell: shells (e.g. bash) If it’s a server: If it’s a web server: servers/http (e.g. apache-httpd) If it’s an implementation of the X Windowing System: servers/x11 (e.g. xorg — this includes the client libraries and programs) Else: servers/misc If it’s a desktop environment (including window managers): desktops (e.g. kde, gnome, enlightenment) If it’s an application: A (typically large) program with a distinct user interface, primarily used interactively. If it’s a version management system: applications/version-management (e.g. subversion) If it’s for video playback / editing: applications/video (e.g. vlc) If it’s for graphics viewing / editing: applications/graphics (e.g. gimp) If it’s for networking: If it’s a mailreader: applications/networking/mailreaders (e.g. thunderbird) If it’s a newsreader: applications/networking/newsreaders (e.g. pan) If it’s a web browser: applications/networking/browsers (e.g. firefox) Else: applications/networking/misc Else: applications/misc If it’s data (i.e., does not have a straight-forward executable semantics): If it’s a font: data/fonts If it’s related to SGML/XML processing: If it’s an XML DTD: data/sgml+xml/schemas/xml-dtd (e.g. docbook) If it’s an XSLT stylesheet: (Okay, these are executable...) data/sgml+xml/stylesheets/xslt (e.g. docbook-xsl) If it’s a game: games Else: misc