···
toClosureList = file: parentKey: imap (n: x:
if isAttrs x || isFunction x then
90
-
unifyModuleSyntax file "${parentKey}:anon-${toString n}" (applyIfFunction x args)
90
+
unifyModuleSyntax file "${parentKey}:anon-${toString n}" (unpackSubmodule applyIfFunction x args)
unifyModuleSyntax (toString x) (toString x) (applyIfFunction (import x) args));
···
applyIfFunction = f: arg@{ config, options, lib }: if isFunction f then
123
+
# Module arguments are resolved in a strict manner when attribute set
124
+
# deconstruction is used. As the arguments are now defined with the
125
+
# config.__interanl.args option, the strictness used on the attribute
126
+
# set argument would cause an infinite loop, if the result of the
127
+
# option is given as argument.
129
+
# To work-around the strictness issue on the deconstruction of the
130
+
# attributes set argument, we create a new attribute set which is
131
+
# constructed to satisfy the expected set of attributes. Thus calling
132
+
# a module will resolve strictly the attributes used as argument but
133
+
# not their values. The values are forwarding the result of the
134
+
# evaluation of the option.
requiredArgs = builtins.attrNames (builtins.functionArgs f);
extraArgs = builtins.listToAttrs (map (name: {
···
144
+
/* We have to pack and unpack submodules. We cannot wrap the expected
145
+
result of the function as we would no longer be able to list the arguments
146
+
of the submodule. (see applyIfFunction) */
147
+
unpackSubmodule = unpack: m: args:
148
+
if isType "submodule" m then
149
+
{ _file = m.file; } // (unpack m.submodule args)
150
+
else unpack m args;
152
+
packSubmodule = file: m:
153
+
{ _type = "submodule"; file = file; submodule = m; };
/* Merge a list of modules. This will recurse over the option
declarations in all modules, combining them into a single set.
···
current option declaration as the file use for the submodule. If the
submodule defines any filename, then we ignore the enclosing option file. */
options' = toList opt.options.options;
210
-
if isFunction m then args: { _file = opt.file; } // (m args)
211
-
else { _file = opt.file; } // m;
coerceOption = file: opt:
213
-
if isFunction opt then args: { _file = file; } // (opt args)
214
-
else { _file = file; options = opt; };
233
+
if isFunction opt then packSubmodule file opt
234
+
else packSubmodule file { options = opt; };
getSubModules = opt.options.type.getSubModules or null;
217
-
if getSubModules != null then map addModuleFile getSubModules ++ res.options
237
+
if getSubModules != null then map (packSubmodule opt.file) getSubModules ++ res.options
else if opt.options ? options then map (coerceOption opt.file) options' ++ res.options