diff options
author | Robert Hensing <robert@roberthensing.nl> | 2024-01-29 07:10:14 +0100 |
---|---|---|
committer | Robert Hensing <robert@roberthensing.nl> | 2024-04-04 11:54:41 +0200 |
commit | 5b49672af44875df0449f7ff1b55965eedeec1da (patch) | |
tree | 95bc925c9eb0f64dec8734242dfb46811d8f99c0 | |
parent | 6949bc21ce1de068bc1b21e273d15620c0e5770e (diff) |
lib.types.attrTag: Support module docs
-rw-r--r-- | lib/tests/modules/docs.nix | 41 | ||||
-rw-r--r-- | lib/tests/modules/types-attrTag.nix | 19 | ||||
-rw-r--r-- | lib/types.nix | 6 |
3 files changed, 65 insertions, 1 deletions
diff --git a/lib/tests/modules/docs.nix b/lib/tests/modules/docs.nix new file mode 100644 index 0000000000000..225aa7eac1de8 --- /dev/null +++ b/lib/tests/modules/docs.nix @@ -0,0 +1,41 @@ +/* + A basic documentation generating module. + Declares and defines a `docs` option, suitable for making assertions about + the extraction "phase" of documentation generation. + */ +{ lib, options, ... }: + +let + inherit (lib) + head + length + mkOption + types + ; + + traceListSeq = l: v: lib.foldl' (a: b: lib.traceSeq b a) v l; + +in + +{ + options.docs = mkOption { + type = types.lazyAttrsOf types.raw; + description = '' + All options to be rendered, without any visibility filtering applied. + ''; + }; + config.docs = + lib.zipAttrsWith + (name: values: + if length values > 1 then + traceListSeq values + abort "Multiple options with the same name: ${name}" + else + assert length values == 1; + head values + ) + (map + (opt: { ${opt.name} = opt; }) + (lib.optionAttrSetToDocList options) + ); +} diff --git a/lib/tests/modules/types-attrTag.nix b/lib/tests/modules/types-attrTag.nix index 08854ca73f566..1a0a0f7ba01e4 100644 --- a/lib/tests/modules/types-attrTag.nix +++ b/lib/tests/modules/types-attrTag.nix @@ -28,9 +28,24 @@ in } ); }; + submodules = mkOption { + type = types.attrsOf ( + types.attrTag { + foo = types.submodule { + options = { + bar = mkOption { + type = types.int; + }; + }; + }; + qux = types.str; + } + ); + }; okChecks = mkOption {}; }; imports = [ + ./docs.nix { options.merged = mkOption { type = types.attrsOf ( @@ -59,6 +74,10 @@ in assert config.intStrings.numberOne.left == 1; assert config.merged.negative.nay == false; assert config.merged.positive.yay == 100; + # assert lib.foldl' (a: b: builtins.trace b a) true (lib.attrNames config.docs); + assert config.docs."submodules.<name>.foo.bar".type == "signed integer"; + # It's not an option, so we can't render it as such. Something would be nice though. + assert ! (config.docs?"submodules.<name>.qux"); true; }; } diff --git a/lib/types.nix b/lib/types.nix index 59577856f4e1f..5286ce76862e2 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -623,7 +623,11 @@ rec { mkOptionType { name = "attrTag"; description = "attribute-tagged union of ${choicesStr}"; - getSubModules = null; + getSubOptions = prefix: + mapAttrs + (tagName: tagType: + tagType.getSubOptions (prefix ++ [ tagName ])) + tags; substSubModules = m: attrTagWith { tags = mapAttrs (n: v: v.substSubModules m) tags; }; check = v: isAttrs v && length (attrNames v) == 1 && tags?${head (attrNames v)}; merge = loc: defs: |