Merge 'staging' into closure-size

- there were many easy merge conflicts
- cc-wrapper needed nontrivial changes

Many other problems might've been created by interaction of the branches,
but stdenv and a few other packages build fine now.
wip/yesman
Vladimír Čunát 9 years ago
commit bf414c9d4f
  1. 7
      .gitignore
  2. 6
      .travis.yml
  3. 2
      .version
  4. 32
      README.md
  5. 4
      default.nix
  6. 4
      doc/contributing.xml
  7. 623
      doc/language-support.xml
  8. 1
      doc/manual.xml
  9. 35
      doc/meta.xml
  10. 6
      doc/old/cross.txt
  11. 70
      doc/packageconfig.xml
  12. 11
      doc/quick-start.xml
  13. 44
      doc/quote-literals.xsl
  14. 28
      doc/stdenv.xml
  15. 26
      lib/attrsets.nix
  16. 67
      lib/customisation.nix
  17. 36
      lib/debug.nix
  18. 294
      lib/licenses.nix
  19. 67
      lib/lists.nix
  20. 97
      lib/maintainers.nix
  21. 45
      lib/misc.nix
  22. 250
      lib/modules.nix
  23. 24
      lib/options.nix
  24. 2
      lib/platforms.nix
  25. 4
      lib/strings-with-deps.nix
  26. 27
      lib/strings.nix
  27. 2
      lib/systems.nix
  28. 119
      lib/tests/modules.sh
  29. 8
      lib/tests/modules/custom-arg-define-enable.nix
  30. 14
      lib/tests/modules/declare-enable.nix
  31. 29
      lib/tests/modules/declare-loaOfSub-any-enable.nix
  32. 7
      lib/tests/modules/default.nix
  33. 5
      lib/tests/modules/define-enable-force.nix
  34. 3
      lib/tests/modules/define-enable.nix
  35. 5
      lib/tests/modules/define-force-enable.nix
  36. 5
      lib/tests/modules/define-force-loaOfSub-foo-enable.nix
  37. 5
      lib/tests/modules/define-if-loaOfSub-foo-enable.nix
  38. 3
      lib/tests/modules/define-loaOfSub-bar-enable.nix
  39. 3
      lib/tests/modules/define-loaOfSub-bar.nix
  40. 5
      lib/tests/modules/define-loaOfSub-foo-enable-force.nix
  41. 5
      lib/tests/modules/define-loaOfSub-foo-enable-if.nix
  42. 3
      lib/tests/modules/define-loaOfSub-foo-enable.nix
  43. 7
      lib/tests/modules/define-loaOfSub-foo-force-enable.nix
  44. 7
      lib/tests/modules/define-loaOfSub-foo-if-enable.nix
  45. 3
      lib/tests/modules/define-loaOfSub-foo.nix
  46. 7
      lib/tests/modules/define-loaOfSub-force-foo-enable.nix
  47. 7
      lib/tests/modules/define-loaOfSub-if-foo-enable.nix
  48. 3
      lib/tests/modules/define-module-check.nix
  49. 31
      lib/tests/release.nix
  50. 27
      lib/trivial.nix
  51. 59
      lib/types.nix
  52. 14
      maintainers/docker/.dockerignore
  53. 12
      maintainers/docker/Dockerfile
  54. 4
      maintainers/scripts/nix-generate-from-cpan.nix
  55. 2
      maintainers/scripts/nix-generate-from-cpan.pl
  56. 2
      maintainers/scripts/patchelf-hints.sh
  57. 41
      maintainers/scripts/travis-nox-review-pr.sh
  58. 112
      maintainers/scripts/update-channel-branches.sh
  59. 7
      maintainers/scripts/vanity-manual-equalities.txt
  60. 122
      maintainers/scripts/vanity.sh
  61. 6
      nixos/doc/manual/administration/control-groups.xml
  62. 6
      nixos/doc/manual/administration/declarative-containers.xml
  63. 8
      nixos/doc/manual/administration/network-problems.xml
  64. 2
      nixos/doc/manual/configuration/config-file.xml
  65. 5
      nixos/doc/manual/configuration/ipv4-config.xml
  66. 2
      nixos/doc/manual/configuration/linux-kernel.xml
  67. 8
      nixos/doc/manual/configuration/network-manager.xml
  68. 2
      nixos/doc/manual/configuration/summary.xml
  69. 21
      nixos/doc/manual/configuration/x-windows.xml
  70. 48
      nixos/doc/manual/default.nix
  71. 32
      nixos/doc/manual/development/running-nixos-tests.xml
  72. 20
      nixos/doc/manual/development/sources.xml
  73. 19
      nixos/doc/manual/installation/installing.xml
  74. 13
      nixos/doc/manual/installation/obtaining.xml
  75. 44
      nixos/doc/manual/installation/upgrading.xml
  76. 117
      nixos/doc/manual/man-nixos-install.xml
  77. 66
      nixos/doc/manual/man-nixos-option.xml
  78. 23
      nixos/doc/manual/man-nixos-rebuild.xml
  79. 2
      nixos/doc/manual/man-pages.xml
  80. 1
      nixos/doc/manual/manual.xml
  81. 8
      nixos/doc/manual/options-to-docbook.xsl
  82. 6
      nixos/doc/manual/release-notes/release-notes.xml
  83. 22
      nixos/doc/manual/release-notes/rl-1410.xml
  84. 177
      nixos/doc/manual/release-notes/rl-1412.xml
  85. 41
      nixos/doc/manual/release-notes/rl-unstable.xml
  86. 16
      nixos/gui/README
  87. 36
      nixos/gui/application.ini
  88. 1
      nixos/gui/chrome.manifest
  89. 1
      nixos/gui/chrome/chrome.manifest
  90. 137
      nixos/gui/chrome/content/io.js
  91. 70
      nixos/gui/chrome/content/main.js
  92. 63
      nixos/gui/chrome/content/myviewer.xul
  93. 255
      nixos/gui/chrome/content/nixos.js
  94. 242
      nixos/gui/chrome/content/optionView.js
  95. 154
      nixos/gui/components/clh.js
  96. 11
      nixos/gui/defaults/preferences/myviewer-prefs.js
  97. 13
      nixos/lib/build-vms.nix
  98. 83
      nixos/lib/eval-config.nix
  99. 13
      nixos/lib/make-iso9660-image.nix
  100. 70
      nixos/lib/make-iso9660-image.sh
  101. Some files were not shown because too many files have changed in this diff Show More

7
.gitignore vendored

@ -10,4 +10,9 @@ result-*
/doc/manual.pdf
.version-suffix
.DS_Store
.DS_Store
/pkgs/applications/kde-apps-*/tmp/
/pkgs/development/libraries/kde-frameworks-*/tmp/
/pkgs/development/libraries/qt-5/*/tmp/
/pkgs/desktops/plasma-*/tmp/

@ -0,0 +1,6 @@
language: python
python: "3.4"
sudo: required
before_install: ./maintainers/scripts/travis-nox-review-pr.sh nix
install: ./maintainers/scripts/travis-nox-review-pr.sh nox
script: ./maintainers/scripts/travis-nox-review-pr.sh build

@ -1 +1 @@
14.10
15.05

@ -1,10 +1,26 @@
Nixpkgs is a collection of packages for [Nix](http://nixos.org/nix/) package
manager. Nixpkgs also includes [NixOS](http://nixos.org/nixos/) linux distribution source code.
* [NixOS installation instructions](http://nixos.org/nixos/manual/#ch-installation)
* [Manual (How to write packages for Nix)](http://nixos.org/nixpkgs/manual/)
* [Manual (NixOS)](http://nixos.org/nixos/manual/)
* [Continuous build](http://hydra.nixos.org/jobset/nixos/trunk-combined)
* [Tests](http://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
[<img src="http://nixos.org/logo/nixos-hires.png" width="500px" alt="logo" />
](https://nixos.org/nixos)
[![Build Status](https://travis-ci.org/NixOS/nixpkgs.svg?branch=master)](https://travis-ci.org/NixOS/nixpkgs) [![Issue Stats](http://www.issuestats.com/github/nixos/nixpkgs/badge/pr)](http://www.issuestats.com/github/nixos/nixpkgs) [![Issue Stats](http://www.issuestats.com/github/nixos/nixpkgs/badge/issue)](http://www.issuestats.com/github/nixos/nixpkgs)
Nixpkgs is a collection of packages for [Nix](https://nixos.org/nix/) package
manager.
[NixOS](https://nixos.org/nixos/) linux distribution source code is located inside `nixos/` folder.
* [NixOS installation instructions](https://nixos.org/nixos/manual/#ch-installation)
* [Documentation (Nix Expression Language chapter)](https://nixos.org/nix/manual/#ch-expression-language)
* [Manual (How to write packages for Nix)](https://nixos.org/nixpkgs/manual/)
* [Manual (NixOS)](https://nixos.org/nixos/manual/)
* [Continuous package builds for unstable/master](https://hydra.nixos.org/jobset/nixos/trunk-combined)
* [Continuous package builds for 14.12 release](https://hydra.nixos.org/jobset/nixos/release-14.12)
* [Tests for unstable/master](https://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
* [Tests for 14.12 release](https://hydra.nixos.org/job/nixos/release-14.12/tested#tabs-constituents)
Communication:
* [Mailing list](http://lists.science.uu.nl/mailman/listinfo/nix-dev)
* [IRC - #nixos on freenode.net](irc://irc.freenode.net/#nixos)
---
[![Throughput Graph](https://graphs.waffle.io/nixos/nixpkgs/throughput.svg)](https://waffle.io/nixos/nixpkgs/metrics)

@ -1,6 +1,6 @@
if ! builtins ? nixVersion || builtins.compareVersions "1.6" builtins.nixVersion == 1 then
if ! builtins ? nixVersion || builtins.compareVersions "1.8" builtins.nixVersion == 1 then
abort "This version of Nixpkgs requires Nix >= 1.6, please upgrade!"
abort "This version of Nixpkgs requires Nix >= 1.8, please upgrade! See https://nixos.org/wiki/How_to_update_when_nix_is_too_old_to_evaluate_nixpkgs"
else

@ -10,9 +10,7 @@
<listitem><para><command>$ git clone git://github.com/NixOS/nixpkgs.git</command></para></listitem>
<listitem><para><command>$ cd nixpkgs/pkgs/top-level</command></para></listitem>
<listitem><para><command>$ nix-build -A tarball release.nix</command></para></listitem>
<listitem><para><command>$ nix-build -A manual nixpkgs/pkgs/top-level/release.nix</command></para></listitem>
<listitem><para>Inside the built derivation you shall see <literal>manual/index.html</literal> file.</para></listitem>

@ -108,7 +108,7 @@ a <varname>preConfigure</varname> hook to generate a configuration
file used by <filename>Makefile.PL</filename>:
<programlisting>
{buildPerlPackage, fetchurl, db}:
{ buildPerlPackage, fetchurl, db }:
buildPerlPackage rec {
name = "BerkeleyDB-0.36";
@ -191,47 +191,550 @@ you need it.</para>
</section>
<section><title>Python</title>
<section xml:id="python"><title>Python</title>
<para>
Currently supported interpreters are <varname>python26</varname>, <varname>python27</varname>,
<varname>python32</varname>, <varname>python33</varname>, <varname>python34</varname>
and <varname>pypy</varname>.
</para>
<para>
<varname>python</varname> is an alias of <varname>python27</varname> and <varname>python3</varname> is an alias of <varname>python34</varname>.
</para>
<para>
<varname>python26</varname> and <varname>python27</varname> do not include modules that require
external dependencies (to reduce dependency bloat). Following modules need to be added as
<varname>buildInput</varname> explicitly:
</para>
<itemizedlist>
<listitem><para><varname>python.modules.bsddb</varname></para></listitem>
<listitem><para><varname>python.modules.curses</varname></para></listitem>
<listitem><para><varname>python.modules.curses_panel</varname></para></listitem>
<listitem><para><varname>python.modules.crypt</varname></para></listitem>
<listitem><para><varname>python.modules.gdbm</varname></para></listitem>
<listitem><para><varname>python.modules.sqlite3</varname></para></listitem>
<listitem><para><varname>python.modules.tkinter</varname></para></listitem>
<listitem><para><varname>python.modules.readline</varname></para></listitem>
</itemizedlist>
<para>For convenience <varname>python27Full</varname> and <varname>python26Full</varname>
are provided with all modules included.</para>
<para>
Python packages that
use <link xlink:href="http://pypi.python.org/pypi/setuptools/"><literal>setuptools</literal></link>,
which many Python packages do nowadays, can be built very simply using
the <varname>buildPythonPackage</varname> function. This function is
implemented
in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/generic/default.nix"><filename>pkgs/development/python-modules/generic/default.nix</filename></link>
and works similarly to <varname>buildPerlPackage</varname>. (See
<xref linkend="ssec-language-perl"/> for details.)
use <link xlink:href="http://pypi.python.org/pypi/setuptools/"><literal>setuptools</literal></link> or <literal>distutils</literal>,
can be built using the <varname>buildPythonPackage</varname> function as documented below.
</para>
<para>
Python packages that use <varname>buildPythonPackage</varname> are
defined
in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/python-packages.nix"><filename>pkgs/top-level/python-packages.nix</filename></link>.
Most of them are simple. For example:
All packages depending on any Python interpreter get appended <varname>$out/${python.libPrefix}/site-packages</varname>
to <literal>$PYTHONPATH</literal> if such directory exists.
</para>
<programlisting>
<variablelist>
<title>
Useful attributes on interpreters packages:
</title>
<varlistentry>
<term><varname>libPrefix</varname></term>
<listitem><para>
Name of the folder in <literal>${python}/lib/</literal> for corresponding interpreter.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>interpreter</varname></term>
<listitem><para>
Alias for <literal>${python}/bin/${executable}.</literal>
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>buildEnv</varname></term>
<listitem><para>
Function to build python interpreter environments with extra packages bundled together.
See <xref linkend="python-build-env" /> for usage and documentation.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>sitePackages</varname></term>
<listitem><para>
Alias for <literal>lib/${libPrefix}/site-packages</literal>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>executable</varname></term>
<listitem><para>
Name of the interpreter executable, ie <literal>python3.4</literal>.
</para></listitem>
</varlistentry>
</variablelist>
<section xml:id="build-python-package"><title><varname>buildPythonPackage</varname> function</title>
<para>
The function is implemented in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/generic/default.nix">
<filename>pkgs/development/python-modules/generic/default.nix</filename></link>.
Example usage:
<programlisting language="nix">
twisted = buildPythonPackage {
name = "twisted-8.1.0";
src = fetchurl {
src = pkgs.fetchurl {
url = http://tmrc.mit.edu/mirror/twisted/Twisted/8.1/Twisted-8.1.0.tar.bz2;
sha256 = "0q25zbr4xzknaghha72mq57kh53qw1bf8csgp63pm9sfi72qhirl";
};
propagatedBuildInputs = [ pkgs.ZopeInterface ];
propagatedBuildInputs = [ self.ZopeInterface ];
meta = {
homepage = http://twistedmatrix.com/;
description = "Twisted, an event-driven networking engine written in Python";
license = "MIT";
license = stdenv.lib.licenses.mit;
};
};
</programlisting>
</programlisting>
Most of Python packages that use <varname>buildPythonPackage</varname> are defined
in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/python-packages.nix"><filename>pkgs/top-level/python-packages.nix</filename></link>
and generated for each python interpreter separately into attribute sets <varname>python26Packages</varname>,
<varname>python27Packages</varname>, <varname>python32Packages</varname>, <varname>python33Packages</varname>,
<varname>python34Packages</varname> and <varname>pypyPackages</varname>.
</para>
<para>
<function>buildPythonPackage</function> mainly does four things:
<orderedlist>
<listitem><para>
In the <varname>configurePhase</varname>, it patches
<literal>setup.py</literal> to always include setuptools before
distutils for monkeypatching machinery to take place.
</para></listitem>
<listitem><para>
In the <varname>buildPhase</varname>, it calls
<literal>${python.interpreter} setup.py build ...</literal>
</para></listitem>
<listitem><para>
In the <varname>installPhase</varname>, it calls
<literal>${python.interpreter} setup.py install ...</literal>
</para></listitem>
<listitem><para>
In the <varname>postFixup</varname> phase, <literal>wrapPythonPrograms</literal>
bash function is called to wrap all programs in <filename>$out/bin/*</filename>
directory to include <literal>$PYTHONPATH</literal> and <literal>$PATH</literal>
environment variables.
</para></listitem>
</orderedlist>
</para>
<para>By default <varname>doCheck = true</varname> is set and tests are run with
<literal>${python.interpreter} setup.py test</literal> command in <varname>checkPhase</varname>.</para>
<para><varname>propagatedBuildInputs</varname> packages are propagated to user environment.</para>
<para>
By default <varname>meta.platforms</varname> is set to the same value
as the interpreter unless overriden otherwise.
</para>
<variablelist>
<title>
<varname>buildPythonPackage</varname> parameters
(all parameters from <varname>mkDerivation</varname> function are still supported)
</title>
<varlistentry>
<term><varname>namePrefix</varname></term>
<listitem><para>
Prepended text to <varname>${name}</varname> parameter.
Defaults to <literal>"python3.3-"</literal> for Python 3.3, etc. Set it to
<literal>""</literal>
if you're packaging an application or a command line tool.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>disabled</varname></term>
<listitem><para>
If <varname>true</varname>, package is not build for
particular python interpreter version. Grep around
<filename>pkgs/top-level/python-packages.nix</filename>
for examples.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>setupPyInstallFlags</varname></term>
<listitem><para>
List of flags passed to <command>setup.py install</command> command.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>setupPyBuildFlags</varname></term>
<listitem><para>
List of flags passed to <command>setup.py build</command> command.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>pythonPath</varname></term>
<listitem><para>
List of packages to be added into <literal>$PYTHONPATH</literal>.
Packages in <varname>pythonPath</varname> are not propagated into user environment
(contrary to <varname>propagatedBuildInputs</varname>).
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>preShellHook</varname></term>
<listitem><para>
Hook to execute commands before <varname>shellHook</varname>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>postShellHook</varname></term>
<listitem><para>
Hook to execute commands after <varname>shellHook</varname>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>distutilsExtraCfg</varname></term>
<listitem><para>
Extra lines passed to <varname>[easy_install]</varname> section of
<filename>distutils.cfg</filename> (acts as global setup.cfg
configuration).
</para></listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="python-build-env"><title><function>python.buildEnv</function> function</title>
<para>
Create Python environments using low-level <function>pkgs.buildEnv</function> function. Example <filename>default.nix</filename>:
<programlisting language="nix">
<![CDATA[with import <nixpkgs> {};
python.buildEnv.override {
extraLibs = [ pkgs.pythonPackages.pyramid ];
ignoreCollisions = true;
}]]>
</programlisting>
Running <command>nix-build</command> will create
<filename>/nix/store/cf1xhjwzmdki7fasgr4kz6di72ykicl5-python-2.7.8-env</filename>
with wrapped binaries in <filename>bin/</filename>.
</para>
<variablelist>
<title>
<function>python.buildEnv</function> arguments
</title>
<varlistentry>
<term><varname>extraLibs</varname></term>
<listitem><para>
List of packages installed inside the environment.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>postBuild</varname></term>
<listitem><para>
Shell command executed after the build of environment.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>ignoreCollisions</varname></term>
<listitem><para>
Ignore file collisions inside the environment (default is <varname>false</varname>).
</para></listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="python-tools"><title>Tools</title>
<para>Packages inside nixpkgs are written by hand. However many tools
exist in community to help save time. No tool is preferred at the moment.
</para>
<itemizedlist>
<listitem><para>
<link xlink:href="https://github.com/proger/python2nix">python2nix</link>
by Vladimir Kirillov
</para></listitem>
<listitem><para>
<link xlink:href="https://github.com/garbas/pypi2nix">pypi2nix</link>
by Rok Garbas
</para></listitem>
<listitem><para>
<link xlink:href="https://github.com/offlinehacker/pypi2nix">pypi2nix</link>
by Jaka Hudoklin
</para></listitem>
</itemizedlist>
</section>
<section xml:id="python-development"><title>Development</title>
<para>
To develop Python packages <function>buildPythonPackage</function> has
additional logic inside <varname>shellPhase</varname> to run
<command>${python.interpreter} setup.py develop</command> for the package.
</para>
<warning><para><varname>shellPhase</varname> is executed only if <filename>setup.py</filename>
exists.</para></warning>
<para>
Given a <filename>default.nix</filename>:
<programlisting language="nix">
<![CDATA[with import <nixpkgs> {};
buildPythonPackage {
name = "myproject";
buildInputs = with pkgs.pythonPackages; [ pyramid ];
src = ./.;
}]]>
</programlisting>
Running <command>nix-shell</command> with no arguments should give you
the environment in which the package would be build with
<command>nix-build</command>.
</para>
<para>
Shortcut to setup environments with C headers/libraries and python packages:
<programlisting language="bash">$ nix-shell -p pythonPackages.pyramid zlib libjpeg git</programlisting>
</para>
<note><para>
There is a boolean value <varname>lib.inNixShell</varname> set to
<varname>true</varname> if nix-shell is invoked.
</para></note>
</section>
<section xml:id="python-faq"><title>FAQ</title>
<variablelist>
<varlistentry>
<term>How to solve circular dependencies?</term>
<listitem><para>
If you have packages <varname>A</varname> and <varname>B</varname> that
depend on each other, when packaging <varname>B</varname> override package
<varname>A</varname> not to depend on <varname>B</varname> as input
(and also the other way around).
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>install_data / data_files</varname> problems resulting into <literal>error: could not create '/nix/store/6l1bvljpy8gazlsw2aw9skwwp4pmvyxw-python-2.7.8/etc': Permission denied</literal></term>
<listitem><para>
<link xlink:href="https://bitbucket.org/pypa/setuptools/issue/130/install_data-doesnt-respect-prefix">
Known bug in setuptools <varname>install_data</varname> does not respect --prefix</link>. Example of
such package using the feature is <filename>pkgs/tools/X11/xpra/default.nix</filename>. As workaround
install it as an extra <varname>preInstall</varname> step:
<programlisting>${python.interpreter} setup.py install_data --install-dir=$out --root=$out
sed -i '/ = data_files/d' setup.py</programlisting>
</para></listitem>
</varlistentry>
<varlistentry>
<term>Rationale of non-existent global site-packages</term>
<listitem><para>
There is no need to have global site-packages in Nix. Each package has isolated
dependency tree and installing any python package will only populate <varname>$PATH</varname>
inside user environment. See <xref linkend="python-build-env" /> to create self-contained
interpreter with a set of packages.
</para></listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="python-contrib"><title>Contributing guidelines</title>
<para>
Following rules are desired to be respected:
</para>
<itemizedlist>
<listitem><para>
Make sure package builds for all python interpreters. Use <varname>disabled</varname> argument to
<function>buildPythonPackage</function> to set unsupported interpreters.
</para></listitem>
<listitem><para>
If tests need to be disabled for a package, make sure you leave a comment about reasoning.
</para></listitem>
<listitem><para>
Packages in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/python-packages.nix"><filename>pkgs/top-level/python-packages.nix</filename></link>
are sorted quasi-alphabetically to avoid merge conflicts.
</para></listitem>
</itemizedlist>
</section>
</section>
<section xml:id="ssec-language-ruby"><title>Ruby</title>
<para>There currently is support to bundle applications that are packaged as Ruby gems. The utility "bundix" allows you to write a <filename>Gemfile</filename>, let bundler create a <filename>Gemfile.lock</filename>, and then convert
this into a nix expression that contains all Gem dependencies automatically.</para>
<para>For example, to package sensu, we did:</para>
<screen>
<![CDATA[$ cd pkgs/servers/monitoring
$ mkdir sensu
$ cat > Gemfile
source 'https://rubygems.org'
gem 'sensu'
$ bundler package --path /tmp/vendor/bundle
$ $(nix-build '&nixpkgs>' -A bundix)/bin/bundix
$ cat > default.nix
{ lib, bundlerEnv, ruby }:
bundlerEnv {
name = "sensu-0.17.1";
inherit ruby;
gemfile = ./Gemfile;
lockfile = ./Gemfile.lock;
gemset = ./gemset.nix;
meta = with lib; {
description = "A monitoring framework that aims to be simple, malleable,
and scalable.";
homepage = http://sensuapp.org/;
license = with licenses; mit;
maintainers = with maintainers; [ theuni ];
platforms = platforms.unix;
};
}]]>
</screen>
<para>Please check in the <filename>Gemfile</filename>, <filename>Gemfile.lock</filename> and the <filename>gemset.nix</filename> so future updates can be run easily.
</para>
</section>
<section xml:id="ssec-language-go"><title>Go</title>
<para>The function <varname>buildGoPackage</varname> builds
standard Go packages.
</para>
<example xml:id='ex-buildGoPackage'><title>buildGoPackage</title>
<programlisting>
net = buildGoPackage rec {
name = "go.net-${rev}";
goPackagePath = "code.google.com/p/go.net"; <co xml:id='ex-buildGoPackage-1' />
subPackages = [ "ipv4" "ipv6" ]; <co xml:id='ex-buildGoPackage-2' />
rev = "28ff664507e4";
src = fetchhg {
inherit rev;
url = "https://${goPackagePath}";
sha256 = "1lkz4c9pyz3yz2yz18hiycvlfhgy3jxp68bs7mv7bcfpaj729qav";
};
propagatedBuildInputs = [ goPackages.text ]; <co xml:id='ex-buildGoPackage-3' />
};
</programlisting>
</example>
<para><xref linkend='ex-buildGoPackage'/> is an example expression using buildGoPackage,
the following arguments are of special significance to the function:
<calloutlist>
<callout arearefs='ex-buildGoPackage-1'>
<para>
<varname>goPackagePath</varname> specifies the package's canonical Go import path.
</para>
</callout>
<callout arearefs='ex-buildGoPackage-2'>
<para>
<varname>subPackages</varname> limits the builder from building child packages that
have not been listed. If <varname>subPackages</varname> is not specified, all child
packages will be built.
</para>
<para>
In this example only <literal>code.google.com/p/go.net/ipv4</literal> and
<literal>code.google.com/p/go.net/ipv4</literal> will be built.
</para>
</callout>
<callout arearefs='ex-buildGoPackage-3'>
<para>
<varname>propagatedBuildInputs</varname> is where the dependencies of a Go library are
listed. Only libraries should list <varname>propagatedBuildInputs</varname>. If a standalone
program is being build instead, use <varname>buildInputs</varname>. If a library's tests require
additional dependencies that are not propagated, they should be listed in <varname>buildInputs</varname>.
</para>
</callout>
</calloutlist>
</para>
<para>
Reusable Go libraries may be found in the <varname>goPackages</varname> set. You can test
build a Go package as follows:
<screen>
$ nix-build -A goPackages.net
</screen>
</para>
<para>
You may use Go packages installed into the active Nix profiles by adding
the following to your ~/.bashrc:
<screen>
for p in $NIX_PROFILES; do
GOPATH="$p/share/go:$GOPATH"
done
</screen>
</para>
<para>To extract dependency information from a Go package in automated way use <link xlink:href="https://github.com/cstrahan/go2nix">go2nix</link>.</para>
</section>
<section xml:id="ssec-language-java"><title>Java</title>
@ -314,6 +817,90 @@ Runtime) instead of the OpenJRE.</para>
</section>
<section xml:id="ssec-language-lua"><title>Lua</title>
<para>
Lua packages are built by the <varname>buildLuaPackage</varname> function. This function is
implemented
in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/lua-modules/generic/default.nix">
<filename>pkgs/development/lua-modules/generic/default.nix</filename></link>
and works similarly to <varname>buildPerlPackage</varname>. (See
<xref linkend="ssec-language-perl"/> for details.)
</para>
<para>
Lua packages are defined
in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/lua-packages.nix"><filename>pkgs/top-level/lua-packages.nix</filename></link>.
Most of them are simple. For example:
<programlisting>
fileSystem = buildLuaPackage {
name = "filesystem-1.6.2";
src = fetchurl {
url = "https://github.com/keplerproject/luafilesystem/archive/v1_6_2.tar.gz";
sha256 = "1n8qdwa20ypbrny99vhkmx8q04zd2jjycdb5196xdhgvqzk10abz";
};
meta = {
homepage = "https://github.com/keplerproject/luafilesystem";
hydraPlatforms = stdenv.lib.platforms.linux;
maintainers = with maintainers; [ flosse ];
};
};
</programlisting>
</para>
<para>
Though, more complicated package should be placed in a seperate file in
<link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/lua-modules"><filename>pkgs/development/lua-modules</filename></link>.
</para>
<para>
Lua packages accept additional parameter <varname>disabled</varname>, which defines
the condition of disabling package from luaPackages. For example, if package has
<varname>disabled</varname> assigned to <literal>lua.luaversion != "5.1"</literal>,
it will not be included in any luaPackages except lua51Packages, making it
only be built for lua 5.1.
</para>
</section>
<section xml:id="ssec-language-coq"><title>Coq</title>
<para>
Coq libraries should be installed in
<literal>$(out)/lib/coq/${coq.coq-version}/user-contrib/</literal>.
Such directories are automatically added to the
<literal>$COQPATH</literal> environment variable by the hook defined
in the Coq derivation.
</para>
<para>
Some libraries require OCaml and sometimes also Camlp5. The exact
versions that were used to build Coq are saved in the
<literal>coq.ocaml</literal> and <literal>coq.camlp5</literal>
attributes.
</para>
<para>
Here is a simple package example. It is a pure Coq library, thus it
only depends on Coq. Its <literal>makefile</literal> has been
generated using <literal>coq_makefile</literal> so we only have to
set the <literal>$COQLIB</literal> variable at install time.
</para>
<programlisting>
{stdenv, fetchurl, coq}:
stdenv.mkDerivation {
src = fetchurl {
url = http://coq.inria.fr/pylons/contribs/files/Karatsuba/v8.4/Karatsuba.tar.gz;
sha256 = "0ymfpv4v49k4fm63nq6gcl1hbnnxrvjjp7yzc4973n49b853c5b1";
};
name = "coq-karatsuba";
buildInputs = [ coq ];
installFlags = "COQLIB=$(out)/lib/coq/${coq.coq-version}/";
}
</programlisting>
</section>
<!--
<section><title>Haskell</title>

@ -12,6 +12,7 @@
<xi:include href="introduction.xml" />
<xi:include href="quick-start.xml" />
<xi:include href="stdenv.xml" />
<xi:include href="packageconfig.xml" />
<xi:include href="meta.xml" />
<xi:include href="language-support.xml" />
<xi:include href="package-notes.xml" />

@ -84,8 +84,7 @@ hello-2.3 A program that produces a familiar, friendly greeting
<section><title>Standard meta-attributes</title>
<para>The following meta-attributes have a standard
interpretation:</para>
<para>It is expected that each meta-attribute is one of the following:</para>
<variablelist>
@ -112,12 +111,30 @@ interpretation:</para>
package.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>version</varname></term>
<listitem><para>Package version.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>branch</varname></term>
<listitem><para>Release branch. Used to specify that a package is not
going to receive updates that are not in this branch; for example, Linux
kernel 3.0 is supposed to be updated to 3.0.X, not 3.1.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>homepage</varname></term>
<listitem><para>The package’s homepage. Example:
<literal>http://www.gnu.org/software/hello/manual/</literal></para></listitem>
</varlistentry>
<varlistentry>
<term><varname>downloadPage</varname></term>
<listitem><para>The page where a link to the current version can be found. Example:
<literal>http://ftp.gnu.org/gnu/hello/</literal></para></listitem>
</varlistentry>
<varlistentry>
<term><varname>license</varname></term>
<listitem><para>The license for the package. One from the
@ -195,6 +212,16 @@ meta.hydraPlatforms = [];
they are fixed.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>updateWalker</varname></term>
<listitem><para>If set to <literal>true</literal>, the package is
tested to be updated correctly by the <literal>update-walker.sh</literal>
script without additional settings. Such packages have
<varname>meta.version</varname> set and their homepage (or
the page specified by <varname>meta.downloadPage</varname>) contains
a direct link to the package tarball.</para></listitem>
</varlistentry>
</variablelist>
@ -256,9 +283,9 @@ to indicate the specific license:
</variablelist>
</para>
</section>
</chapter>

@ -184,10 +184,10 @@ if test "$noSysDirs" = "1"; then
if test "$noSysDirs" = "1"; then
# Figure out what extra flags to pass to the gcc compilers
# being generated to make sure that they use our glibc.
if test -e $NIX_GCC/nix-support/orig-glibc; then
glibc=$(cat $NIX_GCC/nix-support/orig-glibc)
if test -e $NIX_CC/nix-support/orig-glibc; then
glibc=$(cat $NIX_CC/nix-support/orig-glibc)
# Ugh. Copied from gcc-wrapper/builder.sh. We can't just
# source in $NIX_GCC/nix-support/add-flags, since that
# source in $NIX_CC/nix-support/add-flags, since that
# would cause *this* GCC to be linked against the
# *previous* GCC. Need some more modularity there.
extraCFlags="-B$glibc/lib -isystem $glibc/include"

@ -0,0 +1,70 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-packageconfig">
<title><filename>~/.nixpkgs/config.nix</filename>: global configuration</title>
<para>
Nix packages can be configured to allow or deny certain options.
</para>
<para>
To apply the configuration edit <filename>~/.nixpkgs/config.nix</filename>
and set it like
<programlisting>{
allowUnfree = true;
}</programlisting>
and will allow the Nix package manager to install unfree licensed packages.
The configuration as listed also applies to NixOS under <option>nixpkgs.config</option> set.
</para>
<itemizedlist>
<listitem>
<para>
Allow installing of packages that are distributed under unfree license by setting
<programlisting>allowUnfree = true;</programlisting>
or deny them by setting it to <literal>false</literal>.
</para>
<para>
Same can be achieved by setting the environment variable:
<programlisting>$ export NIXPKGS_ALLOW_UNFREE=1</programlisting>
</para>
</listitem>
<listitem>
<para>
Whenever unfree packages are not allowed, single packages can
still be allowed by a predicate function that accepts package
as an argument and should return a boolean:
<programlisting>allowUnfreePredicate = (pkg: ...);</programlisting>
Example to allow flash player only:
<programlisting>allowUnfreePredicate = (pkg: pkgs.lib.hasPrefix "flashplayer-" pkg.name);</programlisting>
</para>
</listitem>
<listitem>
<para>
Whenever unfree packages are not allowed, packages can still be
whitelisted by their license:
<programlisting>whitelistedLicenses = with stdenv.lib.licenses; [ amd wtfpl ];</programlisting>
</para>
</listitem>
<listitem>
<para>
In addition to whitelisting licenses which are denied by the
<literal>allowUnfree</literal> setting, you can also explicitely
deny installation of packages which have a certain license:
<programlisting>blacklistedLicenses = with stdenv.lib.licenses; [ agpl3 gpl3 ];</programlisting>
</para>
</listitem>
</itemizedlist>
<para>
A complete list of licenses can be found in the file
<filename>lib/licenses.nix</filename> of the nix package tree.
</para>
</chapter>

@ -92,17 +92,6 @@ $ git add pkgs/development/libraries/libfoo/default.nix</screen>
hackery.</para>
</listitem>
<listitem>
<para>BitTorrent (wxPython-based): <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/networking/p2p/bittorrent/default.nix"><filename>pkgs/tools/networking/p2p/bittorrent/default.nix</filename></link>.
Uses an external <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/networking/p2p/bittorrent/builder.sh">build
script</link>, which can be useful if you have lots of code
that you don’t want cluttering up the Nix expression. But
external builders are mostly obsolete.
</para>
</listitem>
<listitem>
<para>Thunderbird: <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/networking/mailreaders/thunderbird/default.nix"><filename>pkgs/applications/networking/mailreaders/thunderbird/default.nix</filename></link>.

@ -1,44 +0,0 @@
<?xml version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">
<xsl:output method="xml"/>
<xsl:template match="function|command|literal|varname|filename|option|quote">`<xsl:apply-templates/>'</xsl:template>
<xsl:template match="token"><xsl:text> </xsl:text><xsl:apply-templates /><xsl:text>
</xsl:text></xsl:template>
<xsl:template match="screen|programlisting">
<screen><xsl:apply-templates select="str:split(., '&#xA;')" /></screen>
</xsl:template>
<xsl:template match="section[following::section]">
<section>
<xsl:apply-templates />
<screen><xsl:text>
</xsl:text></screen>
</section>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="namespace::*" />
<xsl:for-each select="@*">
<xsl:attribute name="{name(.)}" namespace="{namespace-uri(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="translate(., '‘’“”—', concat(&quot;`'&quot;, '&quot;&quot;-'))" />
</xsl:template>
</xsl:stylesheet>

@ -150,8 +150,8 @@ genericBuild
<listitem><para>GNU <command>tar</command>.</para></listitem>
<listitem><para><command>gzip</command> and
<command>bzip2</command>.</para></listitem>
<listitem><para><command>gzip</command>, <command>bzip2</command>
and <command>xz</command>.</para></listitem>
<listitem><para>GNU Make. It has been patched to provide
<quote>nested</quote> output that can be fed into the
@ -341,9 +341,11 @@ It supports the following files by default:
<term>Tar files</term>
<listitem><para>These can optionally be compressed using
<command>gzip</command> (<filename>.tar.gz</filename>,
<filename>.tgz</filename> or <filename>.tar.Z</filename>) or
<filename>.tgz</filename> or <filename>.tar.Z</filename>),
<command>bzip2</command> (<filename>.tar.bz2</filename> or
<filename>.tbz2</filename>).</para></listitem>
<filename>.tbz2</filename>) or <command>xz</command>
(<filename>.tar.xz</filename> or
<filename>.tar.lzma</filename>).</para></listitem>
</varlistentry>
<varlistentry>
@ -445,9 +447,10 @@ Additional file types can be supported by setting the
<listitem><para>The list of patches. They must be in the format
accepted by the <command>patch</command> command, and may
optionally be compressed using <command>gzip</command>
(<filename>.gz</filename>) or <command>bzip2</command>
(<filename>.bz2</filename>).</para></listitem>
</varlistentry>
(<filename>.gz</filename>), <command>bzip2</command>
(<filename>.bz2</filename>) or <command>xz</command>
(<filename>.xz</filename>).</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>patchFlags</varname></term>
@ -715,7 +718,7 @@ the Nix store under <envar>out</envar>. The default
install</command>.</para>
<variablelist>
<title>Variables controlling the check phase</title>
<title>Variables controlling the install phase</title>
<varlistentry>
<term><varname>makeFlags</varname> /
@ -794,7 +797,7 @@ following:
</para>
<variablelist>
<title>Variables controlling the check phase</title>
<title>Variables controlling the fixup phase</title>
<varlistentry>
<term><varname>dontStrip</varname></term>
@ -1117,12 +1120,9 @@ echo @foo@
<varlistentry>
<term>Python</term>
<listitem><para>Adds the
<filename>lib/python2.5/site-packages</filename> subdirectory of
<filename>lib/${python.libPrefix}/site-packages</filename> subdirectory of
each build input to the <envar>PYTHONPATH</envar> environment
variable.</para>
<note><para>This should be generalised: the Python version
shouldn’t be hard-coded.</para></note></listitem>
variable.</para></listitem>
</varlistentry>
<varlistentry>

@ -1,7 +1,7 @@
# Operations on attribute sets.
with {
inherit (builtins) head tail;
inherit (builtins) head tail length;
inherit (import ./trivial.nix) or;
inherit (import ./default.nix) fold;
inherit (import ./strings.nix) concatStringsSep;
@ -20,8 +20,8 @@ rec {
let attr = head attrPath;
in
if attrPath == [] then e
else if hasAttr attr e
then attrByPath (tail attrPath) default (getAttr attr e)
else if e ? ${attr}
then attrByPath (tail attrPath) default e.${attr}
else default;
@ -44,8 +44,7 @@ rec {
attrVals ["a" "b" "c"] as
=> [as.a as.b as.c]
*/
attrVals = nameList: set:
map (x: getAttr x set) nameList;
attrVals = nameList: set: map (x: set.${x}) nameList;
/* Return the values of all attributes in the given set, sorted by
@ -55,7 +54,7 @@ rec {
attrValues {c = 3; a = 1; b = 2;}
=> [1 2 3]
*/
attrValues = attrs: attrVals (attrNames attrs) attrs;
attrValues = builtins.attrValues or (attrs: attrVals (attrNames attrs) attrs);
/* Collect each attribute named `attr' from a list of attribute
@ -65,7 +64,8 @@ rec {
catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
=> [1 2]
*/
catAttrs = attr: l: concatLists (map (s: if hasAttr attr s then [(getAttr attr s)] else []) l);
catAttrs = builtins.catAttrs or
(attr: l: concatLists (map (s: if s ? ${attr} then [s.${attr}] else []) l));
/* Filter an attribute set by removing all attributes for which the
@ -76,7 +76,7 @@ rec {
=> { foo = 1; }
*/
filterAttrs = pred: set:
listToAttrs (fold (n: ys: let v = getAttr n set; in if pred n v then [(nameValuePair n v)] ++ ys else ys) [] (attrNames set));
listToAttrs (fold (n: ys: let v = set.${n}; in if pred n v then [(nameValuePair n v)] ++ ys else ys) [] (attrNames set));
/* foldAttrs: apply fold functions to values grouped by key. Eg accumulate values as list:
@ -86,7 +86,7 @@ rec {
foldAttrs = op: nul: list_of_attrs:
fold (n: a:
fold (name: o:
o // (listToAttrs [{inherit name; value = op (getAttr name n) (maybeAttr name nul a); }])
o // (listToAttrs [{inherit name; value = op n.${name} (maybeAttr name nul a); }])
) a (attrNames n)
) {} list_of_attrs;
@ -132,7 +132,7 @@ rec {
=> { x = "x-foo"; y = "y-bar"; }
*/
mapAttrs = f: set:
listToAttrs (map (attr: { name = attr; value = f attr (getAttr attr set); }) (attrNames set));
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set));
/* Like `mapAttrs', but allows the name of each attribute to be
@ -145,7 +145,7 @@ rec {
=> { foo_x = "bar-a"; foo_y = "bar-b"; }
*/
mapAttrs' = f: set:
listToAttrs (map (attr: f attr (getAttr attr set)) (attrNames set));
listToAttrs (map (attr: f attr set.${attr}) (attrNames set));
/* Call a function for each attribute in the given set and return
@ -157,7 +157,7 @@ rec {
=> [ "xa" "yb" ]
*/
mapAttrsToList = f: attrs:
map (name: f name (getAttr name attrs)) (attrNames attrs);
map (name: f name attrs.${name}) (attrNames attrs);
/* Like `mapAttrs', except that it recursively applies itself to
@ -322,7 +322,7 @@ rec {
# override only the attributes that are already present in the old set
# useful for deep-overriding
overrideExisting = old: new:
old // listToAttrs (map (attr: nameValuePair attr (attrByPath [attr] (getAttr attr old) new)) (attrNames old));
old // listToAttrs (map (attr: nameValuePair attr (attrByPath [attr] old.${attr} new)) (attrNames old));
deepSeqAttrs = x: y: deepSeqList (attrValues x) y;
}

@ -1,6 +1,6 @@
let lib = import ./default.nix;
inherit (builtins) getAttr attrNames isFunction;
let
lib = import ./default.nix;
inherit (builtins) attrNames isFunction;
in
rec {
@ -29,8 +29,8 @@ rec {
For another application, see build-support/vm, where this
function is used to build arbitrary derivations inside a QEMU
virtual machine. */
virtual machine.
*/
overrideDerivation = drv: f:
let
newDrv = derivation (drv.drvAttrs // (f drv));
@ -56,13 +56,21 @@ rec {
makeOverridable = f: origArgs:
let
ff = f origArgs;
overrideWith = newArgs: origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs);
in
if builtins.isAttrs ff then (ff //
{ override = newArgs:
makeOverridable f (origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs));
{ override = newArgs: makeOverridable f (overrideWith newArgs);
deepOverride = newArgs:
makeOverridable f (lib.overrideExisting (lib.mapAttrs (deepOverrider newArgs) origArgs) newArgs);
overrideDerivation = fdrv:
makeOverridable (args: overrideDerivation (f args) fdrv) origArgs;
})
else if builtins.isFunction ff then
{ override = newArgs: makeOverridable f (overrideWith newArgs);
__functor = self: ff;
deepOverride = throw "deepOverride not yet supported for functors";
overrideDerivation = throw "overrideDerivation not yet supported for functors";
}
else ff;
deepOverrider = newArgs: name: x: if builtins.isAttrs x then (
@ -93,8 +101,11 @@ rec {
};
*/
callPackageWith = autoArgs: fn: args:
let f = if builtins.isFunction fn then fn else import fn; in
makeOverridable f ((builtins.intersectAttrs (builtins.functionArgs f) autoArgs) // args);
let
f = if builtins.isFunction fn then fn else import fn;
auto = builtins.intersectAttrs (builtins.functionArgs f) autoArgs;
in makeOverridable f (auto // args);
/* Add attributes to each output of a derivation without changing the derivation itself */
addPassthru = drv: passthru:
@ -107,10 +118,44 @@ rec {
outputToAttrListElement = outputName:
{ name = outputName;
value = commonAttrs // {
inherit (builtins.getAttr outputName drv) outPath drvPath type outputName;
inherit (drv.${outputName}) outPath drvPath type outputName;
};
};
outputsList = map outputToAttrListElement outputs;
in builtins.getAttr drv.outputName commonAttrs;
in commonAttrs.${drv.outputName};
/* Strip a derivation of all non-essential attributes, returning
only those needed by hydra-eval-jobs. Also strictly evaluate the
result to ensure that there are no thunks kept alive to prevent
garbage collection. */
hydraJob = drv:
let
outputs = drv.outputs or ["out"];
commonAttrs =
{ inherit (drv) name system meta; inherit outputs; }
// lib.optionalAttrs (drv._hydraAggregate or false) {
_hydraAggregate = true;
constituents = map hydraJob (lib.flatten drv.constituents);
}
// (lib.listToAttrs outputsList);
makeOutput = outputName:
let output = drv.${outputName}; in
{ name = outputName;
value = commonAttrs // {
outPath = output.outPath;
drvPath = output.drvPath;
type = "derivation";
inherit outputName;
};
};
outputsList = map makeOutput outputs;
drv' = (lib.head outputsList).value;
in lib.deepSeq drv' drv';
}

@ -9,23 +9,16 @@ in
rec {
inherit (builtins) addErrorContext;
addErrorContextToAttrs = lib.mapAttrs (a: v: lib.addErrorContext "while evaluating ${a}" v);
traceIf = p: msg: x: if p then trace msg x else x;
traceVal = x: trace x x;
traceXMLVal = x: trace (builtins.toXML x) x;
traceXMLValMarked = str: x: trace (str + builtins.toXML x) x;
# Wrapper aroung the primop `addErrorContext', which shouldn't used
# directly. It evaluates and returns `val', but if an evaluation
# error occurs, the text in `msg' is added to the error context
# (stack trace) printed by Nix.
addErrorContext =
if builtins ? addErrorContext
then builtins.addErrorContext
else msg: val: val;
addErrorContextToAttrs = lib.mapAttrs (a : v : lib.addErrorContext "while evaluating ${a}" v);
traceVal = if builtins ? trace then x: (builtins.trace x x) else x: x;
traceXMLVal = if builtins ? trace then x: (builtins.trace (builtins.toXML x) x) else x: x;
traceXMLValMarked = str: if builtins ? trace then x: (builtins.trace ( str + builtins.toXML x) x) else x: x;
# this can help debug your code as well - designed to not produce thousands of lines
traceShowVal = x : trace (showVal x) x;
traceShowValMarked = str: x: trace (str + showVal x) x;
@ -44,12 +37,13 @@ rec {
else if isString x then "x is a string `${substring 0 50 x}...'"
else "x is probably a path `${substring 0 50 (toString x)}...'";
# trace the arguments passed to function and its result
# trace the arguments passed to function and its result
# maybe rewrite these functions in a traceCallXml like style. Then one function is enough
traceCall = n : f : a : let t = n2 : x : traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a));
traceCall2 = n : f : a : b : let t = n2 : x : traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a) (t "arg 2" b));
traceCall3 = n : f : a : b : c : let t = n2 : x : traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a) (t "arg 2" b) (t "arg 3" c));
# FIXME: rename this?
traceValIfNot = c: x:
if c x then true else trace (showVal x) false;
@ -70,7 +64,7 @@ rec {
then [ { inherit name; expected = test.expected; result = test.expr; } ]
else [] ) tests));
# create a test assuming that list elements are true
# usage: { testX = allTrue [ true ]; }
testAllTrue = expr : { inherit expr; expected = map (x: true) expr; };
@ -109,11 +103,11 @@ rec {
let nr = a;
in (str: expr:
if isFunction expr then
(arg:
(arg:
traceCallXml (builtins.add 1 nr) "${str}\n arg ${builtins.toString nr} is \n ${builtins.toXML (strict arg)}" (expr arg)
)
else
else
let r = strict expr;
in builtins.trace "${str}\n result:\n${builtins.toXML r}" r
in trace "${str}\n result:\n${builtins.toXML r}" r
);
}

@ -1,283 +1,441 @@
let
lib = import ./default.nix;
spdx = lic: lic // {
url = "http://spdx.org/licenses/${lic.shortName}";
};
url = "http://spdx.org/licenses/${lic.spdxId}";
};
in
rec {
lib.mapAttrs (n: v: v // { shortName = n; }) rec {
/* License identifiers from spdx.org where possible.
* If you cannot find your license here, then look for a similar license or
* add it to this list. The URL mentioned above is a good source for inspiration.
*/
afl21 = spdx {
spdxId = "AFL-2.1";
fullName = "Academic Free License";
};
agpl3 = spdx {
shortName = "AGPL-3.0";
spdxId = "AGPL-3.0";
fullName = "GNU Affero General Public License v3.0";
};
agpl3Plus = {
shortName = "AGPL-3.0+";
fullName = "GNU Affero General Public License v3.0 or later";
inherit (agpl3) url;
};
amazonsl = {
fullName = "Amazon Software License";
url = http://aws.amazon.com/asl/;
free = false;
};
amd = {
shortName = "amd";
fullName = "AMD License Agreement";
url = http://developer.amd.com/amd-license-agreement/;
};#
};
apsl20 = spdx {
shortName = "APSL-2.0";
spdxId = "APSL-2.0";
fullName = "Apple Public Source License 2.0";
};
artistic1 = spdx {
spdxId = "Artistic-1.0";
fullName = "Artistic License 1.0";
};
artistic2 = spdx {
shortName = "Artistic-2.0";
spdxId = "Artistic-2.0";
fullName = "Artistic License 2.0";
};
asl20 = spdx {
shortName = "Apache-2.0";
spdxId = "Apache-2.0";
fullName = "Apache License 2.0";
};
boost = spdx {
shortName = "BSL-1.0";
spdxId = "BSL-1.0";
fullName = "Boost Software License 1.0";
};
bsd2 = spdx {
shortName = "BSD-2-Clause";
spdxId = "BSD-2-Clause";
fullName = ''BSD 2-clause "Simplified" License'';
};
bsd3 = spdx {
shortName = "BSD-3-Clause";
spdxId = "BSD-3-Clause";
fullName = ''BSD 3-clause "New" or "Revised" License'';
};
bsdOriginal = spdx {
shortName = "BSD-4-Clause";
spdxId = "BSD-4-Clause";
fullName = ''BSD 4-clause "Original" or "Old" License'';
};
cc0 = spdx {
shortName = "CC0-1.0";
fullName = ''Creative Commons Zero v1.0 Universal'';
spdxId = "CC0-1.0";
fullName = "Creative Commons Zero v1.0 Universal";
};
cc-by-30 = spdx {
shortName = "CC-BY-3.0";
spdxId = "CC-BY-3.0";
fullName = "Creative Commons Attribution 3.0";
};
cc-by-sa-30 = spdx {
spdxId = "CC-BY-SA-3.0";
fullName = "Creative Commons Attribution Share Alike 3.0";
};
cc-by-40 = spdx {
spdxId = "CC-BY-4.0";
fullName = "Creative Commons Attribution 4.0";
};
cc-by-sa-40 = spdx {
spdxId = "CC-BY-SA-4.0";
fullName = "Creative Commons Attribution Share Alike 4.0";
};
cddl = spdx {
shortName = "CDDL-1.0";
spdxId = "CDDL-1.0";
fullName = "Common Development and Distribution License 1.0";
};
cecill20 = spdx {
spdxId = "CECILL-2.0";
fullName = "CeCILL Free Software License Agreement v2.0";
};
cecill-b = spdx {
spdxId = "CECILL-B";
fullName = "CeCILL-B Free Software License Agreement";
};
cecill-c = spdx {
shortName = "CECILL-C";
spdxId = "CECILL-C";
fullName = "CeCILL-C Free Software License Agreement";
};
cpl10 = spdx {
shortName = "CPL-1.0";
spdxId = "CPL-1.0";
fullName = "Common Public License 1.0";
};
efl10 = spdx {
spdxId = "EFL-1.0";
fullName = "Eiffel Forum License v1.0";
};
efl20 = spdx {
spdxId = "EFL-2.0";
fullName = "Eiffel Forum License v2.0";
};
epl10 = spdx {
shortName = "EPL-1.0";
spdxId = "EPL-1.0";
fullName = "Eclipse Public License 1.0";
};
free = "free";
fdl12 = spdx {
spdxId = "GFDL-1.2";
fullName = "GNU Free Documentation License v1.2";
};
free = {
fullName = "Unspecified free software license";
};
gpl1 = spdx {
spdxId = "GPL-1.0";
fullName = "GNU General Public License v1.0 only";
};
gpl1Plus = spdx {
spdxId = "GPL-1.0+";
fullName = "GNU General Public License v1.0 or later";
};
gpl2 = spdx {
shortName = "GPL-2.0";
spdxId = "GPL-2.0";
fullName = "GNU General Public License v2.0 only";
};
gpl2ClasspathPlus = {
fullName = "GNU General Public License v2.0 or later (with Classpath exception)";
url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception;
};
gpl2Oss = {
shortName = "GPL-2.0-with-OSS";
fullName = "GNU General Public License version 2 only (with OSI approved licenses linking exception)";
url = http://www.mysql.com/about/legal/licensing/foss-exception;
};
gpl2Plus = spdx {
shortName = "GPL-2.0+";
spdxId = "GPL-2.0+";
fullName = "GNU General Public License v2.0 or later";
};
gpl3 = spdx {
shortName = "GPL-3.0";
spdxId = "GPL-3.0";
fullName = "GNU General Public License v3.0 only";
};
gpl3Plus = spdx {
shortName = "GPL-3.0+";
spdxId = "GPL-3.0+";
fullName = "GNU General Public License v3.0 or later";
};
gpl3ClasspathPlus = {
shortName = "GPL-3.0+-with-classpath-exception";
fullName = "GNU General Public License v3.0 or later (with Classpath exception)";
url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception;
};
# Intel's license, seems free
iasl = {
fullName = "iASL";
url = http://www.calculate-linux.org/packages/licenses/iASL;
};
ijg = spdx {
spdxId = "IJG";
fullName = "Independent JPEG Group License";
};
inria = {
shortName = "INRIA-NCLA";
fullName = "INRIA Non-Commercial License Agreement";
url = "http://compcert.inria.fr/doc/LICENSE";
};
ipa = spdx {
shortName = "IPA";
spdxId = "IPA";
fullName = "IPA Font License";
};
ipl10 = spdx {
shortName = "IPL-1.0";
spdxId = "IPL-1.0";
fullName = "IBM Public License v1.0";
};
isc = spdx {
shortName = "ISC";
spdxId = "ISC";
fullName = "ISC License";
};
lgpl2 = spdx {
shortName = "LGPL-2.0";
spdxId = "LGPL-2.0";
fullName = "GNU Library General Public License v2 only";
};
lgpl2Plus = spdx {
shortName = "LGPL-2.0+";
spdxId = "LGPL-2.0+";
fullName = "GNU Library General Public License v2 or later";
};
lgpl21 = spdx {
shortName = "LGPL-2.1";
spdxId = "LGPL-2.1";
fullName = "GNU Library General Public License v2.1 only";
};
lgpl21Plus = spdx {
shortName = "LGPL-2.1+";
spdxId = "LGPL-2.1+";
fullName = "GNU Library General Public License v2.1 or later";
};
lgpl3 = spdx {
shortName = "LGPL-3.0";
spdxId = "LGPL-3.0";
fullName = "GNU Lesser General Public License v3.0 only";
};
lgpl3Plus = spdx {
shortName = "LGPL-3.0+";
spdxId = "LGPL-3.0+";
fullName = "GNU Lesser General Public License v3.0 or later";
};
libtiff = {
shortName = "libtiff";
fullName = "libtiff license";
url = https://fedoraproject.org/wiki/Licensing/libtiff;
libpng = spdx {
spdxId = "Libpng";
fullName = "libpng License";
};
libtiff = spdx {
spdxId = "libtiff";
fullName = "libtiff License";
};
llgpl21 = {
shortName = "LLGPL-2.1";
fullName = "Lisp LGPL; GNU Lesser General Public License version 2.1 with Franz Inc. preamble for clarification of LGPL terms in context of Lisp";
url = http://opensource.franz.com/preamble.html;
};
lppl12 = spdx {
spdxId = "LPPL-1.2";
fullName = "LaTeX Project Public License v1.2";
};
lppl13c = spdx {
spdxId = "LPPL-1.3c";
fullName = "LaTeX Project Public License v1.3c";
};
lpl-102 = spdx {
shortName = "LPL-1.02";
spdxId = "LPL-1.02";
fullName = "Lucent Public License v1.02";
};
# spdx.org does not (yet) differentiate between the X11 and Expat versions
# for details see http://en.wikipedia.org/wiki/MIT_License#Various_versions
mit = spdx {
shortName = "MIT";
spdxId = "MIT";
fullName = "MIT License";
};
mpl10 = spdx {
spdxId = "MPL-1.0";
fullName = "Mozilla Public License 1.0";
};
mpl11 = spdx {
shortName = "MPL-1.1";
spdxId = "MPL-1.1";
fullName = "Mozilla Public License 1.1";
};
mpl20 = spdx {
shortName = "MPL-2.0";
spdxId = "MPL-2.0";
fullName = "Mozilla Public License 2.0";
};
msrla = {
shortName = "MSR-LA";
fullName = "Microsoft Research License Agreement";
url = "http://research.microsoft.com/en-us/projects/pex/msr-la.txt";
};
ncsa = spdx {
shortName = "NCSA";
spdxId = "NCSA";
fullName = "University of Illinois/NCSA Open Source License";
};
ofl = spdx {
shortName = "OFL-1.1";
spdxId = "OFL-1.1";
fullName = "SIL Open Font License 1.1";
};
openssl = spdx {
shortName = "OpenSSL";
spdxId = "OpenSSL";
fullName = "OpenSSL License";
};
php301 = spdx {
spdxId = "PHP-3.01";
fullName = "PHP License v3.01";
};
postgresql = spdx {
spdxId = "PostgreSQL";
fullName = "PostgreSQL License";
};
psfl = spdx {
shortName = "Python-2.0";
spdxId = "Python-2.0";
fullName = "Python Software Foundation License version 2";
#url = http://docs.python.org/license.html;
};
publicDomain = {
shortName = "Public Domain";
fullname = "Public Domain";
fullName = "Public Domain";
};
qpl = spdx {
spdxId = "QPL-1.0";
fullName = "Q Public License 1.0";
};
qwt = {
fullName = "Qwt License, Version 1.0";
url = http://qwt.sourceforge.net/qwtlicense.html;
};
ruby = spdx {
spdxId = "Ruby";
fullName = "Ruby License";
};
sgi-b-20 = spdx {
spdxId = "SGI-B-2.0";
fullName = "SGI Free Software License B v2.0";
};
sleepycat = spdx {
shortName = "Sleepycat";
fullName = "Sleepycat License";
spdxId = "Sleepycat";
fullName = "Sleepycat License";
};
tcltk = {
shortName = "Tcl/Tk";
fullName = "Tcl/Tk license";
url = http://www.tcl.tk/software/tcltk/license.html;
tcltk = spdx {
spdxId = "TCL";
fullName = "TCL/TK License";
};
unfree = "unfree";
unfree = {
fullName = "Unfree";
free = false;
};
unfreeRedistributable = "unfree-redistributable";
unfreeRedistributable = {
fullName = "Unfree redistributable";
free = false;
};
unfreeRedistributableFirmware = "unfree-redistributable-firmware";
unfreeRedistributableFirmware = {
fullName = "Unfree redistributable firmware";
# Note: we currently consider these "free" for inclusion in the
# channel and NixOS images.
};
unlicense = spdx {
spdxId = "Unlicense";
fullName = "The Unlicense";
};
vsl10 = spdx {
spdxId = "VSL-1.0";
fullName = "Vovida Software License v1.0";
};
w3c = spdx {
spdxId = "W3C";
fullName = "W3C Software Notice and License";
};
wadalab = {
shortName = "wadalab";
fullName = "Wadalab Font License";
url = https://fedoraproject.org/wiki/Licensing:Wadalab?rd=Licensing/Wadalab;
};
wtfpl = spdx {
spdxId = "WTFPL";
fullName = "Do What The F*ck You Want To Public License";
};
zlib = spdx {
shortName = "Zlib";
spdxId = "Zlib";
fullName = "zlib License";
};
zpt20 = spdx { # FIXME: why zpt* instead of zpl*
shortName = "ZPL-2.0";
spdxId = "ZPL-2.0";
fullName = "Zope Public License 2.0";
};
zpt21 = spdx {
shortName = "ZPL-2.1";
spdxId = "ZPL-2.1";
fullName = "Zope Public License 2.1";
};
}

@ -2,13 +2,7 @@
with import ./trivial.nix;
let
inc = builtins.add 1;
dec = n: builtins.sub n 1;
in rec {
rec {
inherit (builtins) head tail length isList elemAt concatLists filter elem;
@ -29,7 +23,7 @@ in rec {
fold' = n:
if n == len
then nul
else op (elemAt list n) (fold' (inc n));
else op (elemAt list n) (fold' (n + 1));
in fold' 0;
# Left fold: `fold op nul [x_1 x_2 ... x_n] == op (... (op (op nul
@ -38,12 +32,10 @@ in rec {
let
len = length list;
foldl' = n:
if n == minus1
if n == -1
then nul
else op (foldl' (dec n)) (elemAt list n);
in foldl' (dec (length list));
minus1 = dec 0;
else op (foldl' (n - 1)) (elemAt list n);
in foldl' (length list - 1);
# map with index: `imap (i: v: "${v}-${toString i}") ["a" "b"] ==
@ -54,7 +46,7 @@ in rec {
imap' = n:
if n == len
then []
else [ (f (inc n) (elemAt list n)) ] ++ imap' (inc n);
else [ (f (n + 1) (elemAt list n)) ] ++ imap' (n + 1);
in imap' 0;
@ -104,7 +96,7 @@ in rec {
# Count how many times function `pred' returns true for the elements
# of `list'.
count = pred: fold (x: c: if pred x then inc c else c) 0;
count = pred: fold (x: c: if pred x then c + 1 else c) 0;
# Return a singleton list or an empty list, depending on a boolean
@ -125,9 +117,9 @@ in rec {
# Return a list of integers from `first' up to and including `last'.
range = first: last:
if lessThan last first
if last < first
then []
else [first] ++ range (add first 1) last;
else [first] ++ range (first + 1) last;
# Partition the elements of a list in two lists, `right' and
@ -144,11 +136,11 @@ in rec {
let
len1 = length fst;
len2 = length snd;
len = if lessThan len1 len2 then len1 else len2;
len = if len1 < len2 then len1 else len2;
zipListsWith' = n:
if n != len then
[ (f (elemAt fst n) (elemAt snd n)) ]
++ zipListsWith' (inc n)
++ zipListsWith' (n + 1)
else [];
in zipListsWith' 0;
@ -167,7 +159,7 @@ in rec {
let
len = length list;
first = head list;
pivot' = n: acc@{ left, right }: let el = elemAt list n; next = pivot' (inc n); in
pivot' = n: acc@{ left, right }: let el = elemAt list n; next = pivot' (n + 1); in
if n == len
then acc
else if strictLess first el
@ -176,7 +168,7 @@ in rec {
next { left = [ el ] ++ left; inherit right; };
pivot = pivot' 1 { left = []; right = []; };
in
if lessThan len 2 then list
if len < 2 then list
else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right);
@ -188,7 +180,7 @@ in rec {
if n == len || n == count
then []
else
[ (elemAt list n) ] ++ take' (inc n);
[ (elemAt list n) ] ++ take' (n + 1);
in take' 0;
@ -197,16 +189,20 @@ in rec {
let
len = length list;
drop' = n:
if n == minus1 || lessThan n count
if n == -1 || n < count
then []
else
drop' (dec n) ++ [ (elemAt list n) ];
in drop' (dec len);
drop' (n - 1) ++ [ (elemAt list n) ];
in drop' (len - 1);
# Return the last element of a list.
last = list:
assert list != []; elemAt list (dec (length list));
assert list != []; elemAt list (length list - 1);
# Return all elements but the last
init = list: assert list != []; take (length list - 1) list;
# Zip two lists together.
@ -214,11 +210,11 @@ in rec {
let
len1 = length xs;
len2 = length ys;
len = if lessThan len1 len2 then len1 else len2;
len = if len1 < len2 then len1 else len2;
zipTwoLists' = n:
if n != len then
[ { first = elemAt xs n; second = elemAt ys n; } ]
++ zipTwoLists' (inc n)
++ zipTwoLists' (n + 1)
else [];
in zipTwoLists' 0;
@ -227,4 +223,19 @@ in rec {
crossLists = f: foldl (fs: args: concatMap (f: map f args) fs) [f];
# Remove duplicate elements from the list
unique = list:
if list == [] then
[]
else
let
x = head list;
xs = unique (drop 1 list);
in [x] ++ remove x xs;
# Intersects list 'e' and another list
intersectLists = e: filter (x: elem x e);
# Subtracts list 'e' from another list
subtractLists = e: filter (x: !(elem x e));
}

@ -5,7 +5,10 @@
alphabetically sorted. */
_1126 = "Christian Lask <mail@elfsechsundzwanzig.de>";
abaldeau = "Andreas Baldeau <andreas@baldeau.net>";
abbradar = "Nikolay Amiantov <ab@fmap.me>";
aforemny = "Alexander Foremny <alexanderforemny@googlemail.com>";
aherrmann = "Andreas Herrmann <andreash87@gmx.ch>";
ak = "Alexander Kjeldaas <ak@formalprivacy.com>";
akc = "Anders Claesson <akc@akc.is>";
algorith = "Dries Van Daele <dries_van_daele@telenet.be>";
@ -15,52 +18,100 @@
AndersonTorres = "Anderson Torres <torres.anderson.85@gmail.com>";
andres = "Andres Loeh <ksnixos@andres-loeh.de>";
antono = "Antono Vasiljev <self@antono.info>";
ardumont = "Antoine R. Dumont <eniotna.t@gmail.com>";
aristid = "Aristid Breitkreuz <aristidb@gmail.com>";
arobyn = "Alexei Robyn <shados@shados.net>";
asppsa = "Alastair Pharo <asppsa@gmail.com>";
astsmtl = "Alexander Tsamutali <astsmtl@yandex.ru>";
aszlig = "aszlig <aszlig@redmoonstudios.org>";
auntie = "Jonathan Glines <auntieNeo@gmail.com>";
aycanirican = "Aycan iRiCAN <iricanaycan@gmail.com>";
balajisivaraman = "Balaji Sivaraman<sivaraman.balaji@gmail.com>";
bbenoist = "Baptist BENOIST <return_0@live.com>";
bcdarwin = "Ben Darwin <bcdarwin@gmail.com>";
bdimcheff = "Brandon Dimcheff <brandon@dimcheff.com>";
bennofs = "Benno Fünfstück <benno.fuenfstueck@gmail.com>";
benley = "Benjamin Staffin <benley@gmail.com>";
berdario = "Dario Bertini <berdario@gmail.com>";
bergey = "Daniel Bergey <bergey@teallabs.org>";
bjg = "Brian Gough <bjg@gnu.org>";
bjornfor = "Bjørn Forsman <bjorn.forsman@gmail.com>";
bluescreen303 = "Mathijs Kwik <mathijs@bluescreen303.nl>";
bobvanderlinden = "Bob van der Linden <bobvanderlinden@gmail.com>";
bodil = "Bodil Stokke <nix@bodil.org>";
boothead = "Ben Ford <ben@perurbis.com>";
bosu = "Boris Sukholitko <boriss@gmail.com>";
bstrik = "Berno Strik <dutchman55@gmx.com>";
calrama = "Moritz Maxeiner <moritz@ucworks.org>";
campadrenalin = "Philip Horger <campadrenalin@gmail.com>";
cdepillabout = "Dennis Gosnell <cdep.illabout@gmail.com>";
cfouche = "Chaddaï Fouché <chaddai.fouche@gmail.com>";
chaoflow = "Florian Friesdorf <flo@chaoflow.net>";
christopherpoole = "Christopher Mark Poole <mail@christopherpoole.net>";
coconnor = "Corey O'Connor <coreyoconnor@gmail.com>";
cocreature = "Moritz Kiefer <moritz.kiefer@purelyfunctional.org>";
codyopel = "Cody Opel <codyopel@gmail.com>";
copumpkin = "Dan Peebles <pumpkingod@gmail.com>";
coroa = "Jonas Hörsch <jonas@chaoflow.net>";
cstrahan = "Charles Strahan <charles.c.strahan@gmail.com>";
cwoac = "Oliver Matthews <oliver@codersoffortune.net>";
DamienCassou = "Damien Cassou <damien.cassou@gmail.com>";
davidrusu = "David Rusu <davidrusu.me@gmail.com>";
dbohdan = "Danyil Bohdan <danyil.bohdan@gmail.com>";
DerGuteMoritz = "Moritz Heidkamp <moritz@twoticketsplease.de>";
devhell = "devhell <\"^\"@regexmail.net>";
dmalikov = "Dmitry Malikov <malikov.d.y@gmail.com>";
doublec = "Chris Double <chris.double@double.co.nz>";
ederoyd46 = "Matthew Brown <matt@ederoyd.co.uk>";
eduarrrd = "Eduard Bachmakov <e.bachmakov@gmail.com>";
edwtjo = "Edward Tjörnhammar <ed@cflags.cc>";
eelco = "Eelco Dolstra <eelco.dolstra@logicblox.com>";
eikek = "Eike Kettner <eike.kettner@posteo.de>";
ellis = "Ellis Whitehead <nixos@ellisw.net>";
emery = "Emery Hemingway <emery@vfemail.net>";
ertes = "Ertugrul Söylemez <ertesx@gmx.de>";
exlevan = "Alexey Levan <exlevan@gmail.com>";
falsifian = "James Cook <james.cook@utoronto.ca>";
flosse = "Markus Kohlhase <mail@markus-kohlhase.de>";
fluffynukeit = "Daniel Austin <dan@fluffynukeit.com>";
fpletz = "Franz Pletz <fpletz@fnordicwalking.de>";
ftrvxmtrx = "Siarhei Zirukin <ftrvxmtrx@gmail.com>";
funfunctor = "Edward O'Callaghan <eocallaghan@alterapraxis.com>";
fuuzetsu = "Mateusz Kowalczyk <fuuzetsu@fuuzetsu.co.uk>";
gal_bolle = "Florent Becker <florent.becker@ens-lyon.org>";
garbas = "Rok Garbas <rok@garbas.si>";
garrison = "Jim Garrison <jim@garrison.cc>";
gavin = "Gavin Rogers <gavin@praxeology.co.uk>";
gebner = "Gabriel Ebner <gebner@gebner.org>";
giogadi = "Luis G. Torres <lgtorres42@gmail.com>";
globin = "Robin Gloster <robin@glob.in>";
goibhniu = "Cillian de Róiste <cillian.deroiste@gmail.com>";
gridaphobe = "Eric Seidel <eric@seidel.io>";
guibert = "David Guibert <david.guibert@gmail.com>";
henrytill = "Henry Till <henrytill@gmail.com>";
hinton = "Tom Hinton <t@larkery.com>";
hrdinka = "Christoph Hrdinka <c.nix@hrdinka.at>";
iand675 = "Ian Duncan <ian@iankduncan.com>";
ianwookim = "Ian-Woo Kim <ianwookim@gmail.com>";
iElectric = "Domen Kozar <domen@dev.si>";
iyzsong = "Song Wenwu <iyzsong@gmail.com>";
j-keck = "Jürgen Keck <jhyphenkeck@gmail.com>";
jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>";
jb55 = "William Casarin <bill@casarin.me>";
jcumming = "Jack Cummings <jack@mudshark.org>";
jgeerds = "Jascha Geerds <jg@ekby.de>";
jirkamarsik = "Jirka Marsik <jiri.marsik89@gmail.com>";
joachifm = "Joachim Fasting <joachifm@fastmail.fm>";
joamaki = "Jussi Maki <joamaki@gmail.com>";
joelmo = "Joel Moberg <joel.moberg@gmail.com>";
joelteon = "Joel Taylor <me@joelt.io>";
jpbernardy = "Jean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com>";
jwiegley = "John Wiegley <johnw@newartisans.com>";
jzellner = "Jeff Zellner <jeffz@eml.cc>";
kkallio = "Karn Kallio <tierpluspluslists@gmail.com>";
koral = "Koral <koral@mailoo.org>";
kovirobi = "Kovacsics Robert <kovirobi@gmail.com>";
kragniz = "Louis Taylor <kragniz@gmail.com>";
ktosiek = "Tomasz Kontusz <tomasz.kontusz@gmail.com>";
lethalman = "Luca Bruno <lucabru@src.gnome.org>";
lhvwb = "Nathaniel Baxter <nathaniel.baxter@gmail.com>";
@ -68,63 +119,109 @@
lovek323 = "Jason O'Conal <jason@oconal.id.au>";
ludo = "Ludovic Courtès <ludo@gnu.org>";
madjar = "Georges Dubus <georges.dubus@compiletoi.net>";
magnetophon = "Bart Brouns <bart@magnetophon.nl>";
malyn = "Michael Alyn Miller <malyn@strangeGizmo.com>";
manveru = "Michael Fellinger <m.fellinger@gmail.com>";
marcweber = "Marc Weber <marco-oweber@gmx.de>";
matejc = "Matej Cotman <cotman.matej@gmail.com>";
matthiasbeyer = "Matthias Beyer <mail@beyermatthias.de>";
meditans = "Carlo Nucera <meditans@gmail.com>";
meisternu = "Matt Miemiec <meister@krutt.org>";
michelk = "Michel Kuhlmann <michel@kuhlmanns.info>";
modulistic = "Pablo Costa <modulistic@gmail.com>";
mornfall = "Petr Ročkai <me@mornfall.net>";
MP2E = "Cray Elliott <MP2E@archlinux.us>";
msackman = "Matthew Sackman <matthew@wellquite.org>";
mtreskin = "Max Treskin <zerthurd@gmail.com>";
muflax = "Stefan Dorn <mail@muflax.com>";
nathan-gs = "Nathan Bijnens <nathan@nathan.gs>";
nckx = "Tobias Geerinckx-Rice <tobias.geerinckx.rice@gmail.com>";
notthemessiah = "Brian Cohen <brian.cohen.88@gmail.com>";
np = "Nicolas Pouillard <np.nix@nicolaspouillard.fr>";
nslqqq = "Nikita Mikhailov <nslqqq@gmail.com>";
obadz = "obadz <dav-nixos@odav.org>";
ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
offline = "Jaka Hudoklin <jakahudoklin@gmail.com>";
olcai = "Erik Timan <dev@timan.info>";
orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
page = "Carles Pagès <page@cubata.homelinux.net>";
paholg = "Paho Lurie-Gregg <paho@paholg.com>";
pakhfn = "Fedor Pakhomov <pakhfn@gmail.com>";
pashev = "Igor Pashev <pashev.igor@gmail.com>";
phausmann = "Philipp Hausmann <nix@314.ch>";
phreedom = "Evgeny Egorochkin <phreedom@yandex.ru>";
pierron = "Nicolas B. Pierron <nixos@nbp.name>";
piotr = "Piotr Pietraszkiewicz <ppietrasa@gmail.com>";
pjones = "Peter Jones <pjones@devalot.com>";
pkmx = "Chih-Mao Chen <pkmx.tw@gmail.com>";
plcplc = "Philip Lykke Carlsen <plcplc@gmail.com>";
pmahoney = "Patrick Mahoney <pat@polycrystal.org>";
prikhi = "Pavan Rikhi <pavan.rikhi@gmail.com>";
pSub = "Pascal Wittmann <mail@pascal-wittmann.de>";
puffnfresh = "Brian McKenna <brian@brianmckenna.org>";
qknight = "Joachim Schiele <js@lastlog.de>";
ragge = "Ragnar Dahlen <r.dahlen@gmail.com>";
raskin = "Michael Raskin <7c6f434c@mail.ru>";
redbaron = "Maxim Ivanov <ivanov.maxim@gmail.com>";
refnil = "Martin Lavoie <broemartino@gmail.com>";
relrod = "Ricky Elrod <ricky@elrod.me>";
renzo = "Renzo Carbonara <renzocarbonara@gmail.com>";
rickynils = "Rickard Nilsson <rickynils@gmail.com>";
rob = "Rob Vermaas <rob.vermaas@gmail.com>";
robberer = "Longrin Wischnewski <robberer@freakmail.de>";
roconnor = "Russell O'Connor <roconnor@theorem.ca>";
roelof = "Roelof Wobben <rwobben@hotmail.com>";
romildo = "José Romildo Malaquias <malaquias@gmail.com>";
rszibele = "Richard Szibele <richard_szibele@hotmail.com>";
rushmorem = "Rushmore Mushambi <rushmore@webenchanter.com>";
rycee = "Robert Helgesson <robert@rycee.net>";
sander = "Sander van der Burg <s.vanderburg@tudelft.nl>";
schmitthenner = "Fabian Schmitthenner <development@schmitthenner.eu>";
schristo = "Scott Christopher <schristopher@konputa.com>";
sepi = "Raffael Mancini <raffael@mancini.lu>";
shell = "Shell Turner <cam.turn@gmail.com>";
shlevy = "Shea Levy <shea@shealevy.com>";
simons = "Peter Simons <simons@cryp.to>";
sjagoe = "Simon Jagoe <simon@simonjagoe.com>";
sjmackenzie = "Stewart Mackenzie <setori88@gmail.com>";
skeidel = "Sven Keidel <svenkeidel@gmail.com>";
smironov = "Sergey Mironov <ierton@gmail.com>";
sprock = "Roger Mason <rmason@mun.ca>";
spwhitt = "Spencer Whitt <sw@swhitt.me>";
sztupi = "Attila Sztupak <attila.sztupak@gmail.com>";
tailhook = "Paul Colomiets <paul@colomiets.name>";
thammers = "Tobias Hammerschmidt <jawr@gmx.de>";
the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>";
theuni = "Christian Theune <ct@flyingcircus.io>";
thoughtpolice = "Austin Seipp <aseipp@pobox.com>";
titanous = "Jonathan Rudenberg <jonathan@titanous.com>";
tomberek = "Thomas Bereknyei <tomberek@gmail.com>";
trino = "Hubert Mühlhans <muehlhans.hubert@ekodia.de>";
tstrobel = "Thomas Strobel <ts468@cam.ac.uk>";
ttuegel = "Thomas Tuegel <ttuegel@gmail.com>";
tv = "Tomislav Viljetić <tv@shackspace.de>";
twey = "James Twey Kay <twey@twey.co.uk>";
urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>";
vandenoever = "Jos van den Oever <jos@vandenoever.info>";
vbgl = "Vincent Laporte <Vincent.Laporte@gmail.com>";
vbmithr = "Vincent Bernardoff <vb@luminar.eu.org>";
vcunat = "Vladimír Čunát <vcunat@gmail.com>";
viric = "Lluís Batlle i Rossell <viric@viric.name>";
vizanto = "Danny Wilson <danny@prime.vc>";
vlstill = "Vladimír Štill <xstill@fi.muni.cz>";
vmandela = "Venkateswara Rao Mandela <venkat.mandela@gmail.com>";
vozz = "Oliver Hunt <oliver.huntuk@gmail.com>";
winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>";
wizeman = "Ricardo M. Correia <rcorreia@wizy.org>";
wjlroe = "William Roe <willroe@gmail.com>";
wkennington = "William A. Kennington III <william@wkennington.com>";
wmertens = "Wout Mertens <Wout.Mertens@gmail.com>";
wscott = "Wayne Scott <wsc9tt@gmail.com>";
wyvie = "Elijah Rum <elijahrum@gmail.com>";
yarr = "Dmitry V. <savraz@gmail.com>";
z77z = "Marco Maggesi <maggesi@math.unifi.it>";
zef = "Zef Hemel <zef@zef.me>";
zimbatm = "zimbatm <zimbatm@zimbatm.com>";
zoomulator = "Kim Simmons <zoomulator@gmail.com>";
Gonzih = "Max Gonzih <gonzih@gmail.com>";
}

@ -1,5 +1,5 @@
let lib = import ./default.nix;
inherit (builtins) isFunction hasAttr getAttr head tail isList isAttrs isInt attrNames;
inherit (builtins) isFunction head tail isList isAttrs isInt attrNames;
in
@ -61,7 +61,7 @@ rec {
fun = n : x :
let newArgs = fixed :
let args = takeFixed fixed;
mergeFun = getAttr n args;
mergeFun = args.${n};
in if isAttrs x then (mergeFun args x)
else assert isFunction x;
mergeFun args (x ( args // { inherit fixed; }));
@ -102,15 +102,12 @@ rec {
# }
composedArgsAndFun = f: foldArgs defaultMerge f {};
# shortcut for attrByPath ["name"] default attrs
maybeAttrNullable = name: default: attrs:
if attrs == null then default else
if __hasAttr name attrs then (__getAttr name attrs) else default;
maybeAttrNullable = maybeAttr;
# shortcut for attrByPath ["name"] default attrs
maybeAttr = name: default: attrs:
if __hasAttr name attrs then (__getAttr name attrs) else default;
maybeAttr = name: default: attrs: attrs.${name} or default;
# Return the second argument if the first one is true or the empty version
@ -233,7 +230,7 @@ rec {
closePropagation = list: (uniqList {inputList = (innerClosePropagation [] list);});
# calls a function (f attr value ) for each record item. returns a list
mapAttrsFlatten = f : r : map (attr: f attr (builtins.getAttr attr r) ) (attrNames r);
mapAttrsFlatten = f : r : map (attr: f attr r.${attr}) (attrNames r);
# attribute set containing one attribute
nvs = name : value : listToAttrs [ (nameValuePair name value) ];
@ -250,10 +247,10 @@ rec {
# merge attributes with custom function handling the case that the attribute
# exists in both sets
mergeAttrsWithFunc = f : set1 : set2 :
fold (n: set : if (__hasAttr n set)
then setAttr set n (f (__getAttr n set) (__getAttr n set2))
fold (n: set : if set ? ${n}
then setAttr set n (f set.${n} set2.${n})
else set )
(set2 // set1) (__attrNames set2);
(set2 // set1) (attrNames set2);
# merging two attribute set concatenating the values of same attribute names
# eg { a = 7; } { a = [ 2 3 ]; } becomes { a = [ 7 2 3 ]; }
@ -270,15 +267,15 @@ rec {
overrideSnd ? [ "buildPhase" ]
} : attrs1 : attrs2 :
fold (n: set :
setAttr set n ( if (__hasAttr n set)
setAttr set n ( if set ? ${n}
then # merge
if elem n mergeLists # attribute contains list, merge them by concatenating
then (__getAttr n attrs2) ++ (__getAttr n attrs1)
then attrs2.${n} ++ attrs1.${n}
else if elem n overrideSnd
then __getAttr n attrs1
then attrs1.${n}
else throw "error mergeAttrsNoOverride, attribute ${n} given in both attributes - no merge func defined"
else __getAttr n attrs2 # add attribute not existing in attr1
)) attrs1 (__attrNames attrs2);
else attrs2.${n} # add attribute not existing in attr1
)) attrs1 (attrNames attrs2);
# example usage:
@ -300,14 +297,14 @@ rec {
fold lib.mergeAttrs {} [
x y
(mapAttrs ( a : v : # merge special names using given functions
if (hasAttr a x)
then if (hasAttr a y)
then v (getAttr a x) (getAttr a y) # both have attr, use merge func
else (getAttr a x) # only x has attr
else (getAttr a y) # only y has attr)
if x ? ${a}
then if y ? ${a}
then v x.${a} y.${a} # both have attr, use merge func
else x.${a} # only x has attr
else y.${a} # only y has attr)
) (removeAttrs mergeAttrBy2
# don't merge attrs which are neither in x nor y
(filter (a : (! hasAttr a x) && (! hasAttr a y) )
(filter (a: ! x ? ${a} && ! y ? ${a})
(attrNames mergeAttrBy2))
)
)
@ -403,7 +400,7 @@ rec {
// args2.cfg;
opts = attrValues (mapAttrs (a : v :
let v2 = if v ? set || v ? unset then v else { set = v; };
n = if (getAttr (flagName a) cfgWithDefaults) then "set" else "unset";
n = if cfgWithDefaults.${flagName a} then "set" else "unset";
attr = maybeAttr n {} v2; in
if (maybeAttr "assertion" true attr)
then attr

@ -9,28 +9,72 @@ rec {
/* Evaluate a set of modules. The result is a set of two
attributes: options: the nested set of all option declarations,
and config: the nested set of all option values. */
evalModules = { modules, prefix ? [], args ? {}, check ? true }:
and config: the nested set of all option values.
!!! Please think twice before adding to this argument list! The more
that is specified here instead of in the modules themselves the harder
it is to transparently move a set of modules to be a submodule of another
config (as the proper arguments need to be replicated at each call to
evalModules) and the less declarative the module set is. */
evalModules = { modules
, prefix ? []
, # This would be remove in the future, Prefer _module.args option instead.
args ? {}
, # This would be remove in the future, Prefer _module.check option instead.
check ? true
}:
let
args' = args // { lib = import ./.; } // result;
closed = closeModules modules args';
# This internal module declare internal options under the `_module'
# attribute. These options are fragile, as they are used by the
# module system to change the interpretation of modules.
internalModule = rec {
_file = ./modules.nix;
key = _file;
options = {
_module.args = mkOption {
type = types.attrsOf types.unspecified;
internal = true;
description = "Arguments passed to each module.";
};
_module.check = mkOption {
type = types.uniq types.bool;
internal = true;
default = check;
description = "Whether to check whether all option definitions have matching declarations.";
};
};
config = {
_module.args = args;
};
};
closed = closeModules (modules ++ [ internalModule ]) { inherit config options; lib = import ./.; };
# Note: the list of modules is reversed to maintain backward
# compatibility with the old module system. Not sure if this is
# the most sensible policy.
options = mergeModules prefix (reverseList closed);
# Traverse options and extract the option values into the final
# config set. At the same time, check whether all option
# definitions have matching declarations.
# !!! _module.check's value can't depend on any other config values
# without an infinite recursion. One way around this is to make the
# 'config' passed around to the modules be unconditionally unchecked,
# and only do the check in 'result'.
config = yieldConfig prefix options;
yieldConfig = prefix: set:
let res = removeAttrs (mapAttrs (n: v:
if isOption v then v.value
else yieldConfig (prefix ++ [n]) v) set) ["_definedNames"];
in
if check && set ? _definedNames then
if options._module.check.value && set ? _definedNames then
fold (m: res:
fold (name: res:
if hasAttr name set then res else throw "The option `${showOption (prefix ++ [name])}' defined in `${m.file}' does not exist.")
if set ? ${name} then res else throw "The option `${showOption (prefix ++ [name])}' defined in `${m.file}' does not exist.")
res m.names)
res set._definedNames
else
@ -43,7 +87,7 @@ rec {
let
toClosureList = file: parentKey: imap (n: x:
if isAttrs x || isFunction x then
unifyModuleSyntax file "${parentKey}:anon-${toString n}" (applyIfFunction x args)
unifyModuleSyntax file "${parentKey}:anon-${toString n}" (unpackSubmodule applyIfFunction x args)
else
unifyModuleSyntax (toString x) (toString x) (applyIfFunction (import x) args));
in
@ -58,7 +102,7 @@ rec {
if m ? config || m ? options then
let badAttrs = removeAttrs m ["imports" "options" "config" "key" "_file"]; in
if badAttrs != {} then
throw "Module `${key}' has an unsupported attribute `${head (attrNames badAttrs)}'."
throw "Module `${key}' has an unsupported attribute `${head (attrNames badAttrs)}'. This is caused by assignments to the top-level attributes `config' or `options'."
else
{ file = m._file or file;
key = toString m.key or key;
@ -74,7 +118,39 @@ rec {
config = removeAttrs m ["key" "_file" "require" "imports"];
};
applyIfFunction = f: arg: if isFunction f then f arg else f;
applyIfFunction = f: arg@{ config, options, lib }: if isFunction f then
let
# Module arguments are resolved in a strict manner when attribute set
# deconstruction is used. As the arguments are now defined with the
# config._module.args option, the strictness used on the attribute
# set argument would cause an infinite loop, if the result of the
# option is given as argument.
#
# To work-around the strictness issue on the deconstruction of the
# attributes set argument, we create a new attribute set which is
# constructed to satisfy the expected set of attributes. Thus calling
# a module will resolve strictly the attributes used as argument but
# not their values. The values are forwarding the result of the
# evaluation of the option.
requiredArgs = builtins.attrNames (builtins.functionArgs f);
extraArgs = builtins.listToAttrs (map (name: {
inherit name;
value = config._module.args.${name};
}) requiredArgs);
in f (extraArgs // arg)
else
f;
/* We have to pack and unpack submodules. We cannot wrap the expected
result of the function as we would no longer be able to list the arguments
of the submodule. (see applyIfFunction) */
unpackSubmodule = unpack: m: args:
if isType "submodule" m then
{ _file = m.file; } // (unpack m.submodule args)
else unpack m args;
packSubmodule = file: m:
{ _type = "submodule"; file = file; submodule = m; };
/* Merge a list of modules. This will recurse over the option
declarations in all modules, combining them into a single set.
@ -94,24 +170,21 @@ rec {
loc = prefix ++ [name];
# Get all submodules that declare ‘name’.
decls = concatLists (map (m:
if hasAttr name m.options
then [ { inherit (m) file; options = getAttr name m.options; } ]
if m.options ? ${name}
then [ { inherit (m) file; options = m.options.${name}; } ]
else []
) options);
# Get all submodules that define ‘name’.
defns = concatLists (map (m:
if hasAttr name m.config
if m.config ? ${name}
then map (config: { inherit (m) file; inherit config; })
(pushDownProperties (getAttr name m.config))
(pushDownProperties m.config.${name})
else []
) configs);
nrOptions = count (m: isOption m.options) decls;
# Process mkMerge and mkIf properties.
defns' = concatMap (m:
if hasAttr name m.config
then map (m': { inherit (m) file; value = m'; }) (dischargeProperties (getAttr name m.config))
else []
) configs;
# Extract the definitions for this loc
defns' = map (m: { inherit (m) file; value = m.config.${name}; })
(filter (m: m.config ? ${name}) configs);
in
if nrOptions == length decls then
let opt = fixupOptionType loc (mergeOptionDecls loc decls);
@ -132,20 +205,41 @@ rec {
The exception is the options attribute, which specifies
sub-options. These can be specified multiple times to allow one
module to add sub-options to an option declared somewhere else
(e.g. multiple modules define sub-options for fileSystems). */
(e.g. multiple modules define sub-options for fileSystems).
'loc' is the list of attribute names where the option is located.
'opts' is a list of modules. Each module has an options attribute which
correspond to the definition of 'loc' in 'opt.file'. */
mergeOptionDecls = loc: opts:
fold (opt: res:
if opt.options ? default && res ? default ||
opt.options ? example && res ? example ||
opt.options ? description && res ? description ||
opt.options ? apply && res ? apply ||
opt.options ? type && res ? type
# Accept to merge options which have identical types.
opt.options ? type && res ? type && opt.options.type.name != res.type.name
then
throw "The option `${showOption loc}' in `${opt.file}' is already declared in ${showFiles res.declarations}."
else
opt.options // res //
let
/* Add the modules of the current option to the list of modules
already collected. The options attribute except either a list of
submodules or a submodule. For each submodule, we add the file of the
current option declaration as the file use for the submodule. If the
submodule defines any filename, then we ignore the enclosing option file. */
options' = toList opt.options.options;
coerceOption = file: opt:
if isFunction opt then packSubmodule file opt
else packSubmodule file { options = opt; };
getSubModules = opt.options.type.getSubModules or null;
submodules =
if getSubModules != null then map (packSubmodule opt.file) getSubModules ++ res.options
else if opt.options ? options then map (coerceOption opt.file) options' ++ res.options
else res.options;
in opt.options // res //
{ declarations = [opt.file] ++ res.declarations;
options = if opt.options ? options then [(toList opt.options.options ++ res.options)] else [];
options = submodules;
}
) { inherit loc; declarations = []; options = []; } opts;
@ -153,27 +247,17 @@ rec {
config value. */
evalOptionValue = loc: opt: defs:
let
# Process mkOverride properties, adding in the default
# value specified in the option declaration (if any).
defsFinal' = filterOverrides
((if opt ? default then [{ file = head opt.declarations; value = mkOptionDefault opt.default; }] else []) ++ defs);
# Sort mkOrder properties.
defsFinal =
# Avoid sorting if we don't have to.
if any (def: def.value._type or "" == "order") defsFinal'
then sortProperties defsFinal'
else defsFinal';
# Add in the default value for this option, if any.
defs' = (optional (opt ? default)
{ file = head opt.declarations; value = mkOptionDefault opt.default; }) ++ defs;
# Handle properties, check types, and merge everything together
inherit (mergeDefinitions loc opt.type defs') isDefined defsFinal mergedValue;
files = map (def: def.file) defsFinal;
# Type-check the remaining definitions, and merge them if
# possible.
merged =
if defsFinal == [] then
throw "The option `${showOption loc}' is used but not defined."
else
fold (def: res:
if opt.type.check def.value then res
else throw "The option value `${showOption loc}' in `${def.file}' is not a ${opt.type.name}.")
(opt.type.merge loc defsFinal) defsFinal;
if isDefined then mergedValue
else throw "The option `${showOption loc}' is used but not defined.";
# Finally, apply the ‘apply’ function to the merged
# value. This allows options to yield a value computed
# from the definitions.
@ -181,10 +265,42 @@ rec {
in opt //
{ value = addErrorContext "while evaluating the option `${showOption loc}':" value;
definitions = map (def: def.value) defsFinal;
isDefined = defsFinal != [];
inherit files;
inherit isDefined files;
};
# Merge definitions of a value of a given type
mergeDefinitions = loc: type: defs: rec {
defsFinal =
let
# Process mkMerge and mkIf properties
processIfAndMerge = defs: concatMap (m:
map (value: { inherit (m) file; inherit value; }) (dischargeProperties m.value)
) defs;
# Process mkOverride properties
processOverride = defs: filterOverrides defs;
# Sort mkOrder properties
processOrder = defs:
# Avoid sorting if we don't have to.
if any (def: def.value._type or "" == "order") defs
then sortProperties defs
else defs;
in
processOrder (processOverride (processIfAndMerge defs));
# Type-check the remaining definitions, and merge them
mergedValue = fold (def: res:
if type.check def.value then res
else throw "The option value `${showOption loc}' in `${def.file}' is not a ${type.name}.")
(type.merge loc defsFinal) defsFinal;
isDefined = defsFinal != [];
optionalValue =
if isDefined then { value = mergedValue; }
else {};
};
/* Given a config set, expand mkMerge properties, and push down the
other properties into the children. The result is a list of
config sets that do not have properties at top-level. For
@ -254,7 +370,7 @@ rec {
let
defaultPrio = 100;
getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPrio;
min = x: y: if builtins.lessThan x y then x else y;
min = x: y: if x < y then x else y;
highestPrio = fold (def: prio: min (getPrio def) prio) 9999 defs;
strip = def: if def.value._type or "" == "override" then def // { value = def.value.content; } else def;
in concatMap (def: if getPrio def == highestPrio then [(strip def)] else []) defs;
@ -273,23 +389,24 @@ rec {
in sort compare defs';
/* Hack for backward compatibility: convert options of type
optionSet to configOf. FIXME: remove eventually. */
optionSet to options of type submodule. FIXME: remove
eventually. */
fixupOptionType = loc: opt:
let
options' = opt.options or
(throw "Option `${showOption loc'}' has type optionSet but has no option attribute.");
coerce = x:
if isFunction x then x
else { config, ... }: { options = x; };
options = map coerce (flatten options');
options = opt.options or
(throw "Option `${showOption loc'}' has type optionSet but has no option attribute, in ${showFiles opt.declarations}.");
f = tp:
if tp.name == "option set" then types.submodule options
if tp.name == "option set" || tp.name == "submodule" then
throw "The option ${showOption loc} uses submodules without a wrapping type, in ${showFiles opt.declarations}."
else if tp.name == "attribute set of option sets" then types.attrsOf (types.submodule options)
else if tp.name == "list or attribute set of option sets" then types.loaOf (types.submodule options)
else if tp.name == "list of option sets" then types.listOf (types.submodule options)
else if tp.name == "null or option set" then types.nullOr (types.submodule options)
else tp;
in opt // { type = f (opt.type or types.unspecified); };
in
if opt.type.getSubModules or null == null
then opt // { type = f (opt.type or types.unspecified); }
else opt // { type = opt.type.substSubModules opt.options; options = []; };
/* Properties. */
@ -331,6 +448,31 @@ rec {
mkBefore = mkOrder 500;
mkAfter = mkOrder 1500;
# Convenient property used to transfer all definitions and their
# properties from one option to another. This property is useful for
# renaming options, and also for including properties from another module
# system, including sub-modules.
#
# { config, options, ... }:
#
# {
# # 'bar' might not always be defined in the current module-set.
# config.foo.enable = mkAliasDefinitions (options.bar.enable or {});
#
# # 'barbaz' has to be defined in the current module-set.
# config.foobar.paths = mkAliasDefinitions options.barbaz.paths;
# }
#
# Note, this is different than taking the value of the option and using it
# as a definition, as the new definition will not keep the mkOverride /
# mkDefault properties of the previous option.
#
mkAliasDefinitions = mkAliasAndWrapDefinitions id;
mkAliasAndWrapDefinitions = wrap: option:
mkMerge
(optional (isOption option && option.isDefined)
(wrap (mkMerge option.definitions)));
/* Compatibility. */
fixMergeModules = modules: args: evalModules { inherit modules args; check = false; };

@ -31,6 +31,23 @@ rec {
type = lib.types.bool;
};
# This option accept anything, but it does not produce any result. This
# is useful for sharing a module across different module sets without
# having to implement similar features as long as the value of the options
# are not expected.
mkSinkUndeclaredOptions = attrs: mkOption ({
internal = true;
visible = false;
default = false;
description = "Sink for option definitions.";
type = mkOptionType {
name = "sink";
check = x: true;
merge = loc: defs: false;
};
apply = x: throw "Option value is not readable because the option is not declared.";
} // attrs);
mergeDefaultOption = loc: defs:
let list = getValues defs; in
if length list == 1 then head list
@ -79,10 +96,11 @@ rec {
declarations = filter (x: x != unknownModule) opt.declarations;
internal = opt.internal or false;
visible = opt.visible or true;
type = opt.type.name or null;
}
// optionalAttrs (opt ? example) { example = scrubOptionValue opt.example; }
// optionalAttrs (opt ? default) { default = scrubOptionValue opt.default; }
// optionalAttrs (opt ? defaultText) { default = opt.defaultText; };
// (if opt ? example then { example = scrubOptionValue opt.example; } else {})
// (if opt ? default then { default = scrubOptionValue opt.default; } else {})
// (if opt ? defaultText then { default = opt.defaultText; } else {});
subOptions =
let ss = opt.type.getSubOptions opt.loc;

@ -2,7 +2,7 @@ let lists = import ./lists.nix; in
rec {
gnu = linux; /* ++ hurd ++ kfreebsd ++ ... */
linux = ["i686-linux" "x86_64-linux" "armv5tel-linux" "armv7l-linux" "mips64el-linux"];
linux = ["i686-linux" "x86_64-linux" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "mips64el-linux"];
darwin = ["x86_64-darwin"];
freebsd = ["i686-freebsd" "x86_64-freebsd"];
openbsd = ["i686-openbsd" "x86_64-openbsd"];

@ -62,8 +62,8 @@ rec {
in { result = x.result ++ [entry.text] ++ y.result;
done = y.done;
}
else if hasAttr entry done then f done (tail todo)
else f (done // listToAttrs [{name = entry; value = 1;}]) ([(builtins.getAttr entry predefined)] ++ tail todo);
else if done ? ${entry} then f done (tail todo)
else f (done // listToAttrs [{name = entry; value = 1;}]) ([predefined.${entry}] ++ tail todo);
in (f {} arg).result;
textClosureMap = f: predefined: names:

@ -2,7 +2,7 @@
let lib = import ./default.nix;
inherit (builtins) add sub lessThan length;
inherit (builtins) length;
in
@ -79,7 +79,7 @@ rec {
stringToCharacters = s: let l = stringLength s; in
if l == 0
then []
else map (p: substring p 1 s) (lib.range 0 (sub l 1));
else map (p: substring p 1 s) (lib.range 0 (l - 1));
# Manipulate a string charcater by character and replace them by strings
@ -123,7 +123,7 @@ rec {
toUpper = replaceChars lowerChars upperChars;
# Appends string context from another string
addContextFrom = a: b: (substring 0 0 a)+b;
addContextFrom = a: b: substring 0 0 a + b;
# Compares strings not requiring context equality
# Obviously, a workaround but works on all Nix versions
@ -139,18 +139,18 @@ rec {
s = addContextFrom _sep _s;
sepLen = stringLength sep;
sLen = stringLength s;
lastSearch = sub sLen sepLen;
lastSearch = sLen - sepLen;
startWithSep = startAt:
substring startAt sepLen s == sep;
recurse = index: startAt:
let cutUntil = i: [(substring startAt (sub i startAt) s)]; in
if lessThan index lastSearch then
let cutUntil = i: [(substring startAt (i - startAt) s)]; in
if index < lastSearch then
if startWithSep index then
let restartAt = add index sepLen; in
let restartAt = index + sepLen; in
cutUntil index ++ recurse restartAt restartAt
else
recurse (add index 1) startAt
recurse (index + 1) startAt
else
cutUntil sLen;
in
@ -208,4 +208,15 @@ rec {
# standard GNU Autoconf scripts.
enableFeature = enable: feat: "--${if enable then "enable" else "disable"}-${feat}";
# Create a fixed width string with additional prefix to match required width
fixedWidthString = width: filler: str:
let
strw = lib.stringLength str;
reqWidth = width - (lib.stringLength filler);
in
assert strw <= width;
if strw == width then str else filler + fixedWidthString reqWidth filler str;
# Format a number adding leading zeroes up to fixed width
fixedWidthNumber = width: n: fixedWidthString width "0" (toString n);
}

@ -24,7 +24,7 @@ rec {
isCpuType = x: isType "cpu-type" x
&& elem x.bits [8 16 32 64 128]
&& (builtins.lessThan 8 x.bits -> isSignificantByte x.significantByte);
&& (8 < x.bits -> isSignificantByte x.significantByte);
cpuTypes = with significantBytes;
setTypes "cpu-type" {

@ -0,0 +1,119 @@
#!/bin/sh
#
# This script is used to test that the module system is working as expected.
# By default it test the version of nixpkgs which is defined in the NIX_PATH.
cd ./modules
pass=0
fail=0
evalConfig() {
local attr=$1
shift;
local script="import ./default.nix { modules = [ $@ ];}"
nix-instantiate --timeout 1 -E "$script" -A "$attr" --eval-only
}
reportFailure() {
local attr=$1
shift;
local script="import ./default.nix { modules = [ $@ ];}"
echo 2>&1 "$ nix-instantiate -E '$script' -A '$attr' --eval-only"
evalConfig "$attr" "$@"
fail=$((fail + 1))
}
checkConfigOutput() {
local outputContains=$1
shift;
if evalConfig "$@" 2>/dev/null | grep --silent "$outputContains" ; then
pass=$((pass + 1))
return 0;
else
echo 2>&1 "error: Expected result matching '$outputContains', while evaluating"
reportFailure "$@"
return 1
fi
}
checkConfigError() {
local errorContains=$1
local err=""
shift;
if err==$(evalConfig "$@" 2>&1 >/dev/null); then
echo 2>&1 "error: Expected error code, got exit code 0, while evaluating"
reportFailure "$@"
return 1
else
if echo "$err" | grep --silent "$errorContains" ; then
pass=$((pass + 1))
return 0;
else
echo 2>&1 "error: Expected error matching '$errorContains', while evaluating"
reportFailure "$@"
return 1
fi
fi
}
# Check boolean option.
checkConfigOutput "false" config.enable ./declare-enable.nix
checkConfigError 'The option .* defined in .* does not exist.' config.enable ./define-enable.nix
# Check mkForce without submodules.
set -- config.enable ./declare-enable.nix ./define-enable.nix
checkConfigOutput "true" "$@"
checkConfigOutput "false" "$@" ./define-force-enable.nix
checkConfigOutput "false" "$@" ./define-enable-force.nix
# Check mkForce with option and submodules.
checkConfigError 'attribute .*foo.* .* not found' config.loaOfSub.foo.enable ./declare-loaOfSub-any-enable.nix
checkConfigOutput 'false' config.loaOfSub.foo.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix
set -- config.loaOfSub.foo.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo-enable.nix
checkConfigOutput 'true' "$@"
checkConfigOutput 'false' "$@" ./define-force-loaOfSub-foo-enable.nix
checkConfigOutput 'false' "$@" ./define-loaOfSub-force-foo-enable.nix
checkConfigOutput 'false' "$@" ./define-loaOfSub-foo-force-enable.nix
checkConfigOutput 'false' "$@" ./define-loaOfSub-foo-enable-force.nix
# Check overriding effect of mkForce on submodule definitions.
checkConfigError 'attribute .*bar.* .* not found' config.loaOfSub.bar.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix
checkConfigOutput 'false' config.loaOfSub.bar.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix ./define-loaOfSub-bar.nix
set -- config.loaOfSub.bar.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix ./define-loaOfSub-bar-enable.nix
checkConfigOutput 'true' "$@"
checkConfigError 'attribute .*bar.* .* not found' "$@" ./define-force-loaOfSub-foo-enable.nix
checkConfigError 'attribute .*bar.* .* not found' "$@" ./define-loaOfSub-force-foo-enable.nix
checkConfigOutput 'true' "$@" ./define-loaOfSub-foo-force-enable.nix
checkConfigOutput 'true' "$@" ./define-loaOfSub-foo-enable-force.nix
# Check mkIf with submodules.
checkConfigError 'attribute .*foo.* .* not found' config.loaOfSub.foo.enable ./declare-enable.nix ./declare-loaOfSub-any-enable.nix
set -- config.loaOfSub.foo.enable ./declare-enable.nix ./declare-loaOfSub-any-enable.nix
checkConfigError 'attribute .*foo.* .* not found' "$@" ./define-if-loaOfSub-foo-enable.nix
checkConfigError 'attribute .*foo.* .* not found' "$@" ./define-loaOfSub-if-foo-enable.nix
checkConfigError 'attribute .*foo.* .* not found' "$@" ./define-loaOfSub-foo-if-enable.nix
checkConfigOutput 'false' "$@" ./define-loaOfSub-foo-enable-if.nix
checkConfigOutput 'true' "$@" ./define-enable.nix ./define-if-loaOfSub-foo-enable.nix
checkConfigOutput 'true' "$@" ./define-enable.nix ./define-loaOfSub-if-foo-enable.nix
checkConfigOutput 'true' "$@" ./define-enable.nix ./define-loaOfSub-foo-if-enable.nix
checkConfigOutput 'true' "$@" ./define-enable.nix ./define-loaOfSub-foo-enable-if.nix
# Check _module.args.
checkConfigOutput "true" config.enable ./declare-enable.nix ./custom-arg-define-enable.nix
# Check _module.check.
set -- config.enable ./declare-enable.nix ./define-enable.nix ./define-loaOfSub-foo.nix
checkConfigError 'The option .* defined in .* does not exist.' "$@"
checkConfigOutput "true" "$@" ./define-module-check.nix
cat <<EOF
====== module tests ======
$pass Pass
$fail Fail
EOF
if test $fail -ne 0; then
exit 1
fi
exit 0

@ -0,0 +1,8 @@
{ lib, custom, ... }:
{
config = {
_module.args.custom = true;
enable = custom;
};
}

@ -0,0 +1,14 @@
{ lib, ... }:
{
options = {
enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
description = ''
Some descriptive text
'';
};
};
}

@ -0,0 +1,29 @@
{ lib, ... }:
let
submod = { ... }: {
options = {
enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
description = ''
Some descriptive text
'';
};
};
};
in
{
options = {
loaOfSub = lib.mkOption {
default = {};
example = {};
type = lib.types.loaOf (lib.types.submodule [ submod ]);
description = ''
Some descriptive text
'';
};
};
}

@ -0,0 +1,7 @@
{ lib ? import <nixpkgs/lib>, modules ? [] }:
{
inherit (lib.evalModules {
inherit modules;
}) config options;
}

@ -0,0 +1,5 @@
{ lib, ... }:
{
enable = lib.mkForce false;
}

@ -0,0 +1,3 @@
{
enable = true;
}

@ -0,0 +1,5 @@
{ lib, ... }:
lib.mkForce {
enable = false;
}

@ -0,0 +1,5 @@
{ lib, ... }:
lib.mkForce {
loaOfSub.foo.enable = false;
}

@ -0,0 +1,5 @@
{ config, lib, ... }:
lib.mkIf config.enable {
loaOfSub.foo.enable = true;
}

@ -0,0 +1,3 @@
{
loaOfSub.bar.enable = true;
}

@ -0,0 +1,3 @@
{
loaOfSub.bar = {};
}

@ -0,0 +1,5 @@
{ lib, ... }:
{
loaOfSub.foo.enable = lib.mkForce false;
}

@ -0,0 +1,5 @@
{ config, lib, ... }:
{
loaOfSub.foo.enable = lib.mkIf config.enable true;
}

@ -0,0 +1,3 @@
{
loaOfSub.foo.enable = true;
}

@ -0,0 +1,7 @@
{ lib, ... }:
{
loaOfSub.foo = lib.mkForce {
enable = false;
};
}

@ -0,0 +1,7 @@
{ config, lib, ... }:
{
loaOfSub.foo = lib.mkIf config.enable {
enable = true;
};
}

@ -0,0 +1,3 @@
{
loaOfSub.foo = {};
}

@ -0,0 +1,7 @@
{ lib, ... }:
{
loaOfSub = lib.mkForce {
foo.enable = false;
};
}

@ -0,0 +1,7 @@
{ config, lib, ... }:
{
loaOfSub = lib.mkIf config.enable {
foo.enable = true;
};
}

@ -0,0 +1,3 @@
{
_module.check = false;
}

@ -0,0 +1,31 @@
{ nixpkgs }:
with import ./../.. { };
with lib;
stdenv.mkDerivation {
name = "nixpkgs-lib-tests";
buildInputs = [ nix ];
NIX_PATH="nixpkgs=${nixpkgs}";
buildCommand = ''
datadir="${nix}/share"
export TEST_ROOT=$(pwd)/test-tmp
export NIX_STORE_DIR=$TEST_ROOT/store
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_DB_DIR=$TEST_ROOT/db
export NIX_CONF_DIR=$TEST_ROOT/etc
export NIX_MANIFESTS_DIR=$TEST_ROOT/var/nix/manifests
export NIX_BUILD_HOOK=
export PAGER=cat
cacheDir=$TEST_ROOT/binary-cache
nix-store --init
cd ${nixpkgs}/lib/tests
./modules.sh
touch $out
'';
}

@ -1,8 +1,3 @@
with {
inherit (import ./lists.nix) deepSeqList;
inherit (import ./attrsets.nix) deepSeqAttrs;
};
rec {
# Identity function.
@ -23,23 +18,11 @@ rec {
# Flip the order of the arguments of a binary function.
flip = f: a: b: f b a;
# `seq x y' evaluates x, then returns y. That is, it forces strict
# evaluation of its first argument.
seq = x: y: if x == null then y else y;
# Like `seq', but recurses into lists and attribute sets to force evaluation
# of all list elements/attributes.
deepSeq = x: y:
if builtins.isList x
then deepSeqList x y
else if builtins.isAttrs x
then deepSeqAttrs x y
else seq x y;
# Pull in some builtins not included elsewhere.
inherit (builtins)
pathExists readFile isBool isFunction
isInt add sub lessThan;
isInt add sub lessThan
seq deepSeq;
# Return the Nixpkgs version number.
nixpkgsVersion =
@ -47,7 +30,11 @@ rec {
readFile ../.version
+ (if pathExists suffixFile then readFile suffixFile else "pre-git");
# Whether we're being called by nix-shell. This is useful to
# Whether we're being called by nix-shell.
inNixShell = builtins.getEnv "IN_NIX_SHELL" == "1";
# Return minimum/maximum of two numbers.
min = x: y: if x < y then x else y;
max = x: y: if x > y then x else y;
}

@ -6,6 +6,7 @@ with import ./attrsets.nix;
with import ./options.nix;
with import ./trivial.nix;
with import ./strings.nix;
with {inherit (import ./modules.nix) mergeDefinitions; };
rec {
@ -33,9 +34,14 @@ rec {
, # Return a flat list of sub-options. Used to generate
# documentation.
getSubOptions ? prefix: {}
, # List of modules if any, or null if none.
getSubModules ? null
, # Function for building the same option type with a different list of
# modules.
substSubModules ? m: null
}:
{ _type = "option-type";
inherit name check merge getSubOptions;
inherit name check merge getSubOptions getSubModules substSubModules;
};
@ -104,23 +110,33 @@ rec {
listOf = elemType: mkOptionType {
name = "list of ${elemType.name}s";
check = value: isList value && all elemType.check value;
check = isList;
merge = loc: defs:
concatLists (imap (n: def: imap (m: def':
elemType.merge (loc ++ ["[${toString n}-${toString m}]"])
[{ inherit (def) file; value = def'; }]) def.value) defs);
map (x: x.value) (filter (x: x ? value) (concatLists (imap (n: def: imap (m: def':
(mergeDefinitions
(loc ++ ["[definition ${toString n}-entry ${toString m}]"])
elemType
[{ inherit (def) file; value = def'; }]
).optionalValue
) def.value) defs)));
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*"]);
getSubModules = elemType.getSubModules;
substSubModules = m: listOf (elemType.substSubModules m);
};
attrsOf = elemType: mkOptionType {
name = "attribute set of ${elemType.name}s";
check = x: isAttrs x && all elemType.check (attrValues x);
check = isAttrs;
merge = loc: defs:
zipAttrsWith (name: elemType.merge (loc ++ [name]))
mapAttrs (n: v: v.value) (filterAttrs (n: v: v ? value) (zipAttrsWith (name: defs:
(mergeDefinitions (loc ++ [name]) elemType defs).optionalValue
)
# Push down position info.
(map (def: listToAttrs (mapAttrsToList (n: def':
{ name = n; value = { inherit (def) file; value = def'; }; }) def.value)) defs);
{ name = n; value = { inherit (def) file; value = def'; }; }) def.value)) defs)));
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name>"]);
getSubModules = elemType.getSubModules;
substSubModules = m: attrsOf (elemType.substSubModules m);
};
# List or attribute set of ...
@ -141,18 +157,19 @@ rec {
attrOnly = attrsOf elemType;
in mkOptionType {
name = "list or attribute set of ${elemType.name}s";
check = x:
if isList x then listOnly.check x
else if isAttrs x then attrOnly.check x
else false;
check = x: isList x || isAttrs x;
merge = loc: defs: attrOnly.merge loc (imap convertIfList defs);
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name?>"]);
getSubModules = elemType.getSubModules;
substSubModules = m: loaOf (elemType.substSubModules m);
};
uniq = elemType: mkOptionType {
inherit (elemType) name check;
merge = mergeOneOption;
getSubOptions = elemType.getSubOptions;
getSubModules = elemType.getSubModules;
substSubModules = m: uniq (elemType.substSubModules m);
};
nullOr = elemType: mkOptionType {
@ -165,14 +182,8 @@ rec {
throw "The option `${showOption loc}' is defined both null and not null, in ${showFiles (getFiles defs)}."
else elemType.merge loc defs;
getSubOptions = elemType.getSubOptions;
};
functionTo = elemType: mkOptionType {
name = "function that evaluates to a(n) ${elemType.name}";
check = isFunction;
merge = loc: defs:
fnArgs: elemType.merge loc (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs);
getSubOptions = elemType.getSubOptions;
getSubModules = elemType.getSubModules;
substSubModules = m: nullOr (elemType.substSubModules m);
};
submodule = opts:
@ -187,11 +198,17 @@ rec {
let
coerce = def: if isFunction def then def else { config = def; };
modules = opts' ++ map (def: { _file = def.file; imports = [(coerce def.value)]; }) defs;
in (evalModules { inherit modules; args.name = last loc; prefix = loc; }).config;
in (evalModules {
inherit modules;
args.name = last loc;
prefix = loc;
}).config;
getSubOptions = prefix: (evalModules
{ modules = opts'; inherit prefix;
# FIXME: hack to get shit to evaluate.
args = { name = ""; }; }).options;
getSubModules = opts';
substSubModules = m: submodule m;
};
enum = values: mkOptionType {

@ -0,0 +1,14 @@
*~
,*
.*.swp
.*.swo
result
result-*
/doc/NEWS.html
/doc/NEWS.txt
/doc/manual.html
/doc/manual.pdf
.version-suffix
.DS_Store
.git

@ -0,0 +1,12 @@
FROM busybox
RUN dir=`mktemp -d` && trap 'rm -rf "$dir"' EXIT && \
wget -O- https://nixos.org/releases/nix/nix-1.7/nix-1.7-x86_64-linux.tar.bz2 | bzcat | tar x -C $dir && \
mkdir -m 0755 /nix && USER=root sh $dir/*/install && \
echo ". /root/.nix-profile/etc/profile.d/nix.sh" >> /etc/profile
ADD . /root/nix/nixpkgs
ONBUILD ENV NIX_PATH nixpkgs=/root/nix/nixpkgs:nixos=/root/nix/nixpkgs/nixos
ONBUILD ENV PATH /root/.nix-profile/bin:/root/.nix-profile/sbin:/bin:/sbin:/usr/bin:/usr/sbin
ONBUILD ENV ENV /etc/profile
ENV ENV /etc/profile

@ -3,7 +3,7 @@
stdenv.mkDerivation {
name = "nix-generate-from-cpan-1";
buildInputs = [ makeWrapper perl perlPackages.YAMLLibYAML perlPackages.JSON ];
buildInputs = [ makeWrapper perl perlPackages.YAMLLibYAML perlPackages.JSON perlPackages.CPANPLUS ];
unpackPhase = "true";
buildPhase = "true";
@ -19,4 +19,4 @@ stdenv.mkDerivation {
maintainers = [ stdenv.lib.maintainers.eelco ];
description = "Utility to generate a Nix expression for a Perl package from CPAN";
};
}
}

@ -100,7 +100,7 @@ sub get_deps {
foreach my $n (keys %{$deps}) {
next if $n eq "perl";
# Hacky way to figure out if this module is part of Perl.
if ($n !~ /^JSON/ && $n !~ /^YAML/) {
if ($n !~ /^JSON/ && $n !~ /^YAML/ && $n !~ /^Module::Pluggable/) {
eval "use $n;";
if (!$@) {
print STDERR "skipping Perl-builtin module $n\n";

@ -62,7 +62,7 @@ for bin in $(find $binaryDist -executable -type f) :; do
)
if test "$names" = "glibc"; then names="stdenv.glibc"; fi
if echo $names | grep -c "gcc" &> /dev/null; then names="stdenv.gcc.gcc"; fi
if echo $names | grep -c "gcc" &> /dev/null; then names="stdenv.cc.cc"; fi
if test $lib != $libPath; then
interpreter="--interpreter \${$names}/lib/$lib"

@ -0,0 +1,41 @@
#! /usr/bin/env bash
set -e
export NIX_CURL_FLAGS=-sS
if [[ $1 == nix ]]; then
echo "=== Installing Nix..."
# Install Nix
bash <(curl -sS https://nixos.org/nix/install)
source $HOME/.nix-profile/etc/profile.d/nix.sh
# Make sure we can use hydra's binary cache
sudo mkdir /etc/nix
sudo tee /etc/nix/nix.conf <<EOF >/dev/null
binary-caches = http://cache.nixos.org http://hydra.nixos.org
trusted-binary-caches = http://hydra.nixos.org
build-max-jobs = 4
EOF
# Verify evaluation
echo "=== Verifying that nixpkgs evaluates..."
nix-env -f. -qa --json >/dev/null
elif [[ $1 == nox ]]; then
echo "=== Installing nox..."
git clone -q https://github.com/madjar/nox
pip --quiet install -e nox
elif [[ $1 == build ]]; then
source $HOME/.nix-profile/etc/profile.d/nix.sh
if [[ $TRAVIS_PULL_REQUEST == false ]]; then
echo "=== Not a pull request"
else
echo "=== Checking PR"
nox-review pr ${TRAVIS_PULL_REQUEST}
fi
# echo "=== Checking tarball creation"
# nix-build pkgs/top-level/release.nix -A tarball
else
echo "$0: Unknown option $1" >&2
false
fi

@ -0,0 +1,112 @@
#!/bin/sh
set -e
: ${NIXOS_CHANNELS:=https://nixos.org/channels/}
: ${CHANNELS_NAMESPACE:=refs/heads/channels/}
# List all channels which are currently in the repository which we would
# have to remove if they are not found again.
deadChannels=$(git for-each-ref --format="%(refname)" "$CHANNELS_NAMESPACE")
updateRef() {
local channelName=$1
local newRev=$2
# if the inputs are not valid, then we do not update any branch.
test -z "$newRev" -o -z "$channelName" && return;
# Update the local refs/heads/channels/* branches to be in-sync with the
# channel references.
local branch=$CHANNELS_NAMESPACE$channelName
oldRev=$(git rev-parse --short "$branch" 2>/dev/null || true)
if test "$oldRev" != "$newRev"; then
if git update-ref "$branch" "$newRev" 2>/dev/null; then
if test -z "$oldRev"; then
echo " * [new branch] $newRev -> ${branch#refs/heads/}"
else
echo " $oldRev..$newRev -> ${branch#refs/heads/}"
fi
else
if test -z "$oldRev"; then
echo " * [missing rev] $newRev -> ${branch#refs/heads/}"
else
echo " [missing rev] $oldRev..$newRev -> ${branch#refs/heads/}"
fi
fi
fi
# Filter out the current channel from the list of dead channels.
deadChannels=$(grep -v "$CHANNELS_NAMESPACE$channelName" <<EOF
$deadChannels
EOF
) ||true
}
# Find the name of all channels which are listed in the directory.
echo "Fetching channels from $NIXOS_CHANNELS:"
for channelName in : $(curl -s "$NIXOS_CHANNELS" | sed -n '/folder/ { s,.*href=",,; s,/".*,,; p }'); do
test "$channelName" = : && continue;
# Do not follow redirections, such that we can extract the
# short-changeset from the name of the directory where we are
# redirected to.
sha1=$(curl -sI "$NIXOS_CHANNELS$channelName" | sed -n '/Location/ { s,.*\.\([a-f0-9]*\)[ \r]*$,\1,; p; }')
updateRef "remotes/$channelName" "$sha1"
done
echo "Fetching channels from nixos-version:"
if currentSystem=$(nixos-version 2>/dev/null); then
# If the system is entirely build from a custom nixpkgs version,
# then the version is not annotated in git version. This sed
# expression is basically matching that the expressions end with
# ".<sha1> (Name)" to extract the sha1.
sha1=$(echo "$currentSystem" | sed -n 's,^.*\.\([a-f0-9]*\) *(.*)$,\1,; T skip; p; :skip;')
updateRef current-system "$sha1"
fi
echo "Fetching channels from $HOME/.nix-defexpr:"
for revFile in : $(find -L "$HOME/.nix-defexpr/" -maxdepth 4 -name svn-revision); do
test "$revFile" = : && continue;
# Deconstruct a path such as, into:
#
# /home/luke/.nix-defexpr/channels_root/nixos/nixpkgs/svn-revision
# channelName = root/nixos
#
# /home/luke/.nix-defexpr/channels/nixpkgs/svn-revision
# channelName = nixpkgs
#
user=${revFile#*.nix-defexpr/channels}
repo=${user#*/}
repo=${repo%%/*}
user=${user%%/*}
user=${user#_}
test -z "$user" && user=$USER
channelName="$user${user:+/}$repo"
sha1=$(sed -n 's,^.*\.\([a-f0-9]*\)$,\1,; T skip; p; :skip;' "$revFile")
updateRef "$channelName" "$sha1"
done
# Suggest to remove channel branches which are no longer found by this
# script. This is to handle the cases where a local/remote channel
# disappear. We should not attempt to remove manually any branches, as they
# might be user branches.
if test -n "$deadChannels"; then
echo "
Some old channel branches are still in your repository, if you
want to remove them, run the following command(s):
"
while read branch; do
echo " git update-ref -d $branch"
done <<EOF
$deadChannels
EOF
echo
fi

@ -0,0 +1,7 @@
viric viriketo@gmail.com
Pjotr Prins pjotr.public01@thebird.nl
Pjotr Prins pjotr.public05@thebird.nl
Wouter den Breejen wbreejen
MarcWeber marcweber
Ricardo Correia Ricardo M. Correia
ertesx@gmx.de ertes

@ -0,0 +1,122 @@
#! /bin/sh
export LANG=C LC_ALL=C LC_COLLATE=C
# Load git log
raw_git_log="$(git log)"
git_data="$(echo "$raw_git_log" | grep 'Author:' |
sed -e 's/^ *Author://; s/\\//g; s/^ *//; s/ *$//;
s/ @ .*//; s/ *[<]/\t/; s/[>]//')"
# Name - nick - email correspondence from log and from maintainer list
# Also there are a few manual entries
maintainers="$(cat "$(dirname "$0")/../../lib/maintainers.nix" |
grep '=' | sed -re 's/\\"/''/g;
s/ *([^ =]*) *= *" *(.*[^ ]) *[<](.*)[>] *".*/\1\t\2\t\3/')"
git_lines="$( ( echo "$git_data";
cat "$(dirname "$0")/vanity-manual-equalities.txt") | sort |uniq)"
emails="$(
( echo "$maintainers" | cut -f 3; echo "$git_data" | cut -f 2 ) |
sort | uniq | grep -E ".+@.+[.].+"
)"
fetchGithubName () {
commitid="$(
echo "$raw_git_log" | grep -B3 "Author: .*[<]$1[>]" | head -n 3 |
grep '^commit ' | tail -n 1 | sed -e 's/^commit //'
)"
userid="$(
curl https://github.com/NixOS/nixpkgs/commit/"$commitid" 2>/dev/null |
grep authored -B10 | grep 'href="/' |
sed -re 's@.* href="/@@; s@".*@@' |
grep -v "/commit/"
)";
echo "$userid"
}
[ -n "$NIXPKGS_GITHUB_NAME_CACHE" ] && {
echo "$emails" | while read email; do
line="$(grep "$email " "$NIXPKGS_GITHUB_NAME_CACHE")"
[ -z "$line" ] && {
echo "$email $(fetchGithubName "$email")" >> \
"$NIXPKGS_GITHUB_NAME_CACHE"
}
done
}
# For RDF
normalize_name () {
sed -e 's/%/%25/g; s/ /%20/g; s/'\''/%27/g; s/"/%22/g; s/`/%60/g; s/\^/%5e/g; '
}
denormalize_name () {
sed -e 's/%20/ /g; s/%27/'\''/g; s/%22/"/g; s/%60/`/g; s/%5e/^/g; s/%25/%/g;';
}
n3="$(mktemp --suffix .n3)"
# «The same person» relation and a sorting hint
# Full name is something with a space
(
echo "$git_lines" | sed -re 's@(.*)\t(.*)@<my://name/\1> <my://can-be> <my://name/\2>.@'
echo "$git_lines" | sed -re 's@(.*)\t(.*)@<my://name/\2> <my://can-be> <my://name/\1>.@'
echo "$maintainers" | sed -re 's@(.*)\t(.*)\t(.*)@<my://name/\1> <my://can-be> <my://name/\2>.@'
echo "$maintainers" | sed -re 's@(.*)\t(.*)\t(.*)@<my://name/\2> <my://can-be> <my://name/\3>.@'
echo "$maintainers" | sed -re 's@(.*)\t(.*)\t(.*)@<my://name/\3> <my://can-be> <my://name/\1>.@'
echo "$git_lines" | grep ' ' | cut -f 1 | sed -e 's@.*@<my://name/&> <my://is-name> <my://0>.@'
echo "$git_lines" | grep -v ' ' | cut -f 1 | sed -e 's@.*@<my://name/&> <my://is-name> <my://1>.@'
echo "$maintainers" | cut -f 2 | sed -e 's@.*@<my://name/&> <my://is-name> <my://0>.@'
[ -n "$NIXPKGS_GITHUB_NAME_CACHE" ] && cat "$NIXPKGS_GITHUB_NAME_CACHE" |
grep -v " $" |
sed -re 's@(.*)\t(.*)@<my://name/\1> <my://at-github> <my://github/\2>.@'
) | normalize_name | grep -E '<my://[-a-z]+>' | sort | uniq > "$n3"
# Get transitive closure
sparql="$(nix-build '<nixpkgs>' -Q -A apache-jena --no-out-link)/bin/sparql"
name_list="$(
"$sparql" --results=TSV --data="$n3" "
select ?x ?y ?g where {
?x <my://can-be>+ ?y.
?x <my://is-name> ?g.
}
" | tail -n +2 |
sed -re 's@<my://name/@@g; s@<my://@@g; s@>@@g;' |
sort -k 2,3 -t ' '
)"
github_name_list="$(
"$sparql" --results=TSV --data="$n3" "
select ?x ?y where {
?x (<my://can-be>+ / <my://at-github>) ?y.
}
" | tail -n +2 |
sed -re 's@<my://(name|github)/@@g; s@<my://@@g; s@>@@g;'
)"
# Take first spelling option for every person
name_list_canonical="$(echo "$name_list" | cut -f 1,2 | uniq -f1)"
cleaner_script="$(echo "$name_list_canonical" | denormalize_name |
sed -re 's/(.*)\t(.*)/s#^\2$#\1#g/g')"
# Add github usernames
if [ -n "$NIXPKGS_GITHUB_NAME_CACHE" ]; then
github_adder_script="$(echo "$github_name_list" |
grep -E "$(echo "$name_list_canonical" | cut -f 2 |
tr '\n' '|' )" |
sort | uniq |
sed -re 's/(.*)\t(.*)/s| \1$| \1\t\2|g;/' |
denormalize_name
)"
else
github_adder_script=''
fi
echo "$name_list" | denormalize_name
echo
echo "$git_data" | cut -f 1 |
sed -e "$cleaner_script" |
sort | uniq -c | sort -k1n | sed -re "$github_adder_script" |
sed -re 's/^ *([0-9]+) /\1\t/'

@ -58,12 +58,10 @@ controls memory allocation limits; by default, all processes are in
the top-level cgroup, so any service or session can exhaust all
available memory. Per-cgroup memory limits can be specified in
<filename>configuration.nix</filename>; for instance, to limit
<literal>httpd.service</literal> to 512 MiB of RAM (excluding swap)
and 640 MiB of RAM (including swap):
<literal>httpd.service</literal> to 512 MiB of RAM (excluding swap):
<programlisting>
systemd.services.httpd.serviceConfig.MemoryLimit = "512M";
systemd.services.httpd.serviceConfig.ControlGroupAttribute = [ "memory.memsw.limit_in_bytes 640M" ];
</programlisting>
</para>
@ -72,4 +70,4 @@ systemd.services.httpd.serviceConfig.ControlGroupAttribute = [ "memory.memsw.lim
continuously updated list of all cgroups with their CPU and memory
usage.</para>
</chapter>
</chapter>

@ -49,4 +49,8 @@ on container networking.)</para>
switch</literal>. Note that this will not delete the root directory of
the container in <literal>/var/lib/containers</literal>.</para>
</section>
<para>Declarative containers can be started and stopped using the
corresponding systemd service, e.g. <literal>systemctl start
container@database</literal>.</para>
</section>

@ -12,9 +12,9 @@ pre-built binary. That is, whenever a command like
<command>nixos-rebuild</command> needs a path in the Nix store, Nix
will try to download that path from the Internet rather than build it
from source. The default binary cache is
<uri>http://cache.nixos.org/</uri>. If this cache is unreachable, Nix
operations may take a long time due to HTTP connection timeouts. You
can disable the use of the binary cache by adding <option>--option
<uri>https://cache.nixos.org/</uri>. If this cache is unreachable,
Nix operations may take a long time due to HTTP connection timeouts.
You can disable the use of the binary cache by adding <option>--option
use-binary-caches false</option>, e.g.
<screen>
@ -30,4 +30,4 @@ $ nixos-rebuild switch --option binary-caches http://my-cache.example.org/
</para>
</section>
</section>

@ -68,7 +68,7 @@ instance, if you try to define an option that doesn’t exist (that is,
doesn’t have a corresponding <emphasis>option declaration</emphasis>),
<command>nixos-rebuild</command> will give an error like:
<screen>
The option `services.httpd.enabl' defined in `/etc/nixos/configuration.nix' does not exist.
The option `services.httpd.enable' defined in `/etc/nixos/configuration.nix' does not exist.
</screen>
Likewise, values in option definitions must have a correct type. For
instance, <option>services.httpd.enable</option> must be a Boolean

@ -12,12 +12,9 @@ interfaces. However, you can configure an interface manually as
follows:
<programlisting>
networking.interfaces.eth0 = { ipAddress = "192.168.1.2"; prefixLength = 24; };
networking.interfaces.eth0.ip4 = [ { address = "192.168.1.2"; prefixLength = 24; } ];
</programlisting>
(The network prefix can also be specified using the option
<literal>subnetMask</literal>,
e.g. <literal>"255.255.255.0"</literal>, but this is deprecated.)
Typically you’ll also want to set a default gateway and set of name
servers:

@ -56,7 +56,7 @@ root file system), you can use
boot.initrd.extraKernelModules = [ "cifs" ];
</programlisting>
This causes the specified modules and their dependencies to be added
to the initial ramdark.</para>
to the initial ramdisk.</para>
<para>Kernel runtime parameters can be set through
<option>boot.kernel.sysctl</option>, e.g.

@ -10,17 +10,17 @@
use NetworkManager. You can enable NetworkManager by setting:
<programlisting>
services.networkmanager.enable = true;
networking.networkmanager.enable = true;
</programlisting>
Some desktop managers (e.g., GNOME) enable NetworkManager
some desktop managers (e.g., GNOME) enable NetworkManager
automatically for you.</para>
<para>All users that should have permission to change network settings
must belong to the <code>networkmanager</code> group.</para>
<note><para><code>services.networkmanager</code> and
<code>services.wireless</code> can not be enabled at the same time:
<note><para><code>networking.networkmanager</code> and
<code>networking.wireless</code> can not be enabled at the same time:
you can still connect to the wireless networks using
NetworkManager.</para></note>

@ -60,7 +60,7 @@ manual</link> for the rest.</para>
<entry>A nested set, equivalent to <literal>{ foo = { bar = 1; }; }</literal></entry>
</row>
<row>
<entry><literal>rec { x = "bla"; y = x + "bar"; }</literal></entry>
<entry><literal>rec { x = "foo"; y = x + "bar"; }</literal></entry>
<entry>A recursive set, equivalent to <literal>{ x = "foo"; y = "foobar"; }</literal></entry>
</row>
<row>

@ -67,12 +67,31 @@ with other kernel modules.</para>
<para>On 64-bit systems, if you want full acceleration for 32-bit
programs such as Wine, you should also set the following:
<programlisting>
services.xserver.driSupport32Bit = true;
hardware.opengl.driSupport32Bit = true;
</programlisting>
</para>
</simplesect>
<simplesect><title>AMD Graphics Cards</title>
<para>AMD provides a proprietary driver for its graphics cards that
has better 3D performance than the X.org drivers. It is not enabled
by default because it’s not free software. You can enable it as follows:
<programlisting>
services.xserver.videoDrivers = [ "ati_unfree" ];
</programlisting>
You will need to reboot after enabling this driver to prevent a clash
with other kernel modules.</para>
<para>On 64-bit systems, if you want full acceleration for 32-bit
programs such as Wine, you should also set the following:
<programlisting>
hardware.opengl.driSupport32Bit = true;
</programlisting>
</para>
</simplesect>
<simplesect><title>Touchpads</title>

@ -6,12 +6,22 @@ with pkgs.lib;
let
# Remove invisible and internal options.
options' = filter (opt: opt.visible && !opt.internal) (optionAttrSetToDocList options);
optionsList = filter (opt: opt.visible && !opt.internal) (optionAttrSetToDocList options);
# Replace functions by the string <function>
substFunction = x:
if builtins.isAttrs x then mapAttrs (name: substFunction) x
else if builtins.isList x then map substFunction x
else if builtins.isFunction x then "<function>"
else x;
# Clean up declaration sites to not refer to the NixOS source tree.
options'' = flip map options' (opt: opt // {
optionsList' = flip map optionsList (opt: opt // {
declarations = map (fn: stripPrefix fn) opt.declarations;
});
}
// optionalAttrs (opt ? example) { example = substFunction opt.example; }
// optionalAttrs (opt ? default) { default = substFunction opt.default; }
// optionalAttrs (opt ? type) { type = substFunction opt.type; });
prefix = toString ../../..;
@ -21,10 +31,14 @@ let
else
fn;
optionsXML = builtins.toFile "options.xml" (builtins.unsafeDiscardStringContext (builtins.toXML options''));
# Convert the list of options into an XML file. The builtin
# unsafeDiscardStringContext is used to prevent the realisation of
# the store paths which are used in options definitions.
optionsXML = builtins.toFile "options.xml" (builtins.unsafeDiscardStringContext (builtins.toXML optionsList'));
optionsDocBook = runCommand "options-db.xml" {} ''
if grep /nixpkgs/nixos/modules ${optionsXML}; then
optionsXML=${optionsXML}
if grep /nixpkgs/nixos/modules $optionsXML; then
echo "The manual appears to depend on the location of Nixpkgs, which is bad"
echo "since this prevents sharing via the NixOS channel. This is typically"
echo "caused by an option default that refers to a relative path (see above"
@ -33,7 +47,7 @@ let
fi
${libxslt}/bin/xsltproc \
--stringparam revision '${revision}' \
-o $out ${./options-to-docbook.xsl} ${optionsXML}
-o $out ${./options-to-docbook.xsl} $optionsXML
'';
sources = sourceFilesBySuffices ./. [".xml"];
@ -49,6 +63,26 @@ let
in rec {
# The NixOS options in JSON format.
optionsJSON = stdenv.mkDerivation {
name = "options-json";
buildCommand = ''
# Export list of options in different format.
dst=$out/share/doc/nixos
mkdir -p $dst
cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
(listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList'))))
} $dst/options.json
mkdir -p $out/nix-support
echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products
''; # */
meta.description = "List of NixOS options in JSON format";
};
# Generate the NixOS manual.
manual = stdenv.mkDerivation {
name = "nixos-manual";
@ -90,7 +124,7 @@ in rec {
mkdir -p $out/nix-support
echo "nix-build out $out" >> $out/nix-support/hydra-build-products
echo "doc manual $dst manual.html" >> $out/nix-support/hydra-build-products
echo "doc manual $dst" >> $out/nix-support/hydra-build-products
''; # */
meta.description = "The NixOS manual in HTML format";

@ -39,24 +39,13 @@ $ firefox result/log.html
</para>
<para>It is also possible to run the test environment interactively,
allowing you to experiment with the VMs. For example:
<title>Running Tests interactively</title>
<screen>
$ nix-build login.nix -A driver
$ ./result/bin/nixos-run-vms
</screen>
The script <command>nixos-run-vms</command> starts the virtual
machines defined by test. The root file system of the VMs is created
on the fly and kept across VM restarts in
<filename>./</filename><varname>hostname</varname><filename>.qcow2</filename>.</para>
<para>Finally, the test itself can be run interactively. This is
<para>The test itself can be run interactively. This is
particularly useful when developing or debugging a test:
<screen>
$ nix-build tests/ -A nfs.driver
$ nix-build nixos/tests/login.nix -A driver
$ ./result/bin/nixos-test-driver
starting VDE switch for network 1
&gt;
@ -66,6 +55,7 @@ You can then take any Perl statement, e.g.
<screen>
&gt; startAll
&gt; testScript
&gt; $machine->succeed("touch /tmp/foo")
</screen>
@ -74,4 +64,16 @@ script and drops you back into the test driver command line upon its
completion. This allows you to inspect the state of the VMs after the
test (e.g. to debug the test script).</para>
</section>
<para>To just start and experiment with the VMs, run:
<screen>
$ nix-build nixos/tests/login.nix -A driver
$ ./result/bin/nixos-run-vms
</screen>
The script <command>nixos-run-vms</command> starts the virtual
machines defined by test. The root file system of the VMs is created
on the fly and kept across VM restarts in
<filename>./</filename><varname>hostname</varname><filename>.qcow2</filename>.</para>
</section>

@ -40,20 +40,22 @@ rebuild everything from source. So you may want to create a local
branch based on your current NixOS version:
<screen>
$ nixos-version
14.04.273.ea1952b (Baboon)
$ git checkout -b local ea1952b
$ <replaceable>/my/sources</replaceable>/nixpkgs/maintainers/scripts/update-channel-branches.sh
Fetching channels from https://nixos.org/channels:
* [new branch] cbe467e -> channels/remotes/nixos-unstable
Fetching channels from nixos-version:
* [new branch] 9ff4738 -> channels/current-system
Fetching channels from ~/.nix-defexpr:
* [new branch] 0d4acad -> channels/root/nixos
$ git checkout -b local channels/current-system
</screen>
Or, to base your local branch on the latest version available in the
NixOS channel:
<screen>
$ curl -sI http://nixos.org/channels/nixos-unstable/ | grep Location
Location: http://releases.nixos.org/nixos/unstable/nixos-14.10pre43986.acaf4a6/
$ git checkout -b local acaf4a6
$ <replaceable>/my/sources</replaceable>/nixpkgs/maintainers/scripts/update-channel-branches.sh
$ git checkout -b local channels/remotes/nixos-unstable
</screen>
You can then use <command>git rebase</command> to sync your local
@ -92,4 +94,4 @@ to <command>nix-env</command>, as it will break after interpreting expressions
in <filename>nixos/</filename> as packages.</para>
-->
</chapter>
</chapter>

@ -11,14 +11,9 @@
<listitem><para>Boot from the CD.</para></listitem>
<listitem><para>The CD contains a basic NixOS installation. (It
also contains Memtest86+, useful if you want to test new hardware.)
also contains Memtest86+, useful if you want to test new hardware).
When it’s finished booting, it should have detected most of your
hardware and brought up networking (check
<command>ifconfig</command>). Networking is necessary for the
installer, since it will download lots of stuff (such as source
tarballs or Nixpkgs channel binaries). It’s best if you have a DHCP
server on your network. Otherwise configure networking manually
using <command>ifconfig</command>.</para></listitem>
hardware.</para></listitem>
<listitem><para>The NixOS manual is available on virtual console 8
(press Alt+F8 to access).</para></listitem>
@ -29,6 +24,16 @@
<listitem><para>If you downloaded the graphical ISO image, you can
run <command>start display-manager</command> to start KDE.</para></listitem>
<listitem><para>The boot process should have brought up networking (check
<command>ip a</command>). Networking is necessary for the
installer, since it will download lots of stuff (such as source
tarballs or Nixpkgs channel binaries). It’s best if you have a DHCP
server on your network. Otherwise configure networking manually
using <command>ifconfig</command>.</para>
<para>To manually configure the network on the graphical installer,
first disable network-manager with
<command>systemctl stop network-manager</command>.</para></listitem>
<listitem><para>The NixOS installer doesn’t do any partitioning or
formatting yet, so you need to that yourself. Use the following
commands:

@ -8,9 +8,14 @@
<para>NixOS ISO images can be downloaded from the <link
xlink:href="http://nixos.org/nixos/download.html">NixOS
homepage</link>. These can be burned onto a CD. It is also possible
to copy them onto a USB stick and install NixOS from there. For
details, see the <link
download page</link>. There are a number of installation options. If
you happen to have an optical drive and a spare CD, burning the
image to CD and booting from that is probably the easiest option.
Most people will need to prepare a USB stick to boot from.
Unetbootin is recommended and the process is described in brief below.
Note that systems which use UEFI require some additional manual steps.
If you run into difficulty a number of alternative methods are presented
in the <link
xlink:href="https://nixos.org/wiki/Installing_NixOS_from_a_USB_stick">NixOS
Wiki</link>.</para>
@ -22,7 +27,7 @@ running NixOS system through several other means:
<para>Using virtual appliances in Open Virtualization Format (OVF)
that can be imported into VirtualBox. These are available from
the <link xlink:href="http://nixos.org/nixos/download.html">NixOS
homepage</link>.</para>
download page</link>.</para>
</listitem>
<listitem>
<para>Using AMIs for Amazon’s EC2. To find one for your region

@ -14,8 +14,8 @@ been built. These channels are:
<itemizedlist>
<listitem>
<para>Stable channels, such as <literal
xlink:href="http://nixos.org/channels/nixos-14.04">nixos-14.04</literal>.
<para><emphasis>Stable channels</emphasis>, such as <literal
xlink:href="https://nixos.org/channels/nixos-14.12">nixos-14.12</literal>.
These only get conservative bug fixes and package upgrades. For
instance, a channel update may cause the Linux kernel on your
system to be upgraded from 3.4.66 to 3.4.67 (a minor bug fix), but
@ -23,26 +23,40 @@ been built. These channels are:
3.11.<replaceable>x</replaceable> (a major change that has the
potential to break things). Stable channels are generally
maintained until the next stable branch is created.</para>
<para></para>
</listitem>
<listitem>
<para>The unstable channel, <literal
xlink:href="http://nixos.org/channels/nixos-unstable">nixos-unstable</literal>.
<para>The <emphasis>unstable channel</emphasis>, <literal
xlink:href="https://nixos.org/channels/nixos-unstable">nixos-unstable</literal>.
This corresponds to NixOS’s main development branch, and may thus
see radical changes between channel updates. It’s not recommended
for production systems.</para>
</listitem>
<listitem>
<para><emphasis>Small channels</emphasis>, such as <literal
xlink:href="https://nixos.org/channels/nixos-14.12-small">nixos-14.12-small</literal>
or <literal
xlink:href="https://nixos.org/channels/nixos-unstable-small">nixos-unstable-small</literal>. These
are identical to the stable and unstable channels described above,
except that they contain fewer binary packages. This means they
get updated faster than the regular channels (for instance, when a
critical security patch is committed to NixOS’s source tree), but
may require more packages to be built from source than
usual. They’re mostly intended for server environments and as such
contain few GUI applications.</para>
</listitem>
</itemizedlist>
To see what channels are available, go to <link
xlink:href="http://nixos.org/channels"/>. (Note that the URIs of the
xlink:href="https://nixos.org/channels"/>. (Note that the URIs of the
various channels redirect to a directory that contains the channel’s
latest version and includes ISO images and VirtualBox
appliances.)</para>
<para>When you first install NixOS, you’re automatically subscribed to
the NixOS channel that corresponds to your installation source. For
instance, if you installed from a 14.04 ISO, you will be subscribed to
the <literal>nixos-14.04</literal> channel. To see which NixOS
instance, if you installed from a 14.12 ISO, you will be subscribed to
the <literal>nixos-14.12</literal> channel. To see which NixOS
channel you’re subscribed to, run the following as root:
<screen>
@ -53,20 +67,26 @@ nixos https://nixos.org/channels/nixos-unstable
To switch to a different NixOS channel, do
<screen>
$ nix-channel --add http://nixos.org/channels/<replaceable>channel-name</replaceable> nixos
$ nix-channel --add https://nixos.org/channels/<replaceable>channel-name</replaceable> nixos
</screen>
(Be sure to include the <literal>nixos</literal> parameter at the
end.) For instance, to use the NixOS 14.04 stable channel:
end.) For instance, to use the NixOS 14.12 stable channel:
<screen>
$ nix-channel --add https://nixos.org/channels/nixos-14.12 nixos
</screen>
If you have a server, you may want to use the “small” channel instead:
<screen>
$ nix-channel --add http://nixos.org/channels/nixos-14.04 nixos
$ nix-channel --add https://nixos.org/channels/nixos-14.12-small nixos
</screen>
But it you want to live on the bleeding edge:
And if you want to live on the bleeding edge:
<screen>
$ nix-channel --add http://nixos.org/channels/nixos-unstable nixos
$ nix-channel --add https://nixos.org/channels/nixos-unstable nixos
</screen>
</para>

@ -11,12 +11,45 @@
<refnamediv>
<refname><command>nixos-install</command></refname>
<refpurpose>install NixOS</refpurpose>
<refpurpose>install bootloader and NixOS</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nixos-install</command>
<arg>
<arg choice='plain'><option>-I</option></arg>
<replaceable>path</replaceable>
</arg>
<arg>
<arg choice='plain'><option>--root</option></arg>
<replaceable>root</replaceable>
</arg>
<arg>
<group choice='req'>
<arg choice='plain'><option>--max-jobs</option></arg>
<arg choice='plain'><option>-j</option></arg>
</group>
<replaceable>number</replaceable>
</arg>
<arg>
<option>--cores</option>
<replaceable>number</replaceable>
</arg>
<arg>
<option>--option</option>
<replaceable>name</replaceable>
<replaceable>value</replaceable>
</arg>
<arg>
<arg choice='plain'><option>--show-trace</option></arg>
</arg>
<arg>
<arg choice='plain'><option>--chroot</option></arg>
</arg>
<arg>
<arg choice='plain'><option>--help</option></arg>
</arg>
</cmdsynopsis>
</refsynopsisdiv>
@ -55,6 +88,87 @@ it.</para>
</refsection>
<refsection><title>Options</title>
<para>This command accepts the following options:</para>
<variablelist>
<varlistentry>
<term><option>--root</option></term>
<listitem>
<para>Defaults to <filename>/mnt</filename>. If this option is given, treat the directory
<replaceable>root</replaceable> as the root of the NixOS installation.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-I</option></term>
<listitem>
<para>Add a path to the Nix expression search path. This option may be given multiple times.
See the NIX_PATH environment variable for information on the semantics of the Nix search path.
Paths added through <replaceable>-I</replaceable> take precedence over NIX_PATH.</para>
</listitem>
</varlistentry>
<varlistentry><term><option>--max-jobs</option></term>
<term><option>-j</option></term>
<listitem><para>Sets the maximum number of build jobs that Nix will
perform in parallel to the specified number. The default is <literal>1</literal>.
A higher value is useful on SMP systems or to exploit I/O latency.</para></listitem>
</varlistentry>
<varlistentry><term><option>--cores</option></term>
<listitem><para>Sets the value of the <envar>NIX_BUILD_CORES</envar>
environment variable in the invocation of builders. Builders can
use this variable at their discretion to control the maximum amount
of parallelism. For instance, in Nixpkgs, if the derivation
attribute <varname>enableParallelBuilding</varname> is set to
<literal>true</literal>, the builder passes the
<option>-j<replaceable>N</replaceable></option> flag to GNU Make.
The value <literal>0</literal> means that the builder should use all
available CPU cores in the system.</para></listitem>
</varlistentry>
<varlistentry><term><option>--option</option> <replaceable>name</replaceable> <replaceable>value</replaceable></term>
<listitem><para>Set the Nix configuration option
<replaceable>name</replaceable> to <replaceable>value</replaceable>.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--show-trace</option></term>
<listitem>
<para>Causes Nix to print out a stack trace in case of Nix expression evaluation errors.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--chroot</option></term>
<listitem>
<para>Chroot into given installation. Any additional arguments passed are going to be executed inside the chroot.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--help</option></term>
<listitem>
<para>Synonym for <command>man nixos-install</command>.</para>
</listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection><title>Examples</title>
@ -72,6 +186,7 @@ $ mount /dev/sda1 /mnt
$ nixos-generate-config --root /mnt
$ # edit /mnt/etc/nixos/configuration.nix
$ nixos-install
$ reboot
</screen>
</para>

@ -17,11 +17,6 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>nixos-option</command>
<group choice="opt">
<option>-v</option>
<option>-d</option>
<option>-l</option>
</group>
<arg choice='plain'><replaceable>option.name</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
@ -31,50 +26,13 @@
<para>This command evaluates the configuration specified in
<filename>/etc/nixos/configuration.nix</filename> and returns the properties
of the option name given as argument. By default, it returns the value of
the option.</para>
of the option name given as argument.</para>
<para>When the option name is not an option, the command prints the list of
attributes contained in the attribute set.</para>
</refsection>
<refsection><title>Options</title>
<para>This command accepts the following options:</para>
<variablelist>
<varlistentry>
<term><option>--value</option>, <option>-v</option></term>
<listitem>
<para>Returns the value of the option. This is the default operation
if no other options are defined.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--description</option>, <option>-d</option></term>
<listitem>
<para>Return the default value, the example and the description of the
option when available.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--lookup</option>, <option>-l</option></term>
<listitem>
<para>Return the locations where the option is declared and where it
is defined. This is extremely useful to find sources of errors in
your configuration.</para>
</listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection><title>Environment</title>
<variablelist>
@ -103,27 +61,21 @@ grub
initScript
$ nixos-option boot.loader.grub.enable
true</screen></para>
Value:
true
<para>Prints option information:
Default:
true
<screen>$ nixos-option -d networking.hostName
Default: "nixos"
Description:
The name of the machine. Leave it empty if you want to obtain
it from a DHCP server (if using DHCP).</screen></para>
<para>Find the locations which are declaring and defining an option:
Whether to enable the GNU GRUB boot loader.
<screen>$ nixos-option -l hardware.firmware
Declared by:
/mnt/data/nix-sources/nixos/modules/services/hardware/udev.nix
"/nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix"
Defined by:
/path/to/nixpkgs/nixos/modules/system/boot/kernel.nix
/path/to/nixpkgs/nixos/modules/hardware/network/rt73.nix
/path/to/nixpkgs/nixos/modules/hardware/network/intel-3945abg.nix
/path/to/nixpkgs/nixos/modules/hardware/network/intel-2200bg.nix</screen></para>
"/nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix"
</screen></para>
</refsection>

@ -1,7 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle><command>nixos-rebuild</command></refentrytitle>
<manvolnum>8</manvolnum>
@ -22,7 +22,8 @@
<arg choice='plain'><option>boot</option></arg>
<arg choice='plain'><option>test</option></arg>
<arg choice='plain'><option>build</option></arg>
<arg choice='plain'><option>dry-run</option></arg>
<arg choice='plain'><option>dry-build</option></arg>
<arg choice='plain'><option>dry-activate</option></arg>
<arg choice='plain'><option>build-vm</option></arg>
<arg choice='plain'><option>build-vm-with-bootloader</option></arg>
</group>
@ -114,10 +115,22 @@ $ nix-build /path/to/nixpkgs/nixos -A system
</varlistentry>
<varlistentry>
<term><option>dry-run</option></term>
<term><option>dry-build</option></term>
<listitem>
<para>Show what store paths would be built or downloaded by any
of the operations above, but otherwise do nothing.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>dry-activate</option></term>
<listitem>
<para>Simply show what store paths would be built or downloaded
by any of the operations above.</para>
<para>Build the new configuration, but instead of activating it,
show what changes would be performed by the activation (i.e. by
<command>nixos-rebuild test</command>). For
instance, this command will print which systemd units would be
restarted. The list of changes is not guaranteed to be
complete.</para>
</listitem>
</varlistentry>

@ -15,7 +15,7 @@
</author>
<copyright>
<year>2007-2013</year>
<year>2007-2015</year>
<holder>Eelco Dolstra</holder>
</copyright>

@ -32,6 +32,7 @@
<xi:include href="configuration/configuration.xml" />
<xi:include href="administration/running.xml" />
<!-- <xi:include href="userconfiguration.xml" /> -->
<xi:include href="development/development.xml" />
<xi:include href="release-notes/release-notes.xml" />
<appendix xml:id="ch-options">

@ -34,6 +34,14 @@
select="attr[@name = 'description']/string/@value" />
</para>
<xsl:if test="attr[@name = 'type']">
<para>
<emphasis>Type:</emphasis>
<xsl:text> </xsl:text>
<xsl:apply-templates select="attr[@name = 'type']" mode="top" />
</para>
</xsl:if>
<xsl:if test="attr[@name = 'default']">
<para>
<emphasis>Default:</emphasis>

@ -7,10 +7,12 @@
<title>Release Notes</title>
<partintro>
<para>This section lists the release notes for each stable version of NixOS.</para>
<para>This section lists the release notes for each stable version of NixOS
and current unstable revision.</para>
</partintro>
<xi:include href="rl-1410.xml" />
<xi:include href="rl-unstable.xml" />
<xi:include href="rl-1412.xml" />
<xi:include href="rl-1404.xml" />
<xi:include href="rl-1310.xml" />

@ -1,22 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-release-14.10">
<title>Release 14.10 (“Caterpillar”, 2014/10/??)</title>
<para>When upgrading from a previous release, please be aware of the
following incompatible changes:
<itemizedlist>
<listitem><para>The host side of a container virtual Ethernet pair
is now called <literal>ve-<replaceable>container-name</replaceable></literal>
rather than <literal>c-<replaceable>container-name</replaceable></literal>.</para></listitem>
</itemizedlist>
</para>
</chapter>

@ -0,0 +1,177 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-release-14.12">
<title>Release 14.12 (“Caterpillar”, 2014/12/30)</title>
<para>In addition to numerous new and upgraded packages, this release has the following highlights:
<itemizedlist>
<listitem><para>Systemd has been updated to version 217, which has numerous
<link xlink:href="http://lists.freedesktop.org/archives/systemd-devel/2014-October/024662.html">improvements.</link></para></listitem>
<listitem><para><link xlink:href="http://thread.gmane.org/gmane.linux.distributions.nixos/15165">
Nix has been updated to 1.8.</link></para></listitem>
<listitem><para>NixOS is now based on Glibc 2.20.</para></listitem>
<listitem><para>KDE has been updated to 4.14.</para></listitem>
<listitem><para>The default Linux kernel has been updated to 3.14.</para></listitem>
<listitem><para>If <option>users.mutableUsers</option> is enabled (the
default), changes made to the declaration of a user or group will be
correctly realised when running <command>nixos-rebuild</command>. For
instance, removing a user specification from
<filename>configuration.nix</filename> will cause the actual user
account to be deleted. If <option>users.mutableUsers</option> is
disabled, it is no longer necessary to specify UIDs or GIDs; if
omitted, they are allocated dynamically.</para></listitem>
</itemizedlist></para>
<para>Following new services were added since the last release:
<itemizedlist>
<listitem><para><literal>atftpd</literal></para></listitem>
<listitem><para><literal>bosun</literal></para></listitem>
<listitem><para><literal>bspwm</literal></para></listitem>
<listitem><para><literal>chronos</literal></para></listitem>
<listitem><para><literal>collectd</literal></para></listitem>
<listitem><para><literal>consul</literal></para></listitem>
<listitem><para><literal>cpuminer-cryptonight</literal></para></listitem>
<listitem><para><literal>crashplan</literal></para></listitem>
<listitem><para><literal>dnscrypt-proxy</literal></para></listitem>
<listitem><para><literal>docker-registry</literal></para></listitem>
<listitem><para><literal>docker</literal></para></listitem>
<listitem><para><literal>etcd</literal></para></listitem>
<listitem><para><literal>fail2ban</literal></para></listitem>
<listitem><para><literal>fcgiwrap</literal></para></listitem>
<listitem><para><literal>fleet</literal></para></listitem>
<listitem><para><literal>fluxbox</literal></para></listitem>
<listitem><para><literal>gdm</literal></para></listitem>
<listitem><para><literal>geoclue2</literal></para></listitem>
<listitem><para><literal>gitlab</literal></para></listitem>
<listitem><para><literal>gitolite</literal></para></listitem>
<listitem><para><literal>gnome3.gnome-documents</literal></para></listitem>
<listitem><para><literal>gnome3.gnome-online-miners</literal></para></listitem>
<listitem><para><literal>gnome3.gvfs</literal></para></listitem>
<listitem><para><literal>gnome3.seahorse</literal></para></listitem>
<listitem><para><literal>hbase</literal></para></listitem>
<listitem><para><literal>i2pd</literal></para></listitem>
<listitem><para><literal>influxdb</literal></para></listitem>
<listitem><para><literal>kubernetes</literal></para></listitem>
<listitem><para><literal>liquidsoap</literal></para></listitem>
<listitem><para><literal>lxc</literal></para></listitem>
<listitem><para><literal>mailpile</literal></para></listitem>
<listitem><para><literal>mesos</literal></para></listitem>
<listitem><para><literal>mlmmj</literal></para></listitem>
<listitem><para><literal>monetdb</literal></para></listitem>
<listitem><para><literal>mopidy</literal></para></listitem>
<listitem><para><literal>neo4j</literal></para></listitem>
<listitem><para><literal>nsd</literal></para></listitem>
<listitem><para><literal>openntpd</literal></para></listitem>
<listitem><para><literal>opentsdb</literal></para></listitem>
<listitem><para><literal>openvswitch</literal></para></listitem>
<listitem><para><literal>parallels-guest</literal></para></listitem>
<listitem><para><literal>peerflix</literal></para></listitem>
<listitem><para><literal>phd</literal></para></listitem>
<listitem><para><literal>polipo</literal></para></listitem>
<listitem><para><literal>prosody</literal></para></listitem>
<listitem><para><literal>radicale</literal></para></listitem>
<listitem><para><literal>redmine</literal></para></listitem>
<listitem><para><literal>riemann</literal></para></listitem>
<listitem><para><literal>scollector</literal></para></listitem>
<listitem><para><literal>seeks</literal></para></listitem>
<listitem><para><literal>siproxd</literal></para></listitem>
<listitem><para><literal>strongswan</literal></para></listitem>
<listitem><para><literal>tcsd</literal></para></listitem>
<listitem><para><literal>teamspeak3</literal></para></listitem>
<listitem><para><literal>thermald</literal></para></listitem>
<listitem><para><literal>torque/mrom</literal></para></listitem>
<listitem><para><literal>torque/server</literal></para></listitem>
<listitem><para><literal>uhub</literal></para></listitem>
<listitem><para><literal>unifi</literal></para></listitem>
<listitem><para><literal>znc</literal></para></listitem>
<listitem><para><literal>zookeeper</literal></para></listitem>
</itemizedlist>
</para>
<para>When upgrading from a previous release, please be aware of the
following incompatible changes:
<itemizedlist>
<listitem><para>The default version of Apache httpd is now 2.4. If
you use the <option>extraConfig</option> option to pass literal
Apache configuration text, you may need to update it — see <link
xlink:href="http://httpd.apache.org/docs/2.4/upgrading.html">Apache’s
documentation</link> for details. If you wish to continue to use
httpd 2.2, add the following line to your NixOS configuration:
<programlisting>
services.httpd.package = pkgs.apacheHttpd_2_2;
</programlisting>
</para></listitem>
<listitem><para>PHP 5.3 has been removed because it is no longer
supported by the PHP project. A <link
xlink:href="http://php.net/migration54">migration guide</link> is
available.</para></listitem>
<listitem><para>The host side of a container virtual Ethernet pair
is now called <literal>ve-<replaceable>container-name</replaceable></literal>
rather than <literal>c-<replaceable>container-name</replaceable></literal>.</para></listitem>
<listitem><para>GNOME 3.10 support has been dropped. The default GNOME version is now 3.12.</para></listitem>
<listitem><para>VirtualBox has been upgraded to 4.3.20 release. Users
may be required to run <command>rm -rf /tmp/.vbox*</command>. The line
<literal>imports = [ &lt;nixpkgs/nixos/modules/programs/virtualbox.nix&gt; ]</literal> is
no longer necessary, use <literal>services.virtualboxHost.enable =
true</literal> instead.
</para>
<para>Also, hardening mode is now enabled by default, which means that unless you want to use
USB support, you no longer need to be a member of the <literal>vboxusers</literal> group.
</para></listitem>
<listitem><para>Chromium has been updated to 39.0.2171.65. <option>enablePepperPDF</option> is now enabled by default.
<literal>chromium*Wrapper</literal> packages no longer exist, because upstream removed NSAPI support.
<literal>chromium-stable</literal> has been renamed to <literal>chromium</literal>.
</para></listitem>
<listitem><para>Python packaging documentation is now part of nixpkgs manual. To override
the python packages available to a custom python you now use <literal>pkgs.pythonFull.buildEnv.override</literal>
instead of <literal>pkgs.pythonFull.override</literal>.
</para></listitem>
<listitem><para><literal>boot.resumeDevice = "8:6"</literal> is no longer supported. Most users will
want to leave it undefined, which takes the swap partitions automatically. There is an evaluation
assertion to ensure that the string starts with a slash.
</para></listitem>
<listitem><para>The system-wide default timezone for NixOS installations
changed from <literal>CET</literal> to <literal>UTC</literal>. To choose
a different timezone for your system, configure
<literal>time.timeZone</literal> in
<literal>configuration.nix</literal>. A fairly complete list of possible
values for that setting is available at <link
xlink:href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones"/>.</para></listitem>
<listitem><para>GNU screen has been updated to 4.2.1, which breaks
the ability to connect to sessions created by older versions of
screen.</para></listitem>
<listitem><para>The Intel GPU driver was updated to the 3.x prerelease
version (used by most distributions) and supports DRI3
now.</para></listitem>
</itemizedlist>
</para>
</chapter>

@ -0,0 +1,41 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-release-unstable">
<title>Unstable revision</title>
<para>In addition to numerous new and upgraded packages, this release has the following highlights:
<!--<itemizedlist>
</itemizedlist>-->
</para>
<para>Following new services were added since the last release:
<!--<itemizedlist>
</itemizedlist>-->
</para>
<para>When upgrading from a previous release, please be aware of the
following incompatible changes:
<itemizedlist>
<listitem><para>Steam now doesn't need root rights to work. Instead of using
<literal>*-steam-chrootenv</literal>, you should now just run <literal>steam</literal>.
<literal>steamChrootEnv</literal> package was renamed to <literal>steam</literal>,
and old <literal>steam</literal> package -- to <literal>steamOriginal</literal>.
</para></listitem>
<listitem><para>CMPlayer has been renamed to bomi upstream. Package <literal>cmplayer</literal>
was accordingly renamed to <literal>bomi</literal>
</para></listitem>
</itemizedlist>
</para>
</chapter>

@ -1,16 +0,0 @@
This file should become a nix expression. (see modules/installer/tools/tools.nix)
you need to:
- download the latest jQuery from and copy it to chrome/content:
http://code.jquery.com/jquery-1.5.2.js
- install 'xulrunner' with nix:
nix-env -Ai nixpkgs_sys.firefox40Pkgs.xulrunner
- make sure nixos-option in your path
- have /etc/nixos/nixpkgs
- have /etc/nixos/nixos
run it:
- xulrunner /etc/nixos/nixos/gui/application.ini -jsconsole

@ -1,36 +0,0 @@
[App]
;
; This field specifies your organization's name. This field is recommended,
; but optional.
Vendor=NixOS
;
; This field specifies your application's name. This field is required.
Name=NixOS-gui
;
; This field specifies your application's version. This field is optional.
Version=0.1
;
; This field specifies your application's build ID (timestamp). This field is
; required.
BuildID=20110424
;
; This field specifies a compact copyright notice for your application. This
; field is optional.
;Copyright=
;
; This ID is just an example. Every XUL app ought to have it's own unique ID.
; You can use the microsoft "guidgen" or "uuidgen" tools, or go on
; irc.mozilla.org and /msg botbot uuid. This field is optional.
;ID=
[Gecko]
;
; This field is required. It specifies the minimum Gecko version that this
; application requires.
MinVersion=1.9a5
;
; This field is optional. It specifies the maximum Gecko version that this
; application requires. It should be specified if your application uses
; unfrozen interfaces.
MaxVersion=2.*

@ -1 +0,0 @@
manifest chrome/chrome.manifest

@ -1 +0,0 @@
content nixos-gui content/

@ -1,137 +0,0 @@
function inspect(obj, maxLevels, level)
{
var str = '', type, msg;
// Start Input Validations
// Don't touch, we start iterating at level zero
if(level == null) level = 0;
// At least you want to show the first level
if(maxLevels == null) maxLevels = 1;
if(maxLevels < 1)
return '<font color="red">Error: Levels number must be > 0</font>';
// We start with a non null object
if(obj == null)
return '<font color="red">Error: Object <b>NULL</b></font>';
// End Input Validations
// Each Iteration must be indented
str += '<ul>';
// Start iterations for all objects in obj
for(property in obj)
{
try
{
// Show "property" and "type property"
type = typeof(obj[property]);
str += '<li>(' + type + ') ' + property +
( (obj[property]==null)?(': <b>null</b>'):('')) + '</li>';
// We keep iterating if this property is an Object, non null
// and we are inside the required number of levels
if((type == 'object') && (obj[property] != null) && (level+1 < maxLevels))
str += inspect(obj[property], maxLevels, level+1);
}
catch(err)
{
// Is there some properties in obj we can't access? Print it red.
if(typeof(err) == 'string') msg = err;
else if(err.message) msg = err.message;
else if(err.description) msg = err.description;
else msg = 'Unknown';
str += '<li><font color="red">(Error) ' + property + ': ' + msg +'</font></li>';
}
}
// Close indent
str += '</ul>';
return str;
}
// Run xulrunner application.ini -jsconsole -console, to see messages.
function log(str)
{
Components.classes['@mozilla.org/consoleservice;1']
.getService(Components.interfaces.nsIConsoleService)
.logStringMessage(str);
}
function makeTempFile(prefix)
{
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsIFile);
file.append(prefix || "xulrunner");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0664);
return file;
}
function writeToFile(file, data)
{
// file is nsIFile, data is a string
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
// use 0x02 | 0x10 to open file for appending.
foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
foStream.write(data, data.length);
foStream.close();
}
function readFromFile(file)
{
// |file| is nsIFile
var data = "";
var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);
fstream.init(file, -1, 0, 0);
sstream.init(fstream);
var str = sstream.read(4096);
while (str.length > 0) {
data += str;
str = sstream.read(4096);
}
sstream.close();
fstream.close();
return data;
}
function runProgram(commandLine)
{
// create an nsILocalFile for the executable
var file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath("/bin/sh");
// create an nsIProcess
var process = Components.classes["@mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
process.init(file);
// Run the process.
// If first param is true, calling thread will be blocked until
// called process terminates.
// Second and third params are used to pass command-line arguments
// to the process.
var args = ["-c", commandLine];
process.run(true, args, args.length);
}
// only for testing...
function testIO()
{
var f = makeTempFile();
writeToFile(f, "essai\ntest");
alert(readFromFile(f));
runProgram("zenity --info");
}

@ -1,70 +0,0 @@
// global variables.
var gNixOS;
var gOptionView;
/*
var gProgressBar;
function setProgress(current, max)
{
if (gProgressBar) {
gProgressBar.value = 100 * current / max;
log("progress: " + gProgressBar.value + "%");
}
else
log("unknow progress bar");
}
*/
function updateTextbox(id, value)
{
// setting the height cause an overflow which resize the textbox to its
// content due to its onoverflow attribute.
$(id).attr("value", value).attr("height", 1);
};
function updatePanel(options)
{
log("updatePanel: " + options.length);
if (options.length == 0)
return;
// FIXME: ignore the rest of the selection for now.
var o = options[0];
$("#name").attr("label", o.path);
if (o.typename != null)
$("#typename").attr("label", o.typename);
else
$("#typename").attr("label", "");
$("#desc").text(o.description);
if (o.value != null)
updateTextbox("#val", o.value);
else
updateTextbox("#val", "");
if (o.defaultValue != null)
updateTextbox("#def", o.defaultValue);
else
updateTextbox("#def", "");
if (o.example != null)
updateTextbox("#exp", o.example);
else
updateTextbox("#exp", "");
updateTextbox("#decls", o.declarations.join("\n"));
updateTextbox("#defs", o.definitions.join("\n"));
}
function onload()
{
var optionTree = document.getElementById("option-tree");
// gProgressBar = document.getElementById("progress-bar");
// setProgress(0, 1);
gNixOS = new NixOS();
gOptionView = new OptionView(gNixOS.option, updatePanel);
optionTree.view = gOptionView;
}

@ -1,63 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE window>
<!-- To edit this file I recommend you to use:
http://xulfr.org/outils/xulediteur.xul
-->
<window
id = "nixos-gui"
title = "NixOS gui"
width = "800"
height = "600"
xmlns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="jquery-1.5.2.js"/>
<script src="io.js"/>
<script src="nixos.js"/>
<script src="optionView.js"/>
<script src="main.js"/>
<hbox flex="1">
<vbox width="250">
<tree flex="1" id="option-tree" persist="height" onselect="gOptionView.selectionChanged()">
<treecols>
<treecol persist="hidden width" flex="9" id="opt-name"
label="Option" primary="true"/>
<!-- Uncomment the following column to see the number of option
printed below each options. -->
<!--
<treecol persist="hidden width" flex="1" id="dbg-size"
label="sz"/>
-->
</treecols>
<treechildren id="first-child" flex="1"/>
</tree>
</vbox>
<vbox flex="3" style="overflow: auto">
<caption id="name" label=""/>
<caption id="typename" label=""/>
<separator/>
<description id="desc" hidden="false"></description>
<separator/>
<caption label="Value:"/>
<textbox id="val" readonly="true" multiline="true" value=""
class="plain" hidden="false" onoverflow="this.height =
this.inputField.scrollHeight;" />
<separator/>
<caption label="Default:"/>
<textbox id="def" readonly="true" multiline="true" value="" class="plain" hidden="false" onoverflow="this.height = this.inputField.scrollHeight;" />
<separator/>
<caption label="Example:"/>
<textbox id="exp" readonly="true" multiline="true" value="" class="plain" hidden="false" onoverflow="this.height = this.inputField.scrollHeight;" />
<separator/>
<caption label="Declarations:"/>
<textbox id="decls" readonly="true" multiline="true" value="" class="plain" hidden="false" onoverflow="this.height = this.inputField.scrollHeight;" />
<separator/>
<caption label="Definitions:"/>
<textbox id="defs" readonly="true" multiline="true" value=""
class="plain" hidden="false" onoverflow="this.height = this.inputField.scrollHeight;" />
</vbox>
</hbox>
<!-- <progressmeter id="progress-bar" value="0%"/> -->
</window>

@ -1,255 +0,0 @@
function NixOS () {
var env = Components.classes["@mozilla.org/process/environment;1"].
getService(Components.interfaces.nsIEnvironment);
if (env.exists("NIXOS"))
this.nixos = env.get("NIXOS");
if (env.exists("NIXOS_CONFIG"))
this.config = env.get("NIXOS_CONFIG");
if (env.exists("NIXPKGS"))
this.nixpkgs = env.get("NIXPKGS");
if (env.exists("mountPoint"))
this.root = env.get("mountPoint");
if (env.exists("NIXOS_OPTION"))
this.optionBin = env.get("NIXOS_OPTION");
this.option = new Option("options", this, null);
};
NixOS.prototype = {
root: "",
nixos: "/etc/nixos/nixos",
nixpkgs: "/etc/nixos/nixpkgs",
config: "/etc/nixos/configuration.nix",
instantiateBin: "/run/current-system/sw/bin/nix-instantiate",
optionBin: "/run/current-system/sw/bin/nixos-option",
tmpFile: "nixos-gui",
option: null
};
function Option (name, context, parent) {
this.name = name;
this.context_ = context;
if (parent == null)
this.path = "";
else if (parent.path == "")
this.path = name;
else
this.path = parent.path + "." + name;
};
Option.prototype = {
load: function () {
var env = "";
env += "'NIXOS=" + this.context_.root + this.context_.nixos + "' ";
env += "'NIXOS_PKGS=" + this.context_.root + this.context_.nixpkgs + "' ";
env += "'NIXOS_CONFIG=" + this.context_.config + "' ";
var out = makeTempFile(this.context_.tmpFile);
var prog = this.context_.optionBin + " 2>&1 >" + out.path + " ";
var args = " --xml " + this.path;
runProgram(/*env + */ prog + args);
var xml = readFromFile(out);
out.remove(false);
// jQuery does a stack overflow when converting a huge XML to a DOM.
var dom = DOMParser().parseFromString(xml, "text/xml");
var xmlAttrs = $("expr > attrs > attr", dom);
this.isOption = xmlAttrs.first().attr("name") == "_isOption";
if (!this.isOption)
this.loadSubOptions(xmlAttrs);
else
this.loadOption(xmlAttrs);
this.isLoaded = true;
},
loadSubOptions: function (xmlAttrs) {
var cur = this;
var attrs = new Array();
xmlAttrs.each(
function (index) {
var name = $(this).attr("name");
var attr = new Option(name, cur.context_, cur);
attrs.push(attr);
}
);
this.subOptions = attrs;
},
optionAttributeMap: {
_isOption: function (cur, v) { },
value: function (cur, v) { cur.value = xml2nix($(v).children().first()); },
default: function (cur, v) { cur.defaultValue = xml2nix($(v).children().first()); },
example: function (cur, v) { cur.example = xml2nix($(v).children().first()); },
description: function (cur, v) { cur.description = this.string(v); },
typename: function (cur, v) { cur.typename = this.string(v); },
options: function (cur, v) { cur.loadSubOptions($("attrs", v).children()); },
declarations: function (cur, v) { cur.declarations = this.pathList(v); },
definitions: function (cur, v) { cur.definitions = this.pathList(v); },
string: function (v) {
return $(v).children("string").first().attr("value");
},
pathList: function (v) {
var list = [];
$(v).children("list").first().children().each(
function (idx) {
list.push($(this).attr("value"));
}
);
return list;
}
},
loadOption: function (attrs) {
var cur = this;
attrs.each(
function (index) {
var name = $(this).attr("name");
log("loadOption: " + name);
cur.optionAttributeMap[name](cur, this);
}
);
},
// keep the context under which this option has been used.
context_: null,
// name of the option.
name: "",
// result of nixos-option.
value: null,
typename: null,
defaultValue: null,
example: null,
description: "",
declarations: [],
definitions: [],
// path to reach this option
path: "",
// list of options accessible from here.
isLoaded: false,
isOption: false,
subOptions: []
};
var xml2nix_pptable = {
attrs: function (node, depth, pp) {
var children = node.children().not(
function () {
var name = $(this).attr("name");
return name.charAt(0) == "_";
}
);
var c = 0;
var out = "";
out += "{";
depth += 1;
children.each(
function (idx) {
c += 1;
out += pp.indent(depth);
out += pp.dispatch($(this), depth, pp);
}
);
depth -= 1;
if (c > 0)
out += this.indent(depth);
else
out += " ";
out += "}";
return out;
},
list: function (node, depth, pp) {
var children = node.children();
var c = 0;
var out = "";
out += "[";
depth += 1;
children.each(
function (idx) {
c += 1;
out += pp.indent(depth);
out += pp.dispatch($(this), depth, pp);
}
);
depth -= 1;
if (c > 0)
out += this.indent(depth);
else
out += " ";
out += "]";
return out;
},
attr: function (node, depth, pp) {
var name = node.attr("name");
var out = "";
var val = "";
out += name + " = ";
depth += 1;
val = pp.dispatch(node.children().first(), depth, pp);
out += val;
depth -= 1;
out += ";";
return out;
},
string: function (node, depth, pp) {
return "\"" + node.attr("value") + "\"";
},
path: function (node, depth, pp) {
return node.attr("value");
},
bool: function (node, depth, pp) {
return node.attr("value");
},
"int": function (node, depth, pp) {
return node.attr("value");
},
null: function (node, depth, pp) {
return "null";
},
derivation: function (node, depth, pp) {
return "<derivation>";
},
function: function (node, depth, pp) {
return "<function>";
},
unevaluated: function (node, depth, pp) {
return "<unevaluated>";
},
dispatch: function (node, depth, pp) {
for (var key in pp)
{
if(node.is(key))
{
// log(this.indent(depth) + "dispatch: " + key);
var out = pp[key](node, depth, pp);
// log(this.indent(depth) + "dispatch: => " + out);
return out;
}
}
return "<dispatch-error>";
},
indent: function (depth) {
var ret = "\n";
while (depth--)
ret += " ";
return ret;
}
};
function xml2nix(node) {
var depth = 0;
var pp = xml2nix_pptable;
var out = pp.dispatch(node, depth, pp);
// log("pretty:\n" + out);
return out;
}

@ -1,242 +0,0 @@
// extend NixOS options to handle the Tree View. Should be better to keep a
// separation of concern here.
Option.prototype.tv_opened = false;
Option.prototype.tv_size = 1;
Option.prototype.tv_open = function () {
this.tv_opened = true;
this.tv_size = 1;
// load an option if it is not loaded yet, and initialize them to be
// read by the Option view.
if (!this.isLoaded)
this.load();
// If this is not an option, then add it's lits of sub-options size.
if (!this.isOption)
{
for (var i = 0; i < this.subOptions.length; i++)
this.tv_size += this.subOptions[i].tv_size;
}
};
Option.prototype.tv_close = function () {
this.tv_opened = false;
this.tv_size = 1;
};
function OptionView (root, selCallback) {
root.tv_open();
this.rootOption = root;
this.selCallback = selCallback;
}
OptionView.prototype = {
rootOption: null,
selCallback: null,
// This function returns the path to option which is at the specified row.
reach_cache: null,
reachRow: function (row) {
var o = this.rootOption; // Current option.
var r = 0; // Number of rows traversed.
var c = 0; // Child index.
var path = [{ row: r, opt: o }]; // new Array();
// hypothesis: this.rootOption.tv_size is always open and bigger than
// Use the previous returned value to avoid making to many checks and to
// optimize for frequent access of near rows.
if (this.reach_cache != null)
{
for (var i = this.reach_cache.length - 2; i >= 0; i--) {
var p = this.reach_cache[i];
// If we will have to go the same path.
if (row >= p.row && row < p.row + p.opt.tv_size)
{
path.unshift(p);
r = path[0].row;
o = path[0].opt;
}
else
break;
};
}
while (r != row)
{
// Go deeper in the child which contains the requested row. The
// tv_size contains the size of the tree starting from each option.
c = 0;
while (c < o.subOptions.length && r + o.subOptions[c].tv_size < row)
{
r += o.subOptions[c].tv_size;
c += 1;
}
if (c < o.subOptions.length && r + o.subOptions[c].tv_size >= row)
{
// Count the current option as a row.
o = o.subOptions[c];
r += 1;
}
else
alert("WTF: " + o.name + " ask: " + row + " children: " + o.subOptions + " c: " + c);
path.unshift({ row: r, opt: o });
}
this.reach_cache = path;
return path;
},
// needs to return true if there is a /row/ at the same level /after/ a
// given row.
hasNextSibling: function(row, after) {
log("sibling " + row + " after " + after);
var path = reachRow(row);
if (path.length > 1)
{
var last = path[1].row + path[1].opt.tv_size;
// Has a next sibling if the row is not over the size of the
// parent and if the current one is not the last child.
return after + 1 < last && path[0].row + path[0].opt.tv_size < last;
}
else
// The top-level option has no sibling.
return false;
},
// Does the current row contain any sub-options?
isContainer: function(row) {
return !this.reachRow(row)[0].opt.isOption;
},
isContainerEmpty: function(row) {
return this.reachRow(row)[0].opt.subOptions.length == 0;
},
isContainerOpen: function(row) {
return this.reachRow(row)[0].opt.tv_opened;
},
// Open or close an option.
toggleOpenState: function (row) {
var path = this.reachRow(row);
var delta = -path[0].opt.tv_size;
if (path[0].opt.tv_opened)
path[0].opt.tv_close();
else
path[0].opt.tv_open();
delta += path[0].opt.tv_size;
// Parents are alreay opened, but we need to update the tv_size
// counters. Thus we have to invalidate the reach cache.
this.reach_cache = null;
for (var i = 1; i < path.length; i++)
path[i].opt.tv_open();
this.tree.rowCountChanged(row + 1, delta);
},
// Return the identation level of the option at the line /row/. The
// top-level level is 0.
getLevel: function(row) {
return this.reachRow(row).length - 1;
},
// Obtain the index of a parent row. If there is no parent row,
// returns -1.
getParentIndex: function(row) {
var path = this.reachRow(row);
if (path.length > 1)
return path[1].row;
else
return -1;
},
// Return the content of each row base on the column name.
getCellText: function(row, column) {
if (column.id == "opt-name")
return this.reachRow(row)[0].opt.name;
if (column.id == "dbg-size")
return this.reachRow(row)[0].opt.tv_size;
return "";
},
// We have no column with images.
getCellValue: function(row, column) { },
isSelectable: function(row, column) { return true; },
// Get the selection out of the tree and give options to the call back
// function.
selectionChanged: function() {
if (this.selCallback == null)
return;
var opts = [];
var start = new Object();
var end = new Object();
var numRanges = this.tree.view.selection.getRangeCount();
for (var t = 0; t < numRanges; t++) {
this.tree.view.selection.getRangeAt(t,start,end);
for (var v = start.value; v <= end.value; v++) {
var opt = this.reachRow(v)[0].opt;
if (!opt.isLoaded)
opt.load();
if (opt.isOption)
opts.push(opt);
// FIXME: no need to make things slowing down, because our current
// callback do not handle multiple option display.
if (!opts.empty)
break;
}
// FIXME: no need to make things slowing down, because our current
// callback do not handle multiple option display.
if (!opts.empty)
break;
}
if (!opts.empty)
this.selCallback(opts);
},
set rowCount(c) { throw "rowCount is a readonly property"; },
get rowCount() { return this.rootOption.tv_size; },
// refuse drag-n-drop of options.
canDrop: function (index, orientation, dataTransfer) { return false; },
drop: function (index, orientation, dataTransfer) { },
// ?
getCellProperties: function(row, column, prop) { },
getColumnProperties: function(column, prop) { },
getRowProperties: function(row, prop) { },
getImageSrc: function(row, column) { },
// No progress columns are used.
getProgressMode: function(row, column) { },
// Do not add options yet.
isEditable: function(row, column) { return false; },
setCellValue: function(row, column, value) { },
setCellText: function(row, column, value) { },
// ...
isSeparator: function(index) { return false; },
isSorted: function() { return false; },
performAction: function(action) { },
performActionOnCell: function(action, row, column) { },
performActionOnRow: function(action, row) { }, // ??
// ??
cycleCell: function (row, col) { },
cycleHeader: function(col) { },
selection: null,
tree: null,
setTree: function(tree) { this.tree = tree; }
};

@ -1,154 +0,0 @@
const nsIAppShellService = Components.interfaces.nsIAppShellService;
const nsISupports = Components.interfaces.nsISupports;
const nsICategoryManager = Components.interfaces.nsICategoryManager;
const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
const nsICommandLine = Components.interfaces.nsICommandLine;
const nsICommandLineHandler = Components.interfaces.nsICommandLineHandler;
const nsIFactory = Components.interfaces.nsIFactory;
const nsIModule = Components.interfaces.nsIModule;
const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
// CHANGEME: to the chrome URI of your extension or application
const CHROME_URI = "chrome://nixos-gui/content/myviewer.xul";
// CHANGEME: change the contract id, CID, and category to be unique
// to your application.
const clh_contractID = "@mozilla.org/commandlinehandler/general-startup;1?type=myapp";
// use uuidgen to generate a unique ID
const clh_CID = Components.ID("{2991c315-b871-42cd-b33f-bfee4fcbf682}");
// category names are sorted alphabetically. Typical command-line handlers use a
// category that begins with the letter "m".
const clh_category = "m-myapp";
/**
* Utility functions
*/
/**
* Opens a chrome window.
* @param aChromeURISpec a string specifying the URI of the window to open.
* @param aArgument an argument to pass to the window (may be null)
*/
function openWindow(aChromeURISpec, aArgument)
{
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].
getService(Components.interfaces.nsIWindowWatcher);
ww.openWindow(null, aChromeURISpec, "_blank",
"chrome,menubar,toolbar,status,resizable,dialog=no",
aArgument);
}
/**
* The XPCOM component that implements nsICommandLineHandler.
* It also implements nsIFactory to serve as its own singleton factory.
*/
const myAppHandler = {
/* nsISupports */
QueryInterface : function clh_QI(iid)
{
if (iid.equals(nsICommandLineHandler) ||
iid.equals(nsIFactory) ||
iid.equals(nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
/* nsICommandLineHandler */
handle : function clh_handle(cmdLine)
{
openWindow(CHROME_URI, cmdLine);
cmdLine.preventDefault = true;
},
// CHANGEME: change the help info as appropriate, but
// follow the guidelines in nsICommandLineHandler.idl
// specifically, flag descriptions should start at
// character 24, and lines should be wrapped at
// 72 characters with embedded newlines,
// and finally, the string should end with a newline
helpInfo : " <filename> Open the file in the viewer\n",
/* nsIFactory */
createInstance : function clh_CI(outer, iid)
{
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return this.QueryInterface(iid);
},
lockFactory : function clh_lock(lock)
{
/* no-op */
}
};
/**
* The XPCOM glue that implements nsIModule
*/
const myAppHandlerModule = {
/* nsISupports */
QueryInterface : function mod_QI(iid)
{
if (iid.equals(nsIModule) ||
iid.equals(nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
/* nsIModule */
getClassObject : function mod_gch(compMgr, cid, iid)
{
if (cid.equals(clh_CID))
return myAppHandler.QueryInterface(iid);
throw Components.results.NS_ERROR_NOT_REGISTERED;
},
registerSelf : function mod_regself(compMgr, fileSpec, location, type)
{
compMgr.QueryInterface(nsIComponentRegistrar);
compMgr.registerFactoryLocation(clh_CID,
"myAppHandler",
clh_contractID,
fileSpec,
location,
type);
var catMan = Components.classes["@mozilla.org/categorymanager;1"].
getService(nsICategoryManager);
catMan.addCategoryEntry("command-line-handler",
clh_category,
clh_contractID, true, true);
},
unregisterSelf : function mod_unreg(compMgr, location, type)
{
compMgr.QueryInterface(nsIComponentRegistrar);
compMgr.unregisterFactoryLocation(clh_CID, location);
var catMan = Components.classes["@mozilla.org/categorymanager;1"].
getService(nsICategoryManager);
catMan.deleteCategoryEntry("command-line-handler", clh_category);
},
canUnload : function (compMgr)
{
return true;
}
};
/* The NSGetModule function is the magic entry point that XPCOM uses to find what XPCOM objects
* this component provides
*/
function NSGetModule(comMgr, fileSpec)
{
return myAppHandlerModule;
}

@ -1,11 +0,0 @@
pref("toolkit.defaultChromeURI", "chrome://nixos-gui/content/myviewer.xul");
pref("general.useragent.extra.myviewer", "NixOS gui/0.0");
/* debugging prefs */
pref("browser.dom.window.dump.enabled", true); // enable output to stderr
pref("javascript.options.showInConsole", true); // show javascript errors from chrome: files in the jsconsole
pref("javascript.options.strict", true); // show javascript strict warnings in the jsconsole
/* disable xul cache so that modifications to chrome: files apply without restarting xulrunner */
pref("nglayout.debug.disable_xul_cache", true);
pref("nglayout.debug.disable_xul_fastload", true);

@ -48,10 +48,11 @@ rec {
let
interfacesNumbered = zipTwoLists config.virtualisation.vlans (range 1 255);
interfaces = flip map interfacesNumbered ({ first, second }:
nameValuePair "eth${toString second}"
{ ipAddress = "192.168.${toString first}.${toString m.second}";
subnetMask = "255.255.255.0";
});
nameValuePair "eth${toString second}" { ip4 =
[ { address = "192.168.${toString first}.${toString m.second}";
prefixLength = 24;
} ];
});
in
{ key = "ip-address";
config =
@ -60,7 +61,7 @@ rec {
networking.interfaces = listToAttrs interfaces;
networking.primaryIPAddress =
optionalString (interfaces != []) (head interfaces).value.ipAddress;
optionalString (interfaces != []) (head (head interfaces).value.ip4).address;
# Put the IP addresses of all VMs in this machine's
# /etc/hosts file. If a machine has multiple
@ -69,7 +70,7 @@ rec {
# virtualisation.vlans option).
networking.extraHosts = flip concatMapStrings machines
(m': let config = (getAttr m' nodes).config; in
optionalString (m.first != m' && config.networking.primaryIPAddress != "")
optionalString (config.networking.primaryIPAddress != "")
("${config.networking.primaryIPAddress} " +
"${config.networking.hostName}\n"));

@ -2,26 +2,51 @@
# configuration object (`config') from which we can retrieve option
# values.
{ system ? builtins.currentSystem
, pkgs ? null
, baseModules ? import ../modules/module-list.nix
, extraArgs ? {}
# !!! Please think twice before adding to this argument list!
# Ideally eval-config.nix would be an extremely thin wrapper
# around lib.evalModules, so that modular systems that have nixos configs
# as subcomponents (e.g. the container feature, or nixops if network
# expressions are ever made modular at the top level) can just use
# types.submodule instead of using eval-config.nix
{ # !!! system can be set modularly, would be nice to remove
system ? builtins.currentSystem
, # !!! is this argument needed any more? The pkgs argument can
# be set modularly anyway.
pkgs ? null
, # !!! what do we gain by making this configurable?
baseModules ? import ../modules/module-list.nix
, # !!! See comment about args in lib/modules.nix
extraArgs ? {}
, modules
, check ? true
, # !!! See comment about check in lib/modules.nix
check ? true
, prefix ? []
, lib ? import ../../lib
}:
let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system; in
let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system;
extraModules = let e = builtins.getEnv "NIXOS_EXTRA_MODULE_PATH";
in if e == "" then [] else [(import (builtins.toPath e))];
in
rec {
let
pkgsModule = rec {
_file = ./eval-config.nix;
key = _file;
config = {
nixpkgs.system = lib.mkDefault system_;
_module.args.pkgs = lib.mkIf (pkgs_ != null) (lib.mkForce pkgs_);
};
};
in rec {
# Merge the option definitions in all modules, forming the full
# system configuration.
inherit (pkgs.lib.evalModules {
inherit prefix;
modules = modules ++ baseModules;
inherit (lib.evalModules {
inherit prefix check;
modules = modules ++ extraModules ++ baseModules ++ [ pkgsModule ];
args = extraArgs;
check = check && options.environment.checkConfigurationOptions.value;
}) config options;
# These are the extra arguments passed to every module. In
@ -32,40 +57,8 @@ rec {
# the 64-bit package anyway. However, it would be cleaner to respect
# nixpkgs.config here.
extraArgs = extraArgs_ // {
inherit pkgs modules baseModules;
modulesPath = ../modules;
pkgs_i686 = import ./nixpkgs.nix { system = "i686-linux"; config.allowUnfree = true; };
utils = import ./utils.nix pkgs;
inherit modules baseModules;
};
# Import Nixpkgs, allowing the NixOS option nixpkgs.config to
# specify the Nixpkgs configuration (e.g., to set package options
# such as firefox.enableGeckoMediaPlayer, or to apply global
# overrides such as changing GCC throughout the system), and the
# option nixpkgs.system to override the platform type. This is
# tricky, because we have to prevent an infinite recursion: "pkgs"
# is passed as an argument to NixOS modules, but the value of "pkgs"
# depends on config.nixpkgs.config, which we get from the modules.
# So we call ourselves here with "pkgs" explicitly set to an
# instance that doesn't depend on nixpkgs.config.
pkgs =
if pkgs_ != null
then pkgs_
else import ./nixpkgs.nix (
let
system = if nixpkgsOptions.system != "" then nixpkgsOptions.system else system_;
nixpkgsOptions = (import ./eval-config.nix {
inherit system extraArgs modules prefix;
# For efficiency, leave out most NixOS modules; they don't
# define nixpkgs.config, so it's pointless to evaluate them.
baseModules = [ ../modules/misc/nixpkgs.nix ../modules/config/no-x-libs.nix ];
pkgs = import ./nixpkgs.nix { system = system_; config = {}; };
check = false;
}).config.nixpkgs;
in
{
inherit system;
inherit (nixpkgsOptions) config;
});
inherit (config._module.args) pkgs;
}

@ -1,4 +1,4 @@
{ stdenv, perl, cdrkit, pathsFromGraph
{ stdenv, perl, pathsFromGraph, xorriso, syslinux
, # The file name of the resulting ISO image.
isoName ? "cd.iso"
@ -22,12 +22,18 @@
, # Whether this should be an efi-bootable El-Torito CD.
efiBootable ? false
, # Wheter this should be an hybrid CD (bootable from USB as well as CD).
usbBootable ? false
, # The path (in the ISO file system) of the boot image.
bootImage ? ""
, # The path (in the ISO file system) of the efi boot image.
efiBootImage ? ""
, # The path (outside the ISO file system) of the isohybrid-mbr image.
isohybridMbrImage ? ""
, # Whether to compress the resulting ISO image with bzip2.
compressImage ? false
@ -38,13 +44,14 @@
assert bootable -> bootImage != "";
assert efiBootable -> efiBootImage != "";
assert usbBootable -> isohybridMbrImage != "";
stdenv.mkDerivation {
name = "iso9660-image";
builder = ./make-iso9660-image.sh;
buildInputs = [perl cdrkit];
buildInputs = [perl xorriso syslinux];
inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable;
inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable isohybridMbrImage usbBootable;
# !!! should use XML.
sources = map (x: x.source) contents;

@ -13,6 +13,20 @@ stripSlash() {
if test "${res:0:1}" = /; then res=${res:1}; fi
}
# Escape potential equal signs (=) with backslash (\=)
escapeEquals() {
echo "$1" | sed -e 's/\\/\\\\/g' -e 's/=/\\=/g'
}
# Queues an file/directory to be placed on the ISO.
# An entry consists of a local source path (2) and
# a destination path on the ISO (1).
addPath() {
target="$1"
source="$2"
echo "$(escapeEquals "$target")=$(escapeEquals "$source")" >> pathlist
}
stripSlash "$bootImage"; bootImage="$res"
@ -31,11 +45,20 @@ if test -n "$bootable"; then
fi
done
bootFlags="-b $bootImage -c .boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table"
isoBootFlags="-eltorito-boot ${bootImage}
-eltorito-catalog .boot.cat
-no-emul-boot -boot-load-size 4 -boot-info-table"
fi
if test -n "$usbBootable"; then
usbBootFlags="-isohybrid-mbr ${isohybridMbrImage}"
fi
if test -n "$efiBootable"; then
bootFlags="$bootFlags -eltorito-alt-boot -e $efiBootImage -no-emul-boot"
efiBootFlags="-eltorito-alt-boot
-e $efiBootImage
-no-emul-boot
-isohybrid-gpt-basdat"
fi
touch pathlist
@ -44,14 +67,14 @@ touch pathlist
# Add the individual files.
for ((i = 0; i < ${#targets_[@]}; i++)); do
stripSlash "${targets_[$i]}"
echo "$res=${sources_[$i]}" >> pathlist
addPath "$res" "${sources_[$i]}"
done
# Add the closures of the top-level store objects.
storePaths=$(perl $pathsFromGraph closure-*)
for i in $storePaths; do
echo "${i:1}=$i" >> pathlist
addPath "${i:1}" "$i"
done
@ -59,7 +82,7 @@ done
# nix-store --load-db.
if [ -n "$object" ]; then
printRegistration=1 perl $pathsFromGraph closure-* > nix-path-registration
echo "nix-path-registration=nix-path-registration" >> pathlist
addPath "nix-path-registration" "nix-path-registration"
fi
@ -70,22 +93,39 @@ for ((n = 0; n < ${#objects[*]}; n++)); do
if test "$symlink" != "none"; then
mkdir -p $(dirname ./$symlink)
ln -s $object ./$symlink
echo "$symlink=./$symlink" >> pathlist
addPath "$symlink" "./$symlink"
fi
done
# !!! what does this do?
cat pathlist | sed -e 's/=\(.*\)=\(.*\)=/\\=\1=\2\\=/' | tee pathlist.safer
mkdir -p $out/iso
genCommand="genisoimage -iso-level 4 -r -J $bootFlags -hide-rr-moved -graft-points -path-list pathlist.safer ${volumeID:+-V $volumeID}"
if test -z "$compressImage"; then
$genCommand -o $out/iso/$isoName
else
$genCommand | bzip2 > $out/iso/$isoName.bz2
xorriso="xorriso
-as mkisofs
-iso-level 3
-volid ${volumeID}
-appid nixos
-publisher nixos
-graft-points
-full-iso9660-filenames
${isoBootFlags}
${usbBootFlags}
${efiBootFlags}
-r
-path-list pathlist
--sort-weight 0 /
--sort-weight 1 /isolinux" # Make sure isolinux is near the beginning of the ISO
$xorriso -output $out/iso/$isoName
if test -n "$usbBootable"; then
echo "Making image hybrid..."
isohybrid --uefi $out/iso/$isoName
fi
if test -n "$compressImage"; then
echo "Compressing image..."
bzip2 $out/iso/$isoName
fi
mkdir -p $out/nix-support
echo $system > $out/nix-support/system

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save