mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-05 21:03:40 +00:00
lib.modules: default to emptyValue (#500104)
This commit is contained in:
@@ -1246,6 +1246,8 @@ let
|
||||
allInvalid = filter (def: !type.check def.value) defsFinal;
|
||||
in
|
||||
throw "A definition for option `${showOption loc}' is not of type `${type.description}'. Definition values:${showDefs allInvalid}"
|
||||
else if type.emptyValue ? value then
|
||||
type.emptyValue.value
|
||||
else
|
||||
# (nixos-option detects this specific error message and gives it special
|
||||
# handling. If changed here, please change it there too.)
|
||||
|
||||
@@ -589,11 +589,16 @@ rec {
|
||||
renderOptionValue opt.example
|
||||
);
|
||||
}
|
||||
// optionalAttrs (opt ? defaultText || opt ? default) {
|
||||
default = builtins.addErrorContext "while evaluating the ${
|
||||
if opt ? defaultText then "defaultText" else "default value"
|
||||
} of option `${name}`" (renderOptionValue (opt.defaultText or opt.default));
|
||||
}
|
||||
//
|
||||
optionalAttrs (opt ? defaultText || opt ? default || ((opt.type or { }).emptyValue or { }) ? value)
|
||||
{
|
||||
default =
|
||||
builtins.addErrorContext
|
||||
"while evaluating the ${
|
||||
if opt ? defaultText then "defaultText" else "default value"
|
||||
} of option `${name}`"
|
||||
(renderOptionValue (opt.defaultText or opt.default or opt.type.emptyValue.value));
|
||||
}
|
||||
// optionalAttrs (opt ? relatedPackages && opt.relatedPackages != null) {
|
||||
inherit (opt) relatedPackages;
|
||||
};
|
||||
|
||||
@@ -3393,6 +3393,44 @@ runTests {
|
||||
];
|
||||
};
|
||||
|
||||
testEmptyValueOption = {
|
||||
expr =
|
||||
let
|
||||
module =
|
||||
{ lib, ... }:
|
||||
{
|
||||
options = {
|
||||
"empty-value" = lib.mkOption {
|
||||
type = lib.mkOptionType {
|
||||
name = "propagate-empty-value-to-default";
|
||||
emptyValue.value = 2;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
eval = evalModules {
|
||||
modules = [ module ];
|
||||
};
|
||||
in
|
||||
filter (o: o.name == "empty-value") (optionAttrSetToDocList eval.options);
|
||||
expected = [
|
||||
{
|
||||
declarations = [ ];
|
||||
default = {
|
||||
_type = "literalExpression";
|
||||
text = "2";
|
||||
};
|
||||
description = null;
|
||||
internal = false;
|
||||
loc = [ "empty-value" ];
|
||||
name = "empty-value";
|
||||
readOnly = false;
|
||||
type = "propagate-empty-value-to-default";
|
||||
visible = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
testDocOptionVisiblity = {
|
||||
expr =
|
||||
let
|
||||
|
||||
@@ -674,6 +674,17 @@ checkConfigOutput "{}" config.submodule.a ./emptyValues.nix
|
||||
checkConfigError 'The option .int.a. was accessed but has no value defined. Try setting the option.' config.int.a ./emptyValues.nix
|
||||
checkConfigError 'The option .nonEmptyList.a. was accessed but has no value defined. Try setting the option.' config.nonEmptyList.a ./emptyValues.nix
|
||||
|
||||
## defaults
|
||||
checkConfigOutput "\[\]" config.list ./defaults.nix
|
||||
checkConfigOutput "{}" config.attrs ./defaults.nix
|
||||
checkConfigOutput "{}" config.attrsOf ./defaults.nix
|
||||
checkConfigOutput "null" config.null ./defaults.nix
|
||||
checkConfigOutput "{}" config.submodule ./defaults.nix
|
||||
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
|
||||
|
||||
# types.unique
|
||||
# requires a single definition
|
||||
checkConfigError 'The option .examples\.merged. is defined multiple times while it.s expected to be unique' config.examples.merged.a ./types-unique.nix
|
||||
|
||||
33
lib/tests/modules/defaults.nix
Normal file
33
lib/tests/modules/defaults.nix
Normal file
@@ -0,0 +1,33 @@
|
||||
{ lib, ... }:
|
||||
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 { };
|
||||
};
|
||||
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;
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user