lib/module: add mkMergedOptionModule function

This commit is contained in:
Eric Sagnes 2016-09-24 21:09:52 +09:00
parent cdec20ac58
commit 13eefc3a31

View File

@ -1,4 +1,5 @@
with import ./lists.nix; with import ./lists.nix;
with import ./strings.nix;
with import ./trivial.nix; with import ./trivial.nix;
with import ./attrsets.nix; with import ./attrsets.nix;
with import ./options.nix; with import ./options.nix;
@ -545,6 +546,58 @@ rec {
use = builtins.trace "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'."; use = builtins.trace "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'.";
}; };
/* Return a module that causes a warning to be shown if any of the "from"
option is defined; the defined values can be used in the "mergeFn" to set
the "to" value.
This function can be used to merge multiple options into one that has a
different type.
"mergeFn" takes the module "config" as a parameter and must return a value
of "to" option type.
mkMergedOptionModule
[ [ "a" "b" "c" ]
[ "d" "e" "f" ] ]
[ "x" "y" "z" ]
(config:
let value = p: getAttrFromPath p config;
in
if (value [ "a" "b" "c" ]) == true then "foo"
else if (value [ "d" "e" "f" ]) == true then "bar"
else "baz")
- options.a.b.c is a removed boolean option
- options.d.e.f is a removed boolean option
- options.x.y.z is a new str option that combines a.b.c and d.e.f
functionality
This show a warning if any a.b.c or d.e.f is set, and set the value of
x.y.z to the result of the merge function
*/
mkMergedOptionModule = from: to: mergeFn:
{ config, options, ... }:
{
options = foldl recursiveUpdate {} (map (path: setAttrByPath path (mkOption {
visible = false;
# To use the value in mergeFn without triggering errors
default = "_mkMergedOptionModule";
})) from);
config = {
warnings = filter (x: x != "") (map (f:
let val = getAttrFromPath f config;
opt = getAttrFromPath f options;
in
optionalString
(val != "_mkMergedOptionModule")
"The option `${showOption f}' defined in ${showFiles opt.files} has been changed to `${showOption to}' that has a different type. Please read `${showOption to}' documentation and update your configuration accordingly."
) from);
} // setAttrByPath to (mkMerge
(optional
(any (f: (getAttrFromPath f config) != "_mkMergedOptionModule") from)
(mergeFn config)));
};
/* Like mkRenamedOptionModule, but doesn't show a warning. */ /* Like mkRenamedOptionModule, but doesn't show a warning. */
mkAliasOptionModule = from: to: doRename { mkAliasOptionModule = from: to: doRename {
inherit from to; inherit from to;