From 56f0338ec5edee11e513d74eaaa38c03d6b884e5 Mon Sep 17 00:00:00 2001 From: Matt Mackay Date: Tue, 23 Jul 2024 19:17:59 -0400 Subject: [PATCH] feat(ts_proto_library): expose protoc_gen_options on ts_proto_library (#650) --- docs/proto.md | 3 ++- ts/private/ts_proto_library.bzl | 19 +++++++++++++++---- ts/proto.bzl | 5 ++++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/docs/proto.md b/docs/proto.md index e99b41a2..1b388763 100644 --- a/docs/proto.md +++ b/docs/proto.md @@ -47,7 +47,7 @@ Future work ## ts_proto_library
-ts_proto_library(name, node_modules, proto, gen_connect_es, gen_connect_query,
+ts_proto_library(name, node_modules, proto, protoc_gen_options, gen_connect_es, gen_connect_query,
                  gen_connect_query_service_mapping, copy_files, proto_srcs, files_to_copy, kwargs)
 
@@ -61,6 +61,7 @@ A macro to generate JavaScript code and TypeScript typings from .proto files. | name | name of resulting ts_proto_library target | none | | node_modules | Label pointing to the linked node_modules target where @bufbuild/protoc-gen-es is linked, e.g. //:node_modules. Since the generated code depends on @bufbuild/protobuf, this package must also be linked. If `gen_connect_es = True` then @bufbuild/proto-gen-connect-es should be linked as well. If `gen_connect_query = True` then @bufbuild/proto-gen-connect-query should be linked as well. | none | | proto | the `proto_library` target that contains the .proto files to generate code for. | none | +| protoc_gen_options | dict of protoc_gen_es options. See https://github.com/bufbuild/protobuf-es/tree/main/packages/protoc-gen-es#plugin-options | `{}` | | gen_connect_es | whether protoc_gen_connect_es should generate grpc services, and therefore `*_connect.{js,d.ts}` should be written. | `True` | | gen_connect_query | whether protoc_gen_connect_query should generate [TanStack Query](https://tanstack.com/query) clients, and therefore `*_connectquery.{js,d.ts}` should be written. | `False` | | gen_connect_query_service_mapping | mapping from source proto file to the named RPC services that file contains. Needed to predict which files will be generated by gen_connect_query. See https://github.com/connectrpc/connect-query-es/tree/main/examples/react/basic/src/gen

For example, given `a.proto` which contains a service `Foo` and `b.proto` that contains a service `Bar`, the mapping would be `{"a.proto": ["Foo"], "b.proto": ["Bar"]}` | `{}` | diff --git a/ts/private/ts_proto_library.bzl b/ts/private/ts_proto_library.bzl index 8e29160a..ccd08927 100644 --- a/ts/private/ts_proto_library.bzl +++ b/ts/private/ts_proto_library.bzl @@ -7,10 +7,7 @@ load("@rules_proto//proto:proto_common.bzl", proto_toolchains = "toolchains") _PROTO_TOOLCHAIN_TYPE = "@rules_proto//proto:toolchain_type" # buildifier: disable=function-docstring-header -def _protoc_action(ctx, proto_info, outputs, options = { - "keep_empty_files": True, - "target": "js+dts", -}): +def _protoc_action(ctx, proto_info, outputs): """Create an action like bazel-out/k8-opt-exec-2B5CBBC6/bin/external/com_google_protobuf/protoc $@' '' \ '--plugin=protoc-gen-es=bazel-out/k8-opt-exec-2B5CBBC6/bin/plugin/bufbuild/protoc-gen-es.sh' \ @@ -21,6 +18,16 @@ def _protoc_action(ctx, proto_info, outputs, options = { """ inputs = depset(proto_info.direct_sources, transitive = [proto_info.transitive_descriptor_sets]) + options = dict({ + "keep_empty_files": True, + "target": "js+dts", + }, **ctx.attr.protoc_gen_options) + + if not options["keep_empty_files"]: + fail("protoc_gen_options.keep_empty_files must be True") + if options["target"] != "js+dts": + fail("protoc_gen_options.target must be 'js+dts'") + args = ctx.actions.args() args.add_joined(["--plugin", "protoc-gen-es", ctx.executable.protoc_gen_es.path], join_with = "=") for (key, value) in options.items(): @@ -105,6 +112,10 @@ ts_proto_library = rule( providers = [ProtoInfo], mandatory = True, ), + "protoc_gen_options": attr.string_dict( + doc = "dict of protoc_gen_es options", + default = {}, + ), "protoc_gen_es": attr.label( doc = "protoc plugin to generate messages", mandatory = True, diff --git a/ts/proto.bzl b/ts/proto.bzl index c484fac1..8663f7f6 100644 --- a/ts/proto.bzl +++ b/ts/proto.bzl @@ -47,7 +47,7 @@ load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_files") load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_library") load("//ts/private:ts_proto_library.bzl", ts_proto_library_rule = "ts_proto_library") -def ts_proto_library(name, node_modules, proto, gen_connect_es = True, gen_connect_query = False, gen_connect_query_service_mapping = {}, copy_files = True, proto_srcs = None, files_to_copy = None, **kwargs): +def ts_proto_library(name, node_modules, proto, protoc_gen_options = {}, gen_connect_es = True, gen_connect_query = False, gen_connect_query_service_mapping = {}, copy_files = True, proto_srcs = None, files_to_copy = None, **kwargs): """ A macro to generate JavaScript code and TypeScript typings from .proto files. @@ -58,6 +58,8 @@ def ts_proto_library(name, node_modules, proto, gen_connect_es = True, gen_conne If `gen_connect_es = True` then @bufbuild/proto-gen-connect-es should be linked as well. If `gen_connect_query = True` then @bufbuild/proto-gen-connect-query should be linked as well. proto: the `proto_library` target that contains the .proto files to generate code for. + protoc_gen_options: dict of protoc_gen_es options. + See https://github.com/bufbuild/protobuf-es/tree/main/packages/protoc-gen-es#plugin-options gen_connect_es: whether protoc_gen_connect_es should generate grpc services, and therefore `*_connect.{js,d.ts}` should be written. gen_connect_query: whether protoc_gen_connect_query should generate [TanStack Query](https://tanstack.com/query) clients, and therefore `*_connectquery.{js,d.ts}` should be written. gen_connect_query_service_mapping: mapping from source proto file to the named RPC services that file contains. @@ -132,6 +134,7 @@ def ts_proto_library(name, node_modules, proto, gen_connect_es = True, gen_conne gen_connect_query = gen_connect_query, gen_connect_query_service_mapping = gen_connect_query_service_mapping, proto = proto, + protoc_gen_options = protoc_gen_options, ) js_library(