summary refs log tree commit diff
path: root/lib/modules.nix
diff options
context:
space:
mode:
authorEric Sagnes <eric.sagnes@gmail.com>2016-09-24 21:09:52 +0900
committerEric Sagnes <eric.sagnes@gmail.com>2016-09-24 21:09:52 +0900
commit13eefc3a31c63febafec5107d38b60c8ddc3788e (patch)
tree763e8eda809236da1e88d3972b76fe73562a8db6 /lib/modules.nix
parentcdec20ac58325af1f606a59413d5a31fc839c8d4 (diff)
downloadnixpkgs-13eefc3a31c63febafec5107d38b60c8ddc3788e.tar
nixpkgs-13eefc3a31c63febafec5107d38b60c8ddc3788e.tar.gz
nixpkgs-13eefc3a31c63febafec5107d38b60c8ddc3788e.tar.bz2
nixpkgs-13eefc3a31c63febafec5107d38b60c8ddc3788e.tar.lz
nixpkgs-13eefc3a31c63febafec5107d38b60c8ddc3788e.tar.xz
nixpkgs-13eefc3a31c63febafec5107d38b60c8ddc3788e.tar.zst
nixpkgs-13eefc3a31c63febafec5107d38b60c8ddc3788e.zip
lib/module: add mkMergedOptionModule function
Diffstat (limited to 'lib/modules.nix')
-rw-r--r--lib/modules.nix53
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/modules.nix b/lib/modules.nix
index 6f08a49399a..d25a064ac8b 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -1,4 +1,5 @@
 with import ./lists.nix;
+with import ./strings.nix;
 with import ./trivial.nix;
 with import ./attrsets.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}'.";
   };
 
+  /* 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. */
   mkAliasOptionModule = from: to: doRename {
     inherit from to;