lib.types: Add deferredModuleWith

+25 -3
+3 -1
lib/modules.nix
··· 467 467 disabledModules = m.disabledModules or []; 468 468 imports = m.require or [] ++ m.imports or []; 469 469 options = {}; 470 - config = addFreeformType (addMeta (removeAttrs m ["_file" "key" "disabledModules" "require" "imports" "freeformType"])); 470 + config = 471 + lib.throwIfNot (isAttrs m) "module ${file} (${key}) does not look like a module." 472 + addFreeformType (addMeta (removeAttrs m ["_file" "key" "disabledModules" "require" "imports" "freeformType"])); 471 473 }; 472 474 473 475 applyModuleArgsIfFunction = key: f: args@{ config, options, lib, ... }: if isFunction f then
+22 -2
lib/types.nix
··· 540 540 }; 541 541 542 542 # A module to be imported in some other part of the configuration. 543 - deferredModule = mkOptionType { 543 + deferredModule = deferredModuleWith { }; 544 + 545 + # A module to be imported in some other part of the configuration. 546 + # `staticModules`' options will be added to the documentation, unlike 547 + # options declared via `config`. 548 + deferredModuleWith = attrs@{ staticModules ? [] }: mkOptionType { 544 549 name = "deferredModule"; 545 550 description = "module"; 546 551 check = x: isAttrs x || isFunction x || path.check x; 547 - merge = loc: defs: map (def: lib.setDefaultModuleLocation "${def.file}, via option ${showOption loc}" def.value) defs; 552 + merge = loc: defs: staticModules ++ map (def: lib.setDefaultModuleLocation "${def.file}, via option ${showOption loc}" def.value) defs; 553 + inherit (submoduleWith { modules = staticModules; }) 554 + getSubOptions 555 + getSubModules; 556 + substSubModules = m: deferredModuleWith (attrs // { 557 + staticModules = m; 558 + }); 559 + functor = defaultFunctor "deferredModuleWith" // { 560 + type = types.deferredModuleWith; 561 + payload = { 562 + inherit staticModules; 563 + }; 564 + binOp = lhs: rhs: { 565 + staticModules = lhs.staticModules ++ rhs.staticModules; 566 + }; 567 + }; 548 568 }; 549 569 550 570 # The type of a type!