forked from typedb/typedb-dependencies
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
rust_tonic_compile
rule (typedb#391)
## What is the goal of this PR? We added the `rust_tonic_compile` rule which compiles `.proto` files into Rust sources that depend on the `tonic` and `prost` crates. ## What are the changes implemented in this PR? We had an existing Rust binary for compiling proto files into a Tonic library - a Cargo build script in `typedb-protocol`. But Cargo users shouldn't have to run `protoc` on their machine to compile `typedb-client` (which is what happens with a Cargo build script). Rather, the `typedb-protocol` crate should contain the generated Rust gRPC + Protobuf sources. So we've created a rule, `rust_tonic_compile`, that internally runs a `rust_binary` (similarly to how many of our rules run Kotlin binaries), which uses `tonic_build` to compile `.proto` files into Rust sources, and exposes the outputs. Any `rust_library` can then depend on these generated sources. The API is similar to Java and Python (`java_grpc_compile` and `python_grpc_compile` respectively), and the `antlr` rule from `rules_antlr` behaves similarly, too. Ideally, we wouldn't need our own rule to do this, however, the Bazel rules repos that contain Rust gRPC + Protobuf rules only support the `grpc` crate, and not the more popular `tonic` crate. Moreover, all of them already have open PRs for adding such functionality: - rules-proto-grpc/rules_proto_grpc#143 - stackb/rules_proto#201 - bazelbuild/rules_rust#915 Given that our implementation is **very minimal** (~30 lines of code) it should incur a very low maintenance effort.
- Loading branch information
1 parent
8106b66
commit e908d52
Showing
4 changed files
with
128 additions
and
3 deletions.
There are no files selected for viewing
This file contains 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 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,33 @@ | ||
# | ||
# Copyright (C) 2022 Vaticle | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
# | ||
|
||
load("@rules_rust//rust:defs.bzl", "rust_binary") | ||
load("@vaticle_dependencies//tool/checkstyle:rules.bzl", "checkstyle_test") | ||
|
||
rust_binary( | ||
name = "compile", | ||
srcs = ["compile.rs"], | ||
deps = ["@vaticle_dependencies//library/crates:tonic_build"], | ||
visibility = ["//visibility:public"] | ||
) | ||
|
||
checkstyle_test( | ||
name = "checkstyle", | ||
include = glob(["*"]), | ||
license_type = "agpl-header", | ||
size = "small", | ||
) |
This file contains 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,62 @@ | ||
# | ||
# Copyright (C) 2022 Vaticle | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
# | ||
|
||
def _rust_tonic_compile_impl(ctx): | ||
protos = [src[ProtoInfo].direct_sources[0] for src in ctx.attr.srcs] | ||
|
||
inputs = ctx.attr.protoc.files.to_list() + protos | ||
outputs = [ctx.actions.declare_file("{}.rs".format(package)) for package in ctx.attr.packages] | ||
|
||
ctx.actions.run( | ||
inputs = inputs, | ||
outputs = outputs, | ||
executable = ctx.executable._compile_script, | ||
env = { | ||
"OUT_DIR": outputs[0].dirname, | ||
"PROTOC": ctx.attr.protoc.files.to_list()[0].path, | ||
"PROTOS": ";".join([src.path for src in protos]), | ||
"PROTOS_ROOT": ctx.attr.srcs[0][ProtoInfo].proto_source_root, | ||
}, | ||
mnemonic = "RustTonicCompileAction" | ||
) | ||
|
||
return [DefaultInfo(files = depset(outputs))] | ||
|
||
rust_tonic_compile = rule( | ||
implementation = _rust_tonic_compile_impl, | ||
attrs = { | ||
"srcs": attr.label_list( | ||
allow_files = True, | ||
mandatory = True, | ||
doc = "The .proto source files." | ||
), | ||
"packages": attr.string_list( | ||
mandatory = True, | ||
allow_empty = False, | ||
doc = "The Protobuf package names. Each package name corresponds to a single output file." | ||
), | ||
"protoc": attr.label( | ||
default = "@com_google_protobuf//:protoc", | ||
doc = "The protoc executable." | ||
), | ||
"_compile_script": attr.label( | ||
executable = True, | ||
cfg = "host", | ||
default = "@vaticle_dependencies//builder/grpc/rust:compile", | ||
), | ||
} | ||
) |
This file contains 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,28 @@ | ||
// | ||
// Copyright (C) 2022 Vaticle | ||
// | ||
// This program is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU Affero General Public License as | ||
// published by the Free Software Foundation, either version 3 of the | ||
// License, or (at your option) any later version. | ||
// | ||
// This program is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU Affero General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU Affero General Public License | ||
// along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
// | ||
|
||
use std::env; | ||
|
||
fn main() -> std::io::Result<()> { | ||
let protos_raw = env::var("PROTOS").expect("PROTOS environment variable is not set"); | ||
let protos: Vec<&str> = protos_raw.split(";").filter(|&str| !str.is_empty()).collect(); | ||
|
||
tonic_build::configure() | ||
.compile(&protos, &[ | ||
env::var("PROTOS_ROOT").expect("PROTOS_ROOT environment variable is not set") | ||
]) | ||
} |