summaryrefslogtreecommitdiffstats
path: root/lib/modules.nix
diff options
context:
space:
mode:
authorSilvan Mosberger <contact@infinisil.com>2020-01-09 18:20:12 +0100
committerGitHub <noreply@github.com>2020-01-09 18:20:12 +0100
commite9c16ec186b2fc4be93f9dd2be5afaef76cdc6f8 (patch)
tree6843c9cf711a97041ba6c964e7a8528e1ae0cae0 /lib/modules.nix
parent4052aa377e4b1f50ee3f7b147177d1f1d966cf1b (diff)
parenta6462a4a8b9d55586f8706484c155b2de2a34877 (diff)
Merge pull request #76857 from Infinisil/recursive-disableModules
Apply `disabledModules` recursively
Diffstat (limited to 'lib/modules.nix')
-rw-r--r--lib/modules.nix98
1 files changed, 73 insertions, 25 deletions
diff --git a/lib/modules.nix b/lib/modules.nix
index aebc9874aa46..38d6ac8cd916 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -59,9 +59,12 @@ rec {
};
};
- closed = closeModules (modules ++ [ internalModule ]) ({ inherit config options lib; } // specialArgs);
+ collected = collectModules
+ (specialArgs.modulesPath or "")
+ (modules ++ [ internalModule ])
+ ({ inherit config options lib; } // specialArgs);
- options = mergeModules prefix (reverseList (filterModules (specialArgs.modulesPath or "") closed));
+ options = mergeModules prefix (reverseList collected);
# Traverse options and extract the option values into the final
# config set. At the same time, check whether all option
@@ -87,31 +90,76 @@ rec {
result = { inherit options config; };
in result;
+ # collectModules :: (modulesPath: String) -> (modules: [ Module ]) -> (args: Attrs) -> [ Module ]
+ #
+ # Collects all modules recursively through `import` statements, filtering out
+ # all modules in disabledModules.
+ collectModules = let
- # 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;
+ # Like unifyModuleSyntax, but also imports paths and calls functions if necessary
+ loadModule = args: fallbackFile: fallbackKey: m:
+ if isFunction m || isAttrs m then
+ unifyModuleSyntax fallbackFile fallbackKey (applyIfFunction fallbackKey m args)
+ else unifyModuleSyntax (toString m) (toString m) (applyIfFunction (toString m) (import m) args);
- /* Close a set of modules under the ‘imports’ relation. */
- closeModules = modules: args:
- let
- toClosureList = file: parentKey: imap1 (n: x:
- if isAttrs x || isFunction x then
- let key = "${parentKey}:anon-${toString n}"; in
- unifyModuleSyntax file key (applyIfFunction key x args)
- else
- let file = toString x; key = toString x; in
- unifyModuleSyntax file key (applyIfFunction key (import x) args));
- in
- builtins.genericClosure {
- startSet = toClosureList unknownModule "" modules;
- operator = m: toClosureList m._file m.key m.imports;
- };
+ /*
+ Collects all modules recursively into the form
+
+ {
+ disabled = [ <list of disabled modules> ];
+ # All modules of the main module list
+ modules = [
+ {
+ key = <key1>;
+ module = <module for key1>;
+ # All modules imported by the module for key1
+ modules = [
+ {
+ key = <key1-1>;
+ module = <module for key1-1>;
+ # All modules imported by the module for key1-1
+ modules = [ ... ];
+ }
+ ...
+ ];
+ }
+ ...
+ ];
+ }
+ */
+ collectStructuredModules =
+ let
+ collectResults = modules: {
+ disabled = concatLists (catAttrs "disabled" modules);
+ inherit modules;
+ };
+ in parentFile: parentKey: initialModules: args: collectResults (imap1 (n: x:
+ let
+ module = loadModule args parentFile "${parentKey}:anon-${toString n}" x;
+ collectedImports = collectStructuredModules module._file module.key module.imports args;
+ in {
+ key = module.key;
+ module = module;
+ modules = collectedImports.modules;
+ disabled = module.disabledModules ++ collectedImports.disabled;
+ }) initialModules);
+
+ # filterModules :: String -> { disabled, modules } -> [ Module ]
+ #
+ # Filters a structure as emitted by collectStructuredModules by removing all disabled
+ # modules recursively. It returns the final list of unique-by-key modules
+ filterModules = modulesPath: { disabled, modules }:
+ let
+ moduleKey = m: if isString m then toString modulesPath + "/" + m else toString m;
+ disabledKeys = listToAttrs (map (k: nameValuePair (moduleKey k) null) disabled);
+ keyFilter = filter (attrs: ! disabledKeys ? ${attrs.key});
+ in map (attrs: attrs.module) (builtins.genericClosure {
+ startSet = keyFilter modules;
+ operator = attrs: keyFilter attrs.modules;
+ });
+
+ in modulesPath: initialModules: args:
+ filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args);
/* Massage a module into canonical form, that is, a set consisting
of ‘options’, ‘config’ and ‘imports’ attributes. */