| :author: rules_proto_grpc |
| :description: Changelog for the rules_proto_grpc Bazel rules |
| :keywords: Bazel, Protobuf, gRPC, Protocol Buffers, Rules, Build, Starlark, Developers |
| |
| |
| Developers |
| ========== |
| |
| Contributions are very welcome on this project. Issues should be raised for bugs and feature |
| requests. Pull requests should be targeted at the master branch and will run against CI. |
| |
| .. note:: The rules in the repo are generated by the code in tools/rulegen and the output rules |
| should therefore not be edited directly. However, if you are not comfortable editing this code, |
| please submit a PR with just the output files edited and we'll help update the generator to get |
| the desired result. |
| |
| |
| Code Layout |
| ----------- |
| |
| Each language ``{lang}`` has a top-level subdirectory that contains: |
| |
| 1. ``docs/{lang}.rst``: Generated documentation for the language rules |
| |
| 1. ``{lang}/repositories.bzl``: Macro functions that declare repository rule dependencies for that language |
| |
| 2. ``{lang}/{rule}.bzl``: Rule implementations of the form ``{lang}_{kind}_{type}``, where ``kind`` is one of ``proto|grpc`` and |
| ``type`` is one of ``compile|library`` |
| |
| 3. ``{lang}/BUILD.bazel``: ``proto_plugin()`` declarations for the available plugins for the language |
| |
| 4. ``example/{lang}/{rule}/``: Generated ``WORKSPACE`` and ``BUILD.bazel`` demonstrating standalone usage of the rules |
| |
| 5. ``{lang}/example/routeguide/``: Example routeguide example implementation, if possible |
| |
| |
| Rule Generation |
| --------------- |
| |
| To help maintain consistency of the rule implementations and documentation, all of the rule implementations are |
| generated by the tool ``//tools/rulegen``. Changes in the main ``README.rst`` should be placed in |
| ``tools/rulegen/README.header.rst`` or ``tools/rulegen/README.footer.rst```. Changes to generated rules should be put in the |
| source files (example: ``tools/rulegen/java.go``). |
| |
| |
| Developing Custom Plugins |
| ------------------------- |
| |
| Generally, follow the pattern seen in the multiple language examples in this |
| repository. The basic idea is: |
| |
| 1. Load the plugin rule: ``load("@rules_proto_grpc//:defs.bzl", "proto_plugin")`` |
| 2. Define the rule, giving it a ``name``, ``options`` (not mandatory), ``tool`` and ``outputs``. ``tool`` is a label that refers |
| to the binary executable for the plugin itself |
| 3. Choose your output type (pick one!): |
| - ``outputs``: A list of strings patterns that predicts the pattern of files generated by the plugin. For plugins that |
| produce one output file per input proto file |
| - ``out``: The name of a single output file generated by the plugin |
| - ``output_directory``: Set to true if your plugin generates files in a non-predictable way. e.g. if the output paths |
| depend on the service names within the files |
| 4. Create a compilation rule and aspect using the following template: |
| |
| .. code-block:: python |
| |
| load("@rules_proto//proto:defs.bzl", "ProtoInfo") |
| load( |
| "@rules_proto_grpc//:defs.bzl", |
| "ProtoLibraryAspectNodeInfo", |
| "ProtoPluginInfo", |
| "proto_compile_aspect_attrs", |
| "proto_compile_aspect_impl", |
| "proto_compile_attrs", |
| "proto_compile_impl", |
| ) |
| |
| # Create aspect |
| example_aspect = aspect( |
| implementation = proto_compile_aspect_impl, |
| provides = [ProtoLibraryAspectNodeInfo], |
| attr_aspects = ["deps"], |
| attrs = dict( |
| proto_compile_aspect_attrs, |
| _plugins = attr.label_list( |
| doc = "List of protoc plugins to apply", |
| providers = [ProtoPluginInfo], |
| default = [ |
| Label("//<LABEL OF YOUR PLUGIN>"), |
| ], |
| ), |
| _prefix = attr.string( |
| doc = "String used to disambiguate aspects when generating outputs", |
| default = "example_aspect", |
| ), |
| ), |
| toolchains = ["@rules_proto_grpc//protobuf:toolchain_type"], |
| ) |
| |
| # Create compile rule to apply aspect |
| _rule = rule( |
| implementation = proto_compile_impl, |
| attrs = dict( |
| proto_compile_attrs, |
| protos = attr.label_list( |
| mandatory = False, # TODO: set to true in 4.0.0 when deps removed below |
| providers = [ProtoInfo], |
| doc = "List of labels that provide the ProtoInfo provider (such as proto_library from rules_proto)", |
| ), |
| deps = attr.label_list( |
| mandatory = False, |
| providers = [ProtoInfo, ProtoLibraryAspectNodeInfo], |
| aspects = [example_aspect], |
| doc = "DEPRECATED: Use protos attr", |
| ), |
| _plugins = attr.label_list( |
| providers = [ProtoPluginInfo], |
| default = [ |
| Label("//<LABEL OF YOUR PLUGIN>"), |
| ], |
| doc = "List of protoc plugins to apply", |
| ), |
| ), |
| toolchains = [str(Label("//protobuf:toolchain_type"))], |
| ) |
| |
| # Create macro for converting attrs and passing to compile |
| def example_compile(**kwargs): |
| _rule( |
| verbose_string = "{}".format(kwargs.get("verbose", 0)), |
| **kwargs |
| ) |