diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2013-10-28 19:48:30 +0100 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2013-10-28 22:45:57 +0100 |
commit | 73f32d03758a53ad1baac31795cfd99e325032f3 (patch) | |
tree | 8df21c7319e758a85a4916890714b0d90c631a67 /lib/options.nix | |
parent | dbefab9cf42c09444dd2554380104096969c0728 (diff) | |
download | nixpkgs-73f32d03758a53ad1baac31795cfd99e325032f3.tar nixpkgs-73f32d03758a53ad1baac31795cfd99e325032f3.tar.gz nixpkgs-73f32d03758a53ad1baac31795cfd99e325032f3.tar.bz2 nixpkgs-73f32d03758a53ad1baac31795cfd99e325032f3.tar.lz nixpkgs-73f32d03758a53ad1baac31795cfd99e325032f3.tar.xz nixpkgs-73f32d03758a53ad1baac31795cfd99e325032f3.tar.zst nixpkgs-73f32d03758a53ad1baac31795cfd99e325032f3.zip |
Show precise error messages in option merge failures
For instance, if time.timeZone is defined multiple times, you now get the error message: error: user-thrown exception: The unique option `time.timeZone' is defined multiple times, in `/etc/nixos/configurations/misc/eelco/x11vnc.nix' and `/etc/nixos/configuration.nix'. while previously you got: error: user-thrown exception: Multiple definitions of string. Only one is allowed for this option. and only an inspection of the stack trace gave a clue as to what option caused the problem.
Diffstat (limited to 'lib/options.nix')
-rw-r--r-- | lib/options.nix | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/lib/options.nix b/lib/options.nix index d649d1160a0..66957bc7f15 100644 --- a/lib/options.nix +++ b/lib/options.nix @@ -35,7 +35,7 @@ rec { addDefaultOptionValues = defs: opts: opts // builtins.listToAttrs (map (defName: { name = defName; - value = + value = let defValue = builtins.getAttr defName defs; optValue = builtins.getAttr defName opts; @@ -49,27 +49,26 @@ rec { else # `defValue' is an attribute set containing options. # So recurse. - if hasAttr defName opts && isAttrs optValue + if hasAttr defName opts && isAttrs optValue then addDefaultOptionValues defValue optValue else addDefaultOptionValues defValue {}; } ) (attrNames defs)); - mergeDefaultOption = list: + mergeDefaultOption = args: list: if length list == 1 then head list - else if all builtins.isFunction list then x: mergeDefaultOption (map (f: f x) list) + else if all builtins.isFunction list then x: mergeDefaultOption args (map (f: f x) list) else if all isList list then concatLists list else if all isAttrs list then fold lib.mergeAttrs {} list else if all builtins.isBool list then fold lib.or false list else if all builtins.isString list then lib.concatStrings list - else if all builtins.isInt list && all (x: x == head list) list - then head list - else throw "Cannot merge values."; + else if all builtins.isInt list && all (x: x == head list) list then head list + else throw "Cannot merge definitions of `${showOption args.prefix}' given in ${showFiles args.files}."; /* Obsolete, will remove soon. Specify an option type or apply function instead. */ - mergeTypedOption = typeName: predicate: merge: list: + mergeTypedOption = typeName: predicate: merge: args: list: if all predicate list then merge list else throw "Expect a ${typeName}."; @@ -82,9 +81,10 @@ rec { (x: if builtins ? isString then builtins.isString x else x + "") lib.concatStrings; - mergeOneOption = list: + mergeOneOption = args: list: if list == [] then abort "This case should never happen." - else if length list != 1 then throw "Multiple definitions. Only one is allowed for this option." + else if length list != 1 then + throw "The unique option `${showOption args.prefix}' is defined multiple times, in ${showFiles args.files}." else head list; @@ -135,6 +135,7 @@ rec { /* Helper functions. */ showOption = concatStringsSep "."; + showFiles = files: concatStringsSep " and " (map (f: "`${f}'") files); unknownModule = "<unknown-file>"; } |