summary refs log tree commit diff
path: root/lib/modules.nix
diff options
context:
space:
mode:
authorDaiderd Jordan <daiderd@gmail.com>2017-02-14 23:18:44 +0100
committerVladimír Čunát <vcunat@gmail.com>2017-03-03 13:45:22 +0100
commitd88721e4408988202a0ae3cea3f5551ebfa13168 (patch)
tree5eca06d1133b1615b7c6e667ba7c42f7e97548b3 /lib/modules.nix
parentbb9a37a2a56249483cd98ef09c254b78e736af1a (diff)
downloadnixpkgs-d88721e4408988202a0ae3cea3f5551ebfa13168.tar
nixpkgs-d88721e4408988202a0ae3cea3f5551ebfa13168.tar.gz
nixpkgs-d88721e4408988202a0ae3cea3f5551ebfa13168.tar.bz2
nixpkgs-d88721e4408988202a0ae3cea3f5551ebfa13168.tar.lz
nixpkgs-d88721e4408988202a0ae3cea3f5551ebfa13168.tar.xz
nixpkgs-d88721e4408988202a0ae3cea3f5551ebfa13168.tar.zst
nixpkgs-d88721e4408988202a0ae3cea3f5551ebfa13168.zip
modules: add support for module replacement with disabledModules
This is based on a prototype Nicolas B. Pierron worked on during a
discussion we had at FOSDEM.

A new version with a workaround for problems of the reverted original.
Discussion: https://github.com/NixOS/nixpkgs/commit/3f2566689
Diffstat (limited to 'lib/modules.nix')
-rw-r--r--lib/modules.nix24
1 files changed, 17 insertions, 7 deletions
diff --git a/lib/modules.nix b/lib/modules.nix
index 4eee41306cd..a7c397d2cf4 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -20,7 +20,8 @@ rec {
                 , prefix ? []
                 , # This should only be used for special arguments that need to be evaluated
                   # when resolving module structure (like in imports). For everything else,
-                  # there's _module.args.
+                  # there's _module.args. If specialArgs.modulesPath is defined it will be
+                  # used as the base path for disabledModules.
                   specialArgs ? {}
                 , # This would be remove in the future, Prefer _module.args option instead.
                   args ? {}
@@ -58,10 +59,7 @@ rec {
 
       closed = closeModules (modules ++ [ internalModule ]) ({ inherit config options; lib = import ./.; } // specialArgs);
 
-      # 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);
+      options = mergeModules prefix (reverseList (filterModules (specialArgs.modulesPath or "") closed));
 
       # Traverse options and extract the option values into the final
       # config set.  At the same time, check whether all option
@@ -87,6 +85,16 @@ rec {
       result = { inherit options config; };
     in result;
 
+
+ # Filter disabled modules. Modules can be disabled allowing
+ # their implementation to be replaced.
+ filterModules = modulesPath: modules:
+   let
+     moduleKey = m: if isString m then toString modulesPath + "/" + m else toString m;
+     disabledKeys = map moduleKey (concatMap (m: m.disabledModules) modules);
+   in
+     filter (m: !(elem m.key disabledKeys)) modules;
+
   /* Close a set of modules under the ‘imports’ relation. */
   closeModules = modules: args:
     let
@@ -111,12 +119,13 @@ rec {
       else {};
     in
     if m ? config || m ? options then
-      let badAttrs = removeAttrs m ["imports" "options" "config" "key" "_file" "meta"]; in
+      let badAttrs = removeAttrs m ["_file" "key" "disabledModules" "imports" "options" "config" "meta"]; in
       if badAttrs != {} then
         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;
+          disabledModules = m.disabledModules or [];
           imports = m.imports or [];
           options = m.options or {};
           config = mkMerge [ (m.config or {}) metaSet ];
@@ -124,9 +133,10 @@ rec {
     else
       { file = m._file or file;
         key = toString m.key or key;
+        disabledModules = m.disabledModules or [];
         imports = m.require or [] ++ m.imports or [];
         options = {};
-        config = mkMerge [ (removeAttrs m ["key" "_file" "require" "imports"]) metaSet ];
+        config = mkMerge [ (removeAttrs m ["_file" "key" "disabledModules" "require" "imports"]) metaSet ];
       };
 
   applyIfFunction = key: f: args@{ config, options, lib, ... }: if isFunction f then