-
Notifications
You must be signed in to change notification settings - Fork 156
Description
I am trying to use a gazelle rule with the starlark extension API to dynamically update rules to generate a type library
The standard gazelle:proto_plugin
already supports using builtin:pyi
to generate python type stubs from protobuf, but there isn't a good way out of the box to create a library out of these pyi files for consumption. The bazel-mypy-integration project has a mypy_stubs
rule that is good for this purpose (https://github.com/bazel-contrib/bazel-mypy-integration/blob/main/rules.bzl) so we just need to glue these together.
I attempted to do it using these gazelle declarations:
# gazelle:proto_plugin python implementation builtin:python
# gazelle:proto_rule proto_python_library implementation stackb:rules_proto:proto_py_library
# gazelle:proto_rule proto_python_stub_library implementation example/starlark_proto/lib/rules.star%proto_python_stubs_library
# gazelle:proto_rule proto_python_stub_library visibility //visibility:public
# gazelle:proto_language python plugin python
# gazelle:proto_language python rule proto_python_library
# gazelle:proto_language python rule proto_python_stub_library
and a rules.star
like this:
"""rules_proto based language rules."""
# Ref: https://github.com/stackb/rules_proto/blob/master/pkg/protoc/starlark_rule.go
def _make_proto_python_rule(rule_cfg, protoc_cfg):
return gazelle.Rule(
kind = "mypy_stubs",
name = protoc_cfg.proto_library.base_name + "_pyi_library",
attrs = {
"srcs": [x.replace(".proto", "_pb2.pyi") for x in protoc_cfg.proto_library.srcs],
"visibility": rule_cfg.visibility,
},
)
def _provide_python(rctx, pctx):
return struct(
name = "proto_python_stubs_library",
rule = lambda: _make_proto_python_rule(rctx, pctx),
experimental_resolve_attr = "deps",
)
protoc.Rule(
name = "proto_python_stubs_library",
load_info = lambda: gazelle.LoadInfo(name = "//example/starlark_proto/lib:rules.bzl", symbols = ["mypy_stubs"]),
kind_info = lambda: gazelle.KindInfo(mergeable_attrs = {"srcs": True}, resolve_attrs = {"deps": True}),
provide_rule = _provide_python,
This works on the first run, but when a new proto is added, I noticed that while the "native" rules are updated, the starlark based one is not.
Full example here: https://github.com/avx-rchung/rules_proto/tree/starlark-example in the example/starlark_proto directory
Initial run to check everything is generated as expected:
$ bazel run :gazelle -- example/starlark_proto
check output in example/starlark_proto/proto/BUILD.bazel
-- looks good.
Add a new protobuf:
$ sed -e 's/Bar/Baz/' example/starlark_proto/proto/b.proto > example/starlark_proto/proto/c.proto
$ bazel run :gazelle -- example/starlark_proto
Note that c_pb2.* gets added to proto_library
, proto_compile
, proto_py_library
but not mypy_stubs
If I delete the mypy_stub run and re-run gazelle and the rule is regenerated properly (including c_pb2)