Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using the gazelle starlark API, new files do not update existing rules #381

Open
avx-rchung opened this issue Nov 16, 2024 · 0 comments

Comments

@avx-rchung
Copy link

avx-rchung commented Nov 16, 2024

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant