Files
nixpkgs/lib/tests/modules/defaults.nix
Robert Hensing 77b5864637 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.
2026-04-19 20:52:33 +01:00

57 lines
1.2 KiB
Nix

{ lib, config, ... }:
let
inherit (lib) types;
in
{
options = {
list = lib.mkOption {
type = types.listOf types.int;
};
attrs = lib.mkOption {
type = types.attrs;
};
attrsOf = lib.mkOption {
type = types.attrsOf types.int;
};
null = lib.mkOption {
type = types.nullOr types.int;
};
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);
};
coercedTo = lib.mkOption {
type = types.coercedTo (types.attrsOf types.int) builtins.attrNames (types.listOf types.str);
};
# no empty value
int = lib.mkOption {
type = types.int;
};
result = lib.mkOption {
type = types.str;
default =
assert
config.submoduleWithDefaults == {
enabled = true;
count = 13;
};
"ok";
};
};
}