lol

lib.types.attrTag: Support module docs

+65 -1
+41
lib/tests/modules/docs.nix
··· 1 + /* 2 + A basic documentation generating module. 3 + Declares and defines a `docs` option, suitable for making assertions about 4 + the extraction "phase" of documentation generation. 5 + */ 6 + { lib, options, ... }: 7 + 8 + let 9 + inherit (lib) 10 + head 11 + length 12 + mkOption 13 + types 14 + ; 15 + 16 + traceListSeq = l: v: lib.foldl' (a: b: lib.traceSeq b a) v l; 17 + 18 + in 19 + 20 + { 21 + options.docs = mkOption { 22 + type = types.lazyAttrsOf types.raw; 23 + description = '' 24 + All options to be rendered, without any visibility filtering applied. 25 + ''; 26 + }; 27 + config.docs = 28 + lib.zipAttrsWith 29 + (name: values: 30 + if length values > 1 then 31 + traceListSeq values 32 + abort "Multiple options with the same name: ${name}" 33 + else 34 + assert length values == 1; 35 + head values 36 + ) 37 + (map 38 + (opt: { ${opt.name} = opt; }) 39 + (lib.optionAttrSetToDocList options) 40 + ); 41 + }
+19
lib/tests/modules/types-attrTag.nix
··· 28 28 } 29 29 ); 30 30 }; 31 + submodules = mkOption { 32 + type = types.attrsOf ( 33 + types.attrTag { 34 + foo = types.submodule { 35 + options = { 36 + bar = mkOption { 37 + type = types.int; 38 + }; 39 + }; 40 + }; 41 + qux = types.str; 42 + } 43 + ); 44 + }; 31 45 okChecks = mkOption {}; 32 46 }; 33 47 imports = [ 48 + ./docs.nix 34 49 { 35 50 options.merged = mkOption { 36 51 type = types.attrsOf ( ··· 59 74 assert config.intStrings.numberOne.left == 1; 60 75 assert config.merged.negative.nay == false; 61 76 assert config.merged.positive.yay == 100; 77 + # assert lib.foldl' (a: b: builtins.trace b a) true (lib.attrNames config.docs); 78 + assert config.docs."submodules.<name>.foo.bar".type == "signed integer"; 79 + # It's not an option, so we can't render it as such. Something would be nice though. 80 + assert ! (config.docs?"submodules.<name>.qux"); 62 81 true; 63 82 }; 64 83 }
+5 -1
lib/types.nix
··· 623 623 mkOptionType { 624 624 name = "attrTag"; 625 625 description = "attribute-tagged union of ${choicesStr}"; 626 - getSubModules = null; 626 + getSubOptions = prefix: 627 + mapAttrs 628 + (tagName: tagType: 629 + tagType.getSubOptions (prefix ++ [ tagName ])) 630 + tags; 627 631 substSubModules = m: attrTagWith { tags = mapAttrs (n: v: v.substSubModules m) tags; }; 628 632 check = v: isAttrs v && length (attrNames v) == 1 && tags?${head (attrNames v)}; 629 633 merge = loc: defs: