adding assertion support to modular-nixos

problem: the nix language assert function can't be used because
of the fix-style used in modular-nixos. A minimal stripped down version
illustrating the problem looks like this:

fix (x : assert x.cfg.foo; { upstartJob = ...; cfg = ...; } )

Now nix has to evaluate x.cfg.foo in order to check the assertion.
However to do so it has to access x.cfg.foo beeing defined in the body
The body can only be evaluated after the assertion passes.
So in the end you get an infinite recursion error.

pierron mentioned that adding another mkIf like function could
work. Maybe this implementation is even simpler. It adds
another option collecting assertions only.
The evaluation is forced by a function adding an empty list to
extraPackages. extraPackages is evaluated by nixos in all cases.
If there are assertions evaluating to false all assertion messages are
presented to the user using throw.

svn path=/nixos/branches/modular-nixos/; revision=15387
This commit is contained in:
Marc Weber 2009-04-28 23:05:03 +00:00
parent 84b5d26ffc
commit d804730382
2 changed files with 28 additions and 0 deletions

25
system/assertion.nix Normal file
View File

@ -0,0 +1,25 @@
{pkgs, config, ...}:
let
inherit (pkgs.lib) mkOption filter concatMap concatStringsSep;
failed = map (x : x.message) (filter (x: ! x.assertion) config.assertions);
in
{
assertions = mkOption {
default = [];
example = [{ assertion = false; msg = "you can't enable this for that reason"; }];
merge = pkgs.lib.mergeListOption;
description = ''
Add something like this
assertions = mkAlways [ { assertion = false; message = "false should have been true"; } ];
to your upstart-job.
'';
};
environment = {
# extraPackages are evaluated always. Thus the assertions are checked as well. hacky!
extraPackages = if [] == failed then [] else throw "\n!! failed assertions: !!\n${concatStringsSep "\n" (map (x: "- ${x}") failed)}";
};
}

View File

@ -379,6 +379,9 @@ in
}; };
require = [ require = [
(import ../system/assertion.nix)
# boot (is it the right place ?) # boot (is it the right place ?)
(import ../system/kernel.nix) (import ../system/kernel.nix)
(import ../boot/boot-stage-2.nix) (import ../boot/boot-stage-2.nix)