mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-07-06 17:13:24 -05:00
lib.modules: submodule emptyValue must evaluate sub-option defaults
`emptyValue` for `types.submodule` was `{ value = { }; }`, i.e. none
of the type-declared options or their defaults.
Previously submodules without defs would simply fail for lack of a default,
but since PR #500104 repurposed `emptyValue` as the fallback when no
definitions exist, submodule options without an explicit `default = { }`
(new additions) silently lost their sub-option defaults
(e.g. `requiredFeatures.devnet` in the nixos-test-driver, #511413).
Main change: `emptyValue`: `{ }` -> `{ value = base.config; }`
Additionally, skip `emptyValue`-based default rendering in docs for
types with submodules, because their sub-options are already documented
individually, and forcing evaluation here can break on modules with
invalid or incomplete definitions.
This commit is contained in:
parent
d24dbb1951
commit
77b5864637
4 changed files with 37 additions and 3 deletions
|
|
@ -590,7 +590,16 @@ rec {
|
|||
);
|
||||
}
|
||||
//
|
||||
optionalAttrs (opt ? defaultText || opt ? default || ((opt.type or { }).emptyValue or { }) ? value)
|
||||
optionalAttrs
|
||||
(
|
||||
opt ? defaultText
|
||||
|| opt ? default
|
||||
# Render emptyValue-based defaults, but only for types without
|
||||
# submodules (e.g. types.submodule). Submodules may evaluate to
|
||||
# error without user defs, and their sub-options are documented
|
||||
# individually, so best to skip those here.
|
||||
|| ((opt.type or { }).emptyValue or { }) ? value && (opt.type or { }).getSubModules or null == null
|
||||
)
|
||||
{
|
||||
default =
|
||||
builtins.addErrorContext
|
||||
|
|
|
|||
|
|
@ -686,6 +686,8 @@ checkConfigOutput "\[\]" config.unique ./defaults.nix
|
|||
checkConfigOutput "\[\]" config.coercedTo ./defaults.nix
|
||||
# These types don't have empty values
|
||||
checkConfigError 'The option .int. was accessed but has no value defined. Try setting the option.' config.int ./defaults.nix
|
||||
## submodule emptyValue must evaluate sub-option defaults
|
||||
checkConfigOutput "ok" config.result ./defaults.nix
|
||||
|
||||
# types.unique
|
||||
# requires a single definition
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ lib, ... }:
|
||||
{ lib, config, ... }:
|
||||
let
|
||||
inherit (lib) types;
|
||||
in
|
||||
|
|
@ -19,6 +19,18 @@ in
|
|||
submodule = lib.mkOption {
|
||||
type = types.submodule { };
|
||||
};
|
||||
submoduleWithDefaults = lib.mkOption {
|
||||
type = types.submodule {
|
||||
options.enabled = lib.mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
options.count = lib.mkOption {
|
||||
type = types.int;
|
||||
default = 13;
|
||||
};
|
||||
};
|
||||
};
|
||||
unique = lib.mkOption {
|
||||
type = types.unique { message = "hi"; } (types.listOf types.int);
|
||||
};
|
||||
|
|
@ -29,5 +41,16 @@ in
|
|||
int = lib.mkOption {
|
||||
type = types.int;
|
||||
};
|
||||
|
||||
result = lib.mkOption {
|
||||
type = types.str;
|
||||
default =
|
||||
assert
|
||||
config.submoduleWithDefaults == {
|
||||
enabled = true;
|
||||
count = 13;
|
||||
};
|
||||
"ok";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1320,7 +1320,7 @@ rec {
|
|||
};
|
||||
};
|
||||
emptyValue = {
|
||||
value = { };
|
||||
value = base.config;
|
||||
};
|
||||
getSubOptions =
|
||||
prefix:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue