Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module(

# Lower-bounds (minimum) versions for direct runtime dependencies.
# Do not bump these unless rules_js requires a newer version to function.
bazel_dep(name = "diff.bzl", version = "0.4.3")
bazel_dep(name = "tar.bzl", version = "0.6.0")
bazel_dep(name = "yq.bzl", version = "0.3.2")
bazel_dep(name = "jq.bzl", version = "0.4.0")
Expand Down
1 change: 1 addition & 0 deletions examples/proto/.bazelrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build --incompatible_enable_proto_toolchain_resolution
build --@protobuf//bazel/toolchains:prefer_prebuilt_protoc
build [email protected]//diff:validate
17 changes: 11 additions & 6 deletions examples/proto/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
load("@aspect_rules_js//js:defs.bzl", "js_library", "js_test")
load("@aspect_rules_js//js:defs.bzl", "js_test")
load("@aspect_rules_js//js:proto.bzl", "js_proto_library")
load("@npm//:defs.bzl", "npm_link_all_packages")
load("@protobuf//bazel:proto_library.bzl", "proto_library")

Expand All @@ -13,14 +14,18 @@ proto_library(
deps = ["@protobuf//:timestamp_proto"],
)

js_library(
name = "foo_js_lib",
# This edge runs an aspect to produce a JsInfo provider with protobuf .js/.d.ts files.
deps = [":foo_proto"],
js_proto_library(
name = "foo_js_proto",
copy_types = ["{}_pb.d.ts".format(name.replace(".proto", "")) for name in glob(["*.proto"])],
# An aspect is attached to this edge to produce a JsInfo provider
proto = ":foo_proto",
)

js_test(
name = "test",
data = [":foo_js_lib"],
data = [
":foo_js_proto",
":foo_js_proto.diff",
],
entry_point = "test_proto.js",
)
1 change: 1 addition & 0 deletions examples/proto/status.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ package status;

message Status {
google.protobuf.Timestamp created_at = 1;
string message = 2;
}
34 changes: 34 additions & 0 deletions examples/proto/status_pb.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions examples/proto/user_pb.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions js/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ bzl_library(
visibility = ["//visibility:public"],
deps = [
"//js/private:proto",
"@bazel_skylib//rules:select_file",
"@diff.bzl//diff:defs",
"@protobuf//bazel/toolchains:proto_lang_toolchain_bzl",
],
)
Expand Down
21 changes: 21 additions & 0 deletions js/private/proto.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,24 @@ js_proto_aspect = aspect(
PROTOC_TOOLCHAIN,
],
)

def _js_proto_library_impl(ctx):
return [
OutputGroupInfo(types = ctx.attr.proto[JsInfo].types),
ctx.attr.proto[JsInfo],
]

js_proto_library = rule(
doc = """A rule that wraps a proto_library to invoke the js_proto_aspect.

Useful when you must adapt a ProtoInfo provider to a JsInfo provider, for rule kinds that don't invoke the js_proto_aspect on their deps.
""",
implementation = _js_proto_library_impl,
attrs = {
"proto": attr.label(
mandatory = True,
providers = [ProtoInfo],
aspects = [js_proto_aspect],
),
},
)
28 changes: 27 additions & 1 deletion js/proto.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ js_library(
The generator you setup earlier will be invoked automatically as an action to generate the `.js` and `.d.ts` files.
"""

load("@bazel_skylib//rules:select_file.bzl", "select_file")
load("@diff.bzl//diff:defs.bzl", "diff")
load("@protobuf//bazel/toolchains:proto_lang_toolchain.bzl", "proto_lang_toolchain")
load("//js/private:proto.bzl", "LANG_PROTO_TOOLCHAIN")
load("//js/private:proto.bzl", "LANG_PROTO_TOOLCHAIN", js_proto_library_rule = "js_proto_library")

def js_proto_toolchain(name, plugin_name, plugin_options, plugin_bin, runtime, **kwargs):
"""Define a proto_lang_toolchain that uses the plugin.
Expand Down Expand Up @@ -97,3 +99,27 @@ def js_proto_toolchain(name, plugin_name, plugin_options, plugin_bin, runtime, *
runtime = runtime,
**kwargs
)

def js_proto_library(name, proto, copy_types = []):
"""Wrap a proto_library to invoke the js_proto_toolchain.

Can copy .d.ts type definitions back to the source folder.

Args:
name: The name of the library.
proto: The proto_library to wrap.
copy_types: HACK to get the label of the file in the source folder.
"""

js_proto_library_rule(name = name, proto = proto)
if len(copy_types) > 0:
native.filegroup(name = "_{}.types".format(name), srcs = [name], output_group = "types")
for i, src_file in enumerate(copy_types):
gen_file = "_{}.gen_{}.d.ts".format(name, i)
select_file(name = gen_file, srcs = "_{}.types".format(name), subpath = src_file)
diff(
name = "{}.diff_{}".format(name, i),
file1 = src_file,
file2 = gen_file,
)
native.filegroup(name = "{}.diff".format(name), srcs = ["{}.diff_{}".format(name, i) for i in range(len(copy_types))])
Loading