Open shs96c opened 3 years ago
Adding to the feature request.
We want to pull up docstrings from the wrapped rule to the description. But we also want to be able to override the docstring from the wrapper. This is especially important for computed, mandatory arguments. Consider this case:
_foo = rule(..., attrs={
"out": attr.output(
doc = """output file name. Default: name + ".foo".""",
mandatory = True)
}
)
def foo(name, out=None, **kwargs):
if not out:
out = name + ".foo"
_foo(name=name, out=out, **kwargs)
default
in attr.output
, because the file 'name+".foo"' would be wrong.name + ".foo"
to appear in the default column.I think the solution is to give up on macros being a "tidy abstraction" for the underlying rule, and just be honest with users that both exist. In Aspect's rulesets, we've solved this problem by:
foo/private/foo.bzl
export a rule foo
that includes docstringsfoo/defs.bzl
(the public API surface) load it with an alias load("//foo/private:foo.bzl", _foo = "foo")
foo/defs.bzl
export foo_rule = _foo
so that stardoc documents it.foo/defs.bzl
define the macro foo
that calls _foo
to create rules. Also provide docstrings on the macro, but be honest that **kwargs
is passing args through to the underlying rule. Don't attempt to hide this from users.foo_rule
instead.Things like attribute defaults still get documented on the underlying rule.
As an example, see https://github.com/aspect-build/rules_ts/blob/main/docs/rules.md - the ts_project_rule
documents most of the attributes, has a nice link to "most users want the macro instead", and the macro just documents its syntax sugar.
One pattern in use in repos is to override a rule with a macro so that additional targets can be generated without needing to rewrite existing callers. An example of this approach can be seen in this PR.
stardoc
will document the macro, but will not find the wrapped rule, and so will not correctly document the project.