mergeOptionDecls
lib.mergeOptionDecls
Docs pulled from | This Revision | 10 minutes ago
Merge multiple option declarations into a single declaration. In general, there should be only one declaration of each option. The exception is the ‘options’ attribute, which specifies sub-options. These can be specified multiple times to allow one module to add sub-options to an option declared somewhere else (e.g. multiple modules define sub-options for ‘fileSystems’).
'loc' is the list of attribute names where the option is located.
'opts' is a list of modules. Each module has an options attribute which correspond to the definition of 'loc' in 'opt.file'.
Inputs
loc
-
1. Function argument
opts
-
2. Function argument
Noogle detected
Implementation
The following is the current implementation of this function.
mergeOptionDecls =
loc: opts:
foldl'
(
res: opt:
let
t = res.type;
t' = opt.options.type;
mergedType = t.typeMerge t'.functor;
typesMergeable = mergedType != null;
# TODO: Remove this when all downstream reliances of internals: 'functor.wrapped' are sufficiently migrated.
# A function that adds the deprecated wrapped message to a type.
addDeprecatedWrapped =
t:
t
// {
functor = t.functor // {
wrapped = t.functor.wrappedDeprecationMessage {
inherit loc;
};
};
};
typeSet =
if opt.options ? type then
if res ? type then
if typesMergeable then
{
type =
if mergedType ? functor.wrappedDeprecationMessage then
addDeprecatedWrapped mergedType
else
mergedType;
}
else
# Keep in sync with the same error below!
throw
"The option `${showOption loc}' in `${opt._file}' is already declared in ${showFiles res.declarations}."
else if opt.options.type ? functor.wrappedDeprecationMessage then
{ type = addDeprecatedWrapped opt.options.type; }
else
{ }
else
{ };
bothHave = k: opt.options ? ${k} && res ? ${k};
in
if bothHave "default" || bothHave "example" || bothHave "description" || bothHave "apply" then
# Keep in sync with the same error above!
throw
"The option `${showOption loc}' in `${opt._file}' is already declared in ${showFiles res.declarations}."
else
let
getSubModules = opt.options.type.getSubModules or null;
submodules =
if getSubModules != null then
map (setDefaultModuleLocation opt._file) getSubModules ++ res.options
else
res.options;
in
opt.options
// res
// {
declarations = res.declarations ++ [ opt._file ];
# In the case of modules that are generated dynamically, we won't
# have exact declaration lines; fall back to just the file being
# evaluated.
declarationPositions =
res.declarationPositions
++ (
if opt.pos != null then
[ opt.pos ]
else
[
{
file = opt._file;
line = null;
column = null;
}
]
);
options = submodules;
}
// typeSet
)
{
inherit loc;
declarations = [ ];
declarationPositions = [ ];
options = [ ];
}
opts;