diff --git a/lib/tests/modules/docs.nix b/lib/tests/modules/docs.nix new file mode 100644 index 000000000000..225aa7eac1de --- /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 08854ca73f56..1a0a0f7ba01e 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..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..qux"); true; }; } diff --git a/lib/types.nix b/lib/types.nix index 59577856f4e1..5286ce76862e 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: