Search code examples
protocol-buffersbazel

How to add support for `tags = ["manual"]` through a wrapper?


I noticed that the "unofficial" py_proto_library rule in https://github.com/protocolbuffers/protobuf/ doesn't respect tags = "manual". More specifically, the rule does two things: generate Python code, and create a py_library target. The tags are correctly forwarded to the py_library target, but ignored by the code generation rule. So, there's no way to prevent the code generation from being executed when running a wildcard build like bazel build //....

I thought I could work around this by creating my own macro wrapper:

load("@com_google_protobuf//:protobuf.bzl", real_py_proto_library = "py_proto_library")

def py_proto_library(**kwargs):
  """A py_proto_library that respects the "manual" tag."""
  if "tags" not in kwargs or "manual" not in kwargs["tags"]:
    real_py_proto_library(**kwargs)

But this is a little too respectful of tags = ["manual"]. It simply doesn't generate targets with that tag; there's no way to build them at all!

Is there some other approach that will handle tags = ["manual"] correctly, i.e. skip the target in wildcard builds, but build it when individually requested?


Solution

  • py_proto_library is actually a macro, not a rule. Macros have to manually propagate tags, because some should be handled differently (for example, if some internal rules are already manual, then adding a second one would be an error).

    I would approach it by passing the tags value to all the relevant functions, and having them each do something like maybe_manual = ["manual"] if "manual" in tags else []. Then the rules they create can use something like tags = ["something"] + maybe_manual.

    That should be a pretty straightforwards and helpful change. I'm not a protobuf maintainer, but I suspect they would accept a contribution along those lines.