lib.types.attrTag: Support module docs

This commit is contained in:
Robert Hensing 2024-01-29 07:10:14 +01:00
parent 6949bc21ce
commit 5b49672af4
3 changed files with 65 additions and 1 deletions

View file

@ -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)
);
}

View file

@ -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;
};
}

View file

@ -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: