bazelbuild / stardoc

Stardoc: Starlark Documentation Generator
Apache License 2.0
107 stars 45 forks source link

Wrapping a rule with a macro of the same name prevents the rule from being documented #98

Open shs96c opened 3 years ago

shs96c commented 3 years ago

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.

aiuto commented 2 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)
alexeagle commented 1 year ago

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:

  1. in foo/private/foo.bzl export a rule foo that includes docstrings
  2. in foo/defs.bzl (the public API surface) load it with an alias load("//foo/private:foo.bzl", _foo = "foo")
  3. in foo/defs.bzl export foo_rule = _foo so that stardoc documents it.
  4. in 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.
  5. Power users who don't want the syntax sugar of the macro can now load 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.