-
-
Notifications
You must be signed in to change notification settings - Fork 13.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lib/types: init taggedSubmodule #254790
base: master
Are you sure you want to change the base?
lib/types: init taggedSubmodule #254790
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -710,6 +710,23 @@ rec { | |||||||
in mergedOption.type; | ||||||||
}; | ||||||||
|
||||||||
# A type that is one of several submodules, similiar to types.oneOf but is usable inside attrsOf or listOf | ||||||||
# submodules need an option with a type str which is used to find the corresponding type | ||||||||
taggedSubmodules = | ||||||||
{ types | ||||||||
, specialArgs ? {} | ||||||||
}: mkOptionType rec { | ||||||||
name = "taggedSubmodules"; | ||||||||
description = "one of ${concatStringsSep "," (attrNames types)}"; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
The valid type values can be documented in a generated |
||||||||
check = x: if x ? type then types.${x.type}.check x else throw "No type option set in:\n${lib.generators.toPretty {} x}"; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Assuming we keep the syntax as |
||||||||
merge = loc: foldl' | ||||||||
(res: def: types.${def.value.type}.merge loc [ | ||||||||
(lib.recursiveUpdate { value._module.args = specialArgs; } def) | ||||||||
]) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes it impossible btw to use { lib, ... }:
with lib;
let
mkDataset = cfg: mkMerge [ cfg { type = "zfs_fs"; } ];
mkLegacyMount = p: { mountpoint = p; options.mountpoint = "none"; };
in {
disko.devices.zpool.tank.datasets = mapAttrs (const mkDataset) {
"foo" = mkLegacyMount "/foo";
"bar" =mkLegacyMount "/bar";
};
} This gives the following error:
AFAIU this happens because each declaration on its own is passed into the wrapped type, i.e. the stuff from Anyways, having attr-sets inside the module system where the surroundings (i.e. [1] well, it fails, but it doesn't tell you that it fails because of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could probably be solved by doing an evalModules just to figure out the type and then evaluate the submodule again. (See https://github.com/NixOS/nixpkgs/pull/254790/files#r1323465281) |
||||||||
{ }; | ||||||||
Comment on lines
+722
to
+726
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same solution as in |
||||||||
nestedTypes = types; | ||||||||
}; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO
|
||||||||
|
||||||||
submoduleWith = | ||||||||
{ modules | ||||||||
, specialArgs ? {} | ||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -213,6 +213,57 @@ Submodules are detailed in [Submodule](#section-option-types-submodule). | |||||
options. This is equivalent to | ||||||
`types.submoduleWith { modules = toList o; shorthandOnlyDefinesConfig = true; }`. | ||||||
|
||||||
`types.taggedSubmodules` { *`types`*, *`specialArgs`* ? {} } | ||||||
|
||||||
: Like `types.oneOf`, but takes an attrsSet of submodule in types. Those need to have a type option | ||||||
which is used to find the correct submodule. | ||||||
|
||||||
::: {#ex-tagged-submodules .example} | ||||||
### Tagged submodules | ||||||
```nix | ||||||
let | ||||||
submoduleA = submodule { | ||||||
options = { | ||||||
type = mkOption { | ||||||
type = str; | ||||||
}; | ||||||
foo = mkOption { | ||||||
type = int; | ||||||
}; | ||||||
}; | ||||||
}; | ||||||
submoduleB = submodule { | ||||||
options = { | ||||||
type = mkOption { | ||||||
type = str; | ||||||
}; | ||||||
bar = mkOption { | ||||||
type = int; | ||||||
}; | ||||||
}; | ||||||
}; | ||||||
in | ||||||
options.mod = mkOption { | ||||||
type = attrsOf (taggedSubmodule { | ||||||
types = { | ||||||
a = submoduleA; | ||||||
b = submoduleB; | ||||||
}; | ||||||
}); | ||||||
}; | ||||||
config.mod = { | ||||||
someA = { | ||||||
type = "a"; | ||||||
foo = 123; | ||||||
}; | ||||||
someB = { | ||||||
type = "b"; | ||||||
foo = 456; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
}; | ||||||
}; | ||||||
``` | ||||||
::: | ||||||
|
||||||
`types.submoduleWith` { *`modules`*, *`specialArgs`* ? {}, *`shorthandOnlyDefinesConfig`* ? false } | ||||||
|
||||||
: Like `types.submodule`, but more flexible and with better defaults. | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When used by itself, the option value is just a single submodule.
The naming convention describes the option value rather than the definition syntax (or whether multiple defs are ok).
Also apply to
name
below.