-
-
Notifications
You must be signed in to change notification settings - Fork 183
feat: allow proto_library as js_library#dep #2721
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
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
5210cdb
feat: add js_proto_toolchain
alexeagle eca2c6c
add missing bzl_library
alexeagle e06f532
code review comments
alexeagle 89dc20b
refactor: generalize
alexeagle c7d0dbe
now it is beautiful
alexeagle 24099b3
fix bzl_library
alexeagle File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| """An aspect that generates JavaScript and TypeScript code from .proto files. | ||
|
|
||
| This Bazel integration follows the "Local Generation" mechanism described at | ||
| https://connectrpc.com/docs/web/generating-code#local-generation, | ||
| using packages such as `@bufbuild/protoc-gen-es` and `@connectrpc/protoc-gen-connect-query` | ||
| as plugins to protoc. | ||
|
|
||
| The aspect converts a ProtoInfo provider into a JsInfo provider so that proto_library may be a dep to JS rules. | ||
| """ | ||
|
|
||
| load("@protobuf//bazel/common:proto_info.bzl", "ProtoInfo") | ||
| load("//js:providers.bzl", "JsInfo", "js_info") | ||
| load( | ||
| "//js/private:js_helpers.bzl", | ||
| "gather_npm_package_store_infos", | ||
| "gather_npm_sources", | ||
| "gather_transitive_sources", | ||
| "gather_transitive_types", | ||
| ) | ||
| load(":proto_common.bzl", "proto_common") | ||
|
|
||
| LANG_PROTO_TOOLCHAIN = Label("//js/toolchains:protoc_plugin") | ||
| PROTOC_TOOLCHAIN = Label("@protobuf//bazel/private:proto_toolchain_type") | ||
|
|
||
| def _js_proto_aspect_impl(target, ctx): | ||
| proto_info = target[ProtoInfo] | ||
| protoc_info = ctx.toolchains[PROTOC_TOOLCHAIN].proto | ||
| proto_lang_toolchain_info = ctx.toolchains[LANG_PROTO_TOOLCHAIN].proto | ||
| js_outputs = proto_common.declare_generated_files(ctx.actions, proto_info, "_pb.js") | ||
| dts_outputs = proto_common.declare_generated_files(ctx.actions, proto_info, "_pb.d.ts") | ||
| output_root = js_outputs[0].root | ||
|
|
||
| args = ctx.actions.args() | ||
| args.add(proto_lang_toolchain_info.plugin.executable, format = proto_lang_toolchain_info.plugin_format_flag) | ||
| proto_outdir = proto_common.output_directory(proto_info, output_root) | ||
| args.add_all((proto_lang_toolchain_info.out_replacement_format_flag % proto_outdir).split(" ")) | ||
| args.add("--descriptor_set_in") | ||
| args.add_joined(proto_info.transitive_descriptor_sets, join_with = ctx.configuration.host_path_separator) | ||
|
|
||
| # Vendored: https://github.com/protocolbuffers/protobuf/blob/v31.1/bazel/common/proto_common.bzl#L193-L204 | ||
| # Protoc searches for .protos -I paths in order they are given and then | ||
| # uses the path within the directory as the package. | ||
| # This requires ordering the paths from most specific (longest) to least | ||
| # specific ones, so that no path in the list is a prefix of any of the | ||
| # following paths in the list. | ||
| # For example: 'bazel-out/k8-fastbuild/bin/external/foo' needs to be listed | ||
| # before 'bazel-out/k8-fastbuild/bin'. If not, protoc will discover file under | ||
| # the shorter path and use 'external/foo/...' as its package path. | ||
| args.add_all(proto_info.transitive_proto_path, map_each = proto_common.import_virtual_proto_path) | ||
| args.add_all(proto_info.transitive_proto_path, map_each = proto_common.import_repo_proto_path) | ||
| args.add_all(proto_info.transitive_proto_path, map_each = proto_common.import_main_output_proto_path) | ||
| args.add("-I.") # Needs to come last | ||
|
|
||
| args.add_all(proto_info.direct_sources) | ||
|
|
||
| ctx.actions.run( | ||
| executable = protoc_info.proto_compiler.executable, | ||
| arguments = [args], | ||
| progress_message = "Generating .js/.d.ts from %{label}", | ||
| mnemonic = "JsProtocGenerate", | ||
| env = {"BAZEL_BINDIR": output_root.path}, | ||
| tools = [proto_lang_toolchain_info.plugin, protoc_info.proto_compiler], | ||
| inputs = depset(proto_info.direct_sources, transitive = [proto_info.transitive_descriptor_sets]), | ||
| outputs = js_outputs + dts_outputs, | ||
| use_default_shell_env = True, | ||
| ) | ||
|
|
||
| return [ | ||
| js_info( | ||
| target = ctx.label, | ||
| sources = depset(js_outputs), | ||
| types = depset(dts_outputs), | ||
| transitive_sources = gather_transitive_sources(js_outputs, ctx.rule.attr.deps), | ||
|
alexeagle marked this conversation as resolved.
|
||
| transitive_types = gather_transitive_types(dts_outputs, ctx.rule.attr.deps), | ||
| npm_sources = gather_npm_sources(srcs = [], deps = [proto_lang_toolchain_info.runtime]), | ||
| npm_package_store_infos = gather_npm_package_store_infos([proto_lang_toolchain_info.runtime]), | ||
| ), | ||
| ] | ||
|
|
||
| js_proto_aspect = aspect( | ||
| implementation = _js_proto_aspect_impl, | ||
| # Traverse the "deps" graph edges starting from the target | ||
| attr_aspects = ["deps"], | ||
| # Only visit nodes that produce a ProtoInfo provider | ||
| required_providers = [ProtoInfo], | ||
| # Be a valid dependency of a ts_project rule | ||
| provides = [JsInfo], | ||
| toolchains = [ | ||
| LANG_PROTO_TOOLCHAIN, | ||
| PROTOC_TOOLCHAIN, | ||
| ], | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| """Fork of | ||
| https://github.com/protocolbuffers/protobuf/blob/95dc8a02ad7d64527f0850c17edb1b86d3996ad8/bazel/common/proto_common.bzl#L15 | ||
| that exposes some helper functions that _compile uses, so we can implement our own version of it. | ||
| """ | ||
|
|
||
| load("@protobuf//bazel/common:proto_common.bzl", _proto_common = "proto_common") | ||
|
|
||
| def _import_virtual_proto_path(path): | ||
| """Imports all paths for virtual imports. | ||
|
|
||
| They're of the form: | ||
| 'bazel-out/k8-fastbuild/bin/external/foo/e/_virtual_imports/e' or | ||
| 'bazel-out/foo/k8-fastbuild/bin/e/_virtual_imports/e'""" | ||
| if path.count("/") > 4: | ||
| return "-I%s" % path | ||
| return None | ||
|
|
||
| def _import_repo_proto_path(path): | ||
| """Imports all paths for generated files in external repositories. | ||
|
|
||
| They are of the form: | ||
| 'bazel-out/k8-fastbuild/bin/external/foo' or | ||
| 'bazel-out/foo/k8-fastbuild/bin'""" | ||
| path_count = path.count("/") | ||
| if path_count > 2 and path_count <= 4: | ||
| return "-I%s" % path | ||
| return None | ||
|
|
||
| def _import_main_output_proto_path(path): | ||
| """Imports all paths for generated files or source files in external repositories. | ||
|
|
||
| They're of the form: | ||
| 'bazel-out/k8-fastbuild/bin' | ||
| 'external/foo' | ||
| '../foo' | ||
| """ | ||
| if path.count("/") <= 2 and path != ".": | ||
| return "-I%s" % path | ||
| return None | ||
|
|
||
| def _output_directory(proto_info, root): | ||
| proto_source_root = proto_info.proto_source_root | ||
| if proto_source_root.startswith(root.path): | ||
| #TODO: remove this branch when bin_dir is removed from proto_source_root | ||
| proto_source_root = proto_source_root.removeprefix(root.path).removeprefix("/") | ||
|
|
||
| if proto_source_root == "" or proto_source_root == ".": | ||
| return root.path | ||
|
|
||
| return root.path + "/" + proto_source_root | ||
|
|
||
| proto_common = struct( | ||
|
alexeagle marked this conversation as resolved.
|
||
| declare_generated_files = _proto_common.declare_generated_files, | ||
| import_virtual_proto_path = _import_virtual_proto_path, | ||
| import_repo_proto_path = _import_repo_proto_path, | ||
| import_main_output_proto_path = _import_main_output_proto_path, | ||
| output_directory = _output_directory, | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| """Protobuf and gRPC support for JavaScript and TypeScript. | ||
|
|
||
| See | ||
| - https://connectrpc.com/docs/web/getting-started | ||
| - https://connectrpc.com/docs/node/getting-started | ||
| """ | ||
|
|
||
| load("@protobuf//bazel/toolchains:proto_lang_toolchain.bzl", "proto_lang_toolchain") | ||
| load("//js/private:proto.bzl", "LANG_PROTO_TOOLCHAIN") | ||
|
|
||
| def js_proto_toolchain(name, **kwargs): | ||
| proto_lang_toolchain( | ||
| name = name, | ||
| toolchain_type = LANG_PROTO_TOOLCHAIN, | ||
| **kwargs | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| package(default_visibility = ["//visibility:public"]) | ||
|
|
||
| toolchain_type(name = "protoc_plugin") | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dzbarsky should we drop this in |
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.