diff --git a/lib/modules.nix b/lib/modules.nix index 2ec34699809..decb96ffe11 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -613,7 +613,6 @@ rec { if tp.name == "option set" || tp.name == "submodule" then throw "The option ${showOption loc} uses submodules without a wrapping type, in ${showFiles opt.declarations}." else if optionSetIn "attrsOf" then types.attrsOf (types.submodule options) - else if optionSetIn "loaOf" then types.loaOf (types.submodule options) else if optionSetIn "listOf" then types.listOf (types.submodule options) else if optionSetIn "nullOr" then types.nullOr (types.submodule options) else tp; diff --git a/lib/types.nix b/lib/types.nix index 1845b6ae339..17e7a939fe3 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -252,8 +252,8 @@ rec { merge = mergeEqualOption; }; - # drop this in the future: - list = builtins.trace "`types.list` is deprecated; use `types.listOf` instead" types.listOf; + # TODO: drop this in the future: + list = builtins.trace "`types.list` has been removed; please use `types.listOf` instead" types.listOf; listOf = elemType: mkOptionType rec { name = "listOf"; @@ -326,110 +326,15 @@ 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 ++ [""]); - getSubModules = elemType.getSubModules; - substSubModules = m: loaOf (elemType.substSubModules m); - functor = (defaultFunctor name) // { wrapped = elemType; }; - }; + # TODO: drop this in the future: + loaOf = + let msg = + '' + `types.loaOf` has been removed and 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. + ''; + in builtins.trace msg types.attrsOf; # Value of given type but with no merging (i.e. `uniq list`s are not concatenated). uniq = elemType: mkOptionType rec { diff --git a/nixos/doc/manual/development/option-types.xml b/nixos/doc/manual/development/option-types.xml index 957349ad181..5a6dae6e991 100644 --- a/nixos/doc/manual/development/option-types.xml +++ b/nixos/doc/manual/development/option-types.xml @@ -385,17 +385,6 @@ - - - types.loaOf t - - - - An attribute set or a list of t type. Multiple - definitions are merged according to the value. - - - types.nullOr t diff --git a/nixos/doc/manual/release-notes/rl-2009.xml b/nixos/doc/manual/release-notes/rl-2009.xml index 83bc2f82bbf..bf96fb21a41 100644 --- a/nixos/doc/manual/release-notes/rl-2009.xml +++ b/nixos/doc/manual/release-notes/rl-2009.xml @@ -743,6 +743,18 @@ CREATE ROLE postgres LOGIN SUPERUSER; See the PR that changed this for more info. + + + For NixOS configuration options, the type loaOf, after + its initial deprecation in release 20.03, has been removed. In NixOS and + Nixpkgs options using this type have been converted to attrsOf. + + + For more information on this change have look at these links: + issue #1800, + PR #63103. + + diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix index 56b7af98b61..0ab303d0ae4 100644 --- a/nixos/modules/config/users-groups.nix +++ b/nixos/modules/config/users-groups.nix @@ -463,7 +463,7 @@ in { users.users = mkOption { default = {}; - type = with types; loaOf (submodule userOpts); + type = with types; attrsOf (submodule userOpts); example = { alice = { uid = 1234; @@ -487,7 +487,7 @@ in { { students.gid = 1001; hackers = { }; }; - type = with types; loaOf (submodule groupOpts); + type = with types; attrsOf (submodule groupOpts); description = '' Additional groups to be created automatically by the system. ''; diff --git a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix index 79c835dc390..87545e84203 100644 --- a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix +++ b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix @@ -27,7 +27,7 @@ }; fileSystems."/boot/firmware" = { - # This effectively "renames" the loaOf entry set in sd-image.nix + # This effectively "renames" the attrsOf entry set in sd-image.nix mountPoint = "/boot"; neededForBoot = true; }; diff --git a/nixos/modules/installer/tools/nixos-option/nixos-option.cc b/nixos/modules/installer/tools/nixos-option/nixos-option.cc index 1a7b07a74f8..f779d82edbd 100644 --- a/nixos/modules/installer/tools/nixos-option/nixos-option.cc +++ b/nixos/modules/installer/tools/nixos-option/nixos-option.cc @@ -224,7 +224,7 @@ bool optionTypeIs(Context & ctx, Value & v, const std::string & soughtType) bool isAggregateOptionType(Context & ctx, Value & v) { - return optionTypeIs(ctx, v, "attrsOf") || optionTypeIs(ctx, v, "listOf") || optionTypeIs(ctx, v, "loaOf"); + return optionTypeIs(ctx, v, "attrsOf") || optionTypeIs(ctx, v, "listOf"); } MakeError(OptionPathError, EvalError); diff --git a/nixos/modules/programs/ssh.nix b/nixos/modules/programs/ssh.nix index a983ffa4b89..40af4d0ff5a 100644 --- a/nixos/modules/programs/ssh.nix +++ b/nixos/modules/programs/ssh.nix @@ -131,7 +131,7 @@ in knownHosts = mkOption { default = {}; - type = types.loaOf (types.submodule ({ name, ... }: { + type = types.attrsOf (types.submodule ({ name, ... }: { options = { certAuthority = mkOption { type = types.bool; diff --git a/nixos/modules/programs/tsm-client.nix b/nixos/modules/programs/tsm-client.nix index eb6f1247528..7ac4086d5f0 100644 --- a/nixos/modules/programs/tsm-client.nix +++ b/nixos/modules/programs/tsm-client.nix @@ -7,7 +7,7 @@ let inherit (lib.modules) mkDefault mkIf; inherit (lib.options) literalExample mkEnableOption mkOption; inherit (lib.strings) concatStringsSep optionalString toLower; - inherit (lib.types) addCheck attrsOf lines loaOf nullOr package path port str strMatching submodule; + inherit (lib.types) addCheck attrsOf lines nullOr package path port str strMatching submodule; # Checks if given list of strings contains unique # elements when compared without considering case. @@ -178,7 +178,7 @@ let client system-options file "dsm.sys" ''; servers = mkOption { - type = loaOf (submodule [ serverOptions ]); + type = attrsOf (submodule [ serverOptions ]); default = {}; example.mainTsmServer = { server = "tsmserver.company.com"; diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index 565c15dec24..ce74805ef41 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -544,7 +544,7 @@ in security.pam.services = mkOption { default = []; - type = with types; loaOf (submodule pamOpts); + type = with types; attrsOf (submodule pamOpts); description = '' This option defines the PAM services. A service typically diff --git a/nixos/modules/services/backup/znapzend.nix b/nixos/modules/services/backup/znapzend.nix index 8098617d11f..0ca71b413ce 100644 --- a/nixos/modules/services/backup/znapzend.nix +++ b/nixos/modules/services/backup/znapzend.nix @@ -220,7 +220,7 @@ let }; destinations = mkOption { - type = loaOf (destType config); + type = attrsOf (destType config); description = "Additional destinations."; default = {}; example = literalExample '' @@ -328,7 +328,7 @@ in }; zetup = mkOption { - type = loaOf srcType; + type = attrsOf srcType; description = "Znapzend configuration."; default = {}; example = literalExample '' diff --git a/nixos/modules/services/desktops/geoclue2.nix b/nixos/modules/services/desktops/geoclue2.nix index 542b2ead410..6702bd395a0 100644 --- a/nixos/modules/services/desktops/geoclue2.nix +++ b/nixos/modules/services/desktops/geoclue2.nix @@ -160,7 +160,7 @@ in }; appConfig = mkOption { - type = types.loaOf appConfigModule; + type = types.attrsOf appConfigModule; default = {}; example = literalExample '' "com.github.app" = { diff --git a/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix b/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix index 6f49a1ab6d4..a6afa01dd81 100644 --- a/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix +++ b/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix @@ -81,7 +81,7 @@ in { office1 = { model = "MFC-7860DW"; ip = "192.168.1.2"; }; office2 = { model = "MFC-7860DW"; nodename = "BRW0080927AFBCE"; }; }; - type = with types; loaOf (submodule netDeviceOpts); + type = with types; attrsOf (submodule netDeviceOpts); description = '' The list of network devices that will be registered against the brscan4 sane backend. diff --git a/nixos/modules/services/networking/hylafax/options.nix b/nixos/modules/services/networking/hylafax/options.nix index 4ac6d3fa843..9e28d09dffc 100644 --- a/nixos/modules/services/networking/hylafax/options.nix +++ b/nixos/modules/services/networking/hylafax/options.nix @@ -3,7 +3,7 @@ let inherit (lib.options) literalExample mkEnableOption mkOption; - inherit (lib.types) bool enum int lines loaOf nullOr path str submodule; + inherit (lib.types) bool enum int lines attrsOf nullOr path str submodule; inherit (lib.modules) mkDefault mkIf mkMerge; commonDescr = '' @@ -248,7 +248,7 @@ in }; modems = mkOption { - type = loaOf (submodule [ modemConfigOptions ]); + type = attrsOf (submodule [ modemConfigOptions ]); default = {}; example.ttyS1 = { type = "cirrus"; diff --git a/nixos/modules/services/networking/nylon.nix b/nixos/modules/services/networking/nylon.nix index 7c171281a92..bfc358cb12f 100644 --- a/nixos/modules/services/networking/nylon.nix +++ b/nixos/modules/services/networking/nylon.nix @@ -140,7 +140,7 @@ in services.nylon = mkOption { default = {}; description = "Collection of named nylon instances"; - type = with types; loaOf (submodule nylonOpts); + type = with types; attrsOf (submodule nylonOpts); internal = true; }; diff --git a/nixos/modules/services/networking/prosody.nix b/nixos/modules/services/networking/prosody.nix index e53d7093be8..a6c1cb0f479 100644 --- a/nixos/modules/services/networking/prosody.nix +++ b/nixos/modules/services/networking/prosody.nix @@ -655,7 +655,7 @@ in description = "Define the virtual hosts"; - type = with types; loaOf (submodule vHostOpts); + type = with types; attrsOf (submodule vHostOpts); example = { myhost = { diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index 17f31e3a488..6b27cbc56bd 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -361,7 +361,7 @@ in }; users.users = mkOption { - type = with types; loaOf (submodule userOptions); + type = with types; attrsOf (submodule userOptions); }; }; diff --git a/nixos/modules/services/security/tor.nix b/nixos/modules/services/security/tor.nix index b33e905c67d..885b23ac694 100644 --- a/nixos/modules/services/security/tor.nix +++ b/nixos/modules/services/security/tor.nix @@ -597,7 +597,7 @@ in ]; } ''; - type = types.loaOf (types.submodule ({name, ...}: { + type = types.attrsOf (types.submodule ({name, ...}: { options = { name = mkOption { diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix index 166f89c7066..a4cbb03a8e3 100644 --- a/nixos/modules/system/boot/luksroot.nix +++ b/nixos/modules/system/boot/luksroot.nix @@ -516,7 +516,7 @@ in /dev/mapper/name. ''; - type = with types; loaOf (submodule ( + type = with types; attrsOf (submodule ( { name, ... }: { options = { name = mkOption { diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index a04660fb56e..97eb1d286a3 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -555,7 +555,7 @@ in }; fileSystems = mkOption { - type = with lib.types; loaOf (submodule { + type = with lib.types; attrsOf (submodule { options.neededForBoot = mkOption { default = false; type = types.bool; diff --git a/nixos/modules/system/etc/etc.nix b/nixos/modules/system/etc/etc.nix index 1f4d54a1ae2..7478e3e8071 100644 --- a/nixos/modules/system/etc/etc.nix +++ b/nixos/modules/system/etc/etc.nix @@ -46,7 +46,7 @@ in Set of files that have to be linked in /etc. ''; - type = with types; loaOf (submodule ( + type = with types; attrsOf (submodule ( { name, config, ... }: { options = { diff --git a/nixos/modules/tasks/encrypted-devices.nix b/nixos/modules/tasks/encrypted-devices.nix index 9c3f2d8fccb..dd337de9869 100644 --- a/nixos/modules/tasks/encrypted-devices.nix +++ b/nixos/modules/tasks/encrypted-devices.nix @@ -54,7 +54,7 @@ in options = { fileSystems = mkOption { - type = with lib.types; loaOf (submodule encryptedFSOptions); + type = with lib.types; attrsOf (submodule encryptedFSOptions); }; swapDevices = mkOption { type = with lib.types; listOf (submodule encryptedFSOptions); diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix index 0ade74b957a..3ea67dac714 100644 --- a/nixos/modules/tasks/filesystems.nix +++ b/nixos/modules/tasks/filesystems.nix @@ -159,7 +159,7 @@ in "/bigdisk".label = "bigdisk"; } ''; - type = types.loaOf (types.submodule [coreFileSystemOpts fileSystemOpts]); + type = types.attrsOf (types.submodule [coreFileSystemOpts fileSystemOpts]); description = '' The file systems to be mounted. It must include an entry for the root directory (mountPoint = "/"). Each @@ -193,7 +193,7 @@ in boot.specialFileSystems = mkOption { default = {}; - type = types.loaOf (types.submodule coreFileSystemOpts); + type = types.attrsOf (types.submodule coreFileSystemOpts); internal = true; description = '' Special filesystems that are mounted very early during boot. diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 565868724ad..2e533fb604e 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -519,7 +519,7 @@ in is true, then every interface not listed here will be configured using DHCP. ''; - type = with types; loaOf (submodule interfaceOpts); + type = with types; attrsOf (submodule interfaceOpts); }; networking.vswitches = mkOption { @@ -544,7 +544,7 @@ in interfaces = mkOption { example = [ "eth0" "eth1" ]; description = "The physical network interfaces connected by the vSwitch."; - type = with types; loaOf (submodule vswitchInterfaceOpts); + type = with types; attrsOf (submodule vswitchInterfaceOpts); }; controllers = mkOption { diff --git a/nixos/modules/virtualisation/nixos-containers.nix b/nixos/modules/virtualisation/nixos-containers.nix index b0fa03917c8..8fbb4efd201 100644 --- a/nixos/modules/virtualisation/nixos-containers.nix +++ b/nixos/modules/virtualisation/nixos-containers.nix @@ -627,7 +627,7 @@ in }; bindMounts = mkOption { - type = with types; loaOf (submodule bindMountOpts); + type = with types; attrsOf (submodule bindMountOpts); default = {}; example = literalExample '' { "/home" = { hostPath = "/home/alice"; diff --git a/nixos/modules/virtualisation/railcar.nix b/nixos/modules/virtualisation/railcar.nix index 3f188fc68e5..10464f62898 100644 --- a/nixos/modules/virtualisation/railcar.nix +++ b/nixos/modules/virtualisation/railcar.nix @@ -41,7 +41,7 @@ let description = "Source for the in-container mount"; }; options = mkOption { - type = loaOf (str); + type = attrsOf (str); default = [ "bind" ]; description = '' Mount options of the filesystem to be used. @@ -61,7 +61,7 @@ in containers = mkOption { default = {}; description = "Declarative container configuration"; - type = with types; loaOf (submodule ({ name, config, ... }: { + type = with types; attrsOf (submodule ({ name, config, ... }: { options = { cmd = mkOption { type = types.lines;