submoduleWith
lib.types.submoduleWith
Docs pulled from | This Revision | 15 minutes ago
Contribute
Enhance the ecosystem with your expertise! Contribute to fill the gaps in documentation. Your input can make a difference.
Noogle detected
Implementation
The following is the current implementation of this function.
{
modules,
specialArgs ? { },
shorthandOnlyDefinesConfig ? false,
description ? null,
class ? null,
}@attrs:
let
inherit (lib.modules) evalModules;
allModules =
defs:
map (
{ value, file }:
if isAttrs value && shorthandOnlyDefinesConfig then
{
_file = file;
config = value;
}
else
{
_file = file;
imports = [ value ];
}
) defs;
base = evalModules {
inherit class specialArgs;
modules = [
{
# This is a work-around for the fact that some sub-modules,
# such as the one included in an attribute set, expects an "args"
# attribute to be given to the sub-module. As the option
# evaluation does not have any specific attribute name yet, we
# provide a default for the documentation and the freeform type.
#
# This is necessary as some option declaration might use the
# "name" attribute given as argument of the submodule and use it
# as the default of option declarations.
#
# We use lookalike unicode single angle quotation marks because
# of the docbook transformation the options receive. In all uses
# > and < wouldn't be encoded correctly so the encoded values
# would be used, and use of `<` and `>` would break the XML document.
# It shouldn't cause an issue since this is cosmetic for the manual.
_module.args.name = lib.mkOptionDefault "‹name›";
}
]
++ modules;
};
freeformType = base._module.freeformType;
name = "submodule";
check = {
__functor = _self: x: isAttrs x || isFunction x || path.check x;
isV2MergeCoherent = true;
};
in
mkOptionType {
inherit name;
description =
if description != null then
description
else
let
docsEval = base.extendModules { modules = [ noCheckForDocsModule ]; };
in
if docsEval._module.freeformType ? description then
"open ${name} of ${
optionDescriptionPhrase (
class: class == "noun" || class == "composite"
) docsEval._module.freeformType
}"
else
name;
inherit check;
merge = {
__functor =
self: loc: defs:
(self.v2 { inherit loc defs; }).value;
v2 =
{ loc, defs }:
let
configuration = base.extendModules {
modules = [ { _module.args.name = last loc; } ] ++ allModules defs;
prefix = loc;
};
in
{
headError = checkDefsForError check loc defs;
value = configuration.config;
valueMeta = { inherit configuration; };
};
};
emptyValue = {
value = base.config;
};
getSubOptions =
prefix:
let
docsEval = (
base.extendModules {
inherit prefix;
modules = [ noCheckForDocsModule ];
}
);
# Intentionally shadow the freeformType from the possibly *checked*
# configuration. See `noCheckForDocsModule` comment.
inherit (docsEval._module) freeformType;
in
docsEval.options
// optionalAttrs (freeformType != null) {
# Expose the sub options of the freeform type. Note that the option
# discovery doesn't care about the attribute name used here, so this
# is just to avoid conflicts with potential options from the submodule
_freeformOptions = freeformType.getSubOptions prefix;
};
getSubModules = modules;
substSubModules =
m:
submoduleWith (
attrs
// {
modules = m;
}
);
nestedTypes = lib.optionalAttrs (freeformType != null) {
freeformType = freeformType;
};
functor = defaultFunctor name // {
type = lib.types.submoduleWith;
payload = {
inherit
modules
class
specialArgs
shorthandOnlyDefinesConfig
description
;
};
binOp = lhs: rhs: {
class =
# `or null` was added for backwards compatibility only. `class` is
# always set in the current version of the module system.
if lhs.class or null == null then
rhs.class or null
else if rhs.class or null == null then
lhs.class or null
else if lhs.class or null == rhs.class then
lhs.class or null
else
throw "A submoduleWith option is declared multiple times with conflicting class values \"${toString lhs.class}\" and \"${toString rhs.class}\".";
modules = lhs.modules ++ rhs.modules;
specialArgs =
let
intersecting = builtins.intersectAttrs lhs.specialArgs rhs.specialArgs;
in
if intersecting == { } then
lhs.specialArgs // rhs.specialArgs
else
throw "A submoduleWith option is declared multiple times with the same specialArgs \"${toString (attrNames intersecting)}\"";
shorthandOnlyDefinesConfig =
if lhs.shorthandOnlyDefinesConfig == null then
rhs.shorthandOnlyDefinesConfig
else if rhs.shorthandOnlyDefinesConfig == null then
lhs.shorthandOnlyDefinesConfig
else if lhs.shorthandOnlyDefinesConfig == rhs.shorthandOnlyDefinesConfig then
lhs.shorthandOnlyDefinesConfig
else
throw "A submoduleWith option is declared multiple times with conflicting shorthandOnlyDefinesConfig values";
description =
if lhs.description == null then
rhs.description
else if rhs.description == null then
lhs.description
else if lhs.description == rhs.description then
lhs.description
else
throw "A submoduleWith option is declared multiple times with conflicting descriptions";
};
};
}