aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/lib/types.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/lib/types.nix')
-rw-r--r--nixpkgs/lib/types.nix141
1 files changed, 29 insertions, 112 deletions
diff --git a/nixpkgs/lib/types.nix b/nixpkgs/lib/types.nix
index 6fd6de7e1fd..ef2c78082f8 100644
--- a/nixpkgs/lib/types.nix
+++ b/nixpkgs/lib/types.nix
@@ -91,9 +91,12 @@ rec {
# combinable with the binOp binary operation.
# binOp: binary operation that merge two payloads of the same type.
functor ? defaultFunctor name
+ , # The deprecation message to display when this type is used by an option
+ # If null, the type isn't deprecated
+ deprecationMessage ? null
}:
{ _type = "option-type";
- inherit name check merge emptyValue getSubOptions getSubModules substSubModules typeMerge functor;
+ inherit name check merge emptyValue getSubOptions getSubModules substSubModules typeMerge functor deprecationMessage;
description = if description == null then name else description;
};
@@ -222,8 +225,10 @@ rec {
# Deprecated; should not be used because it quietly concatenates
# strings, which is usually not what you want.
- string = warn "types.string is deprecated because it quietly concatenates strings"
- (separatedString "");
+ string = separatedString "" // {
+ name = "string";
+ deprecationMessage = "See https://github.com/NixOS/nixpkgs/pull/66346 for better alternative types.";
+ };
attrs = mkOptionType {
name = "attrs";
@@ -252,9 +257,6 @@ rec {
merge = mergeEqualOption;
};
- # drop this in the future:
- list = builtins.trace "`types.list` is deprecated; use `types.listOf` instead" types.listOf;
-
listOf = elemType: mkOptionType rec {
name = "listOf";
description = "list of ${elemType.description}s";
@@ -326,110 +328,13 @@ rec {
functor = (defaultFunctor name) // { wrapped = elemType; };
};
- # List or attribute set of ...
- loaOf = elemType:
- let
- convertAllLists = loc: defs:
- let
- padWidth = stringLength (toString (length defs));
- unnamedPrefix = i: "unnamed-" + fixedWidthNumber padWidth i + ".";
- in
- imap1 (i: convertIfList loc (unnamedPrefix i)) defs;
- convertIfList = loc: unnamedPrefix: def:
- if isList def.value then
- let
- padWidth = stringLength (toString (length def.value));
- unnamed = i: unnamedPrefix + fixedWidthNumber padWidth i;
- anyString = placeholder "name";
- nameAttrs = [
- { path = [ "environment" "etc" ];
- name = "target";
- }
- { path = [ "containers" anyString "bindMounts" ];
- name = "mountPoint";
- }
- { path = [ "programs" "ssh" "knownHosts" ];
- # hostNames is actually a list so we would need to handle it only when singleton
- name = "hostNames";
- }
- { path = [ "fileSystems" ];
- name = "mountPoint";
- }
- { path = [ "boot" "specialFileSystems" ];
- name = "mountPoint";
- }
- { path = [ "services" "znapzend" "zetup" ];
- name = "dataset";
- }
- { path = [ "services" "znapzend" "zetup" anyString "destinations" ];
- name = "label";
- }
- { path = [ "services" "geoclue2" "appConfig" ];
- name = "desktopID";
- }
- ];
- matched = let
- equals = a: b: b == anyString || a == b;
- fallback = { name = "name"; };
- in findFirst ({ path, ... }: all (v: v == true) (zipListsWith equals loc path)) fallback nameAttrs;
- nameAttr = matched.name;
- nameValueOld = value:
- if isList value then
- if length value > 0 then
- "[ " + concatMapStringsSep " " escapeNixString value + " ]"
- else
- "[ ]"
- else
- escapeNixString value;
- nameValueNew = value: unnamed:
- if isList value then
- if length value > 0 then
- head value
- else
- unnamed
- else
- value;
- res =
- { inherit (def) file;
- value = listToAttrs (
- imap1 (elemIdx: elem:
- { name = nameValueNew (elem.${nameAttr} or (unnamed elemIdx)) (unnamed elemIdx);
- value = elem;
- }) def.value);
- };
- option = concatStringsSep "." loc;
- sample = take 3 def.value;
- more = lib.optionalString (length def.value > 3) "... ";
- list = concatMapStrings (x: ''{ ${nameAttr} = ${nameValueOld (x.${nameAttr} or "unnamed")}; ...} '') sample;
- set = concatMapStrings (x: ''${nameValueNew (x.${nameAttr} or "unnamed") "unnamed"} = {...}; '') sample;
- msg = ''
- In file ${def.file}
- a list is being assigned to the option config.${option}.
- This will soon be an error as type loaOf is deprecated.
- See https://github.com/NixOS/nixpkgs/pull/63103 for more information.
- Do
- ${option} =
- { ${set}${more}}
- instead of
- ${option} =
- [ ${list}${more}]
- '';
- in
- lib.warn msg res
- else
- def;
- attrOnly = attrsOf elemType;
- in mkOptionType rec {
- name = "loaOf";
- description = "list or attribute set of ${elemType.description}s";
- check = x: isList x || isAttrs x;
- merge = loc: defs: attrOnly.merge loc (convertAllLists loc defs);
- emptyValue = { value = {}; };
- getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name?>"]);
- getSubModules = elemType.getSubModules;
- substSubModules = m: loaOf (elemType.substSubModules m);
- functor = (defaultFunctor name) // { wrapped = elemType; };
- };
+ # TODO: drop this in the future:
+ loaOf = elemType: types.attrsOf elemType // {
+ name = "loaOf";
+ deprecationMessage = "Mixing lists with attribute values is no longer"
+ + " possible; please use `types.attrsOf` instead. See"
+ + " https://github.com/NixOS/nixpkgs/issues/1800 for the motivation.";
+ };
# Value of given type but with no merging (i.e. `uniq list`s are not concatenated).
uniq = elemType: mkOptionType rec {
@@ -486,9 +391,15 @@ rec {
else value
) defs;
+ freeformType = (evalModules {
+ inherit modules specialArgs;
+ args.name = "ā€¹nameā€ŗ";
+ })._module.freeformType;
+
in
mkOptionType rec {
name = "submodule";
+ description = freeformType.description or name;
check = x: isAttrs x || isFunction x || path.check x;
merge = loc: defs:
(evalModules {
@@ -516,7 +427,12 @@ rec {
# 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.
args.name = "ā€¹nameā€ŗ";
- }).options;
+ }).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;
@@ -618,8 +534,9 @@ rec {
# declarations from the ā€˜optionsā€™ attribute of containing option
# declaration.
optionSet = mkOptionType {
- name = builtins.trace "types.optionSet is deprecated; use types.submodule instead" "optionSet";
+ name = "optionSet";
description = "option set";
+ deprecationMessage = "Use `types.submodule' instead";
};
# Augment the given type with an additional type check function.
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };