Skip to content

Commit 12fd477

Browse files
committed
Implement prost
1 parent b418962 commit 12fd477

18 files changed

Lines changed: 1979 additions & 40 deletions

MODULE.bazel

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,45 @@ bazel_dep(name = "bazel_features", version = "1.32.0")
5151
bazel_dep(name = "bazel_skylib", version = "1.4.1")
5252
bazel_dep(name = "package_metadata", version = "0.0.5")
5353
bazel_dep(name = "platforms", version = "0.0.5")
54+
bazel_dep(name = "protobuf", version = "34.0.bcr.1", repo_name = "com_google_protobuf")
5455
bazel_dep(name = "rules_cc", version = "0.2.8")
56+
bazel_dep(name = "rules_proto", version = "7.1.0")
5557
bazel_dep(name = "llvm", version = "0.6.7")
5658
bazel_dep(name = "aspect_tools_telemetry", version = "0.3.2")
5759

5860
tel = use_extension("@aspect_tools_telemetry//:extension.bzl", "telemetry")
5961
use_repo(tel, "aspect_tools_telemetry_report")
6062

63+
crate = use_extension("//rs:extensions.bzl", "crate")
64+
crate.from_cargo(
65+
name = "rrprd",
66+
cargo_lock = "//rs/private/prost:Cargo.lock",
67+
cargo_toml = "//rs/private/prost:Cargo.toml",
68+
platform_triples = [
69+
"aarch64-unknown-linux-gnu",
70+
"aarch64-apple-darwin",
71+
"aarch64-pc-windows-gnullvm",
72+
"aarch64-pc-windows-msvc",
73+
"x86_64-unknown-linux-gnu",
74+
"x86_64-apple-darwin",
75+
"x86_64-pc-windows-gnullvm",
76+
"x86_64-pc-windows-msvc",
77+
],
78+
use_experimental_platforms = True,
79+
)
80+
crate.annotation(
81+
crate = "protoc-gen-prost",
82+
gen_binaries = ["protoc-gen-prost"],
83+
)
84+
crate.annotation(
85+
crate = "protoc-gen-tonic",
86+
gen_binaries = ["protoc-gen-tonic"],
87+
)
88+
use_repo(crate, "rrprd")
89+
90+
rules_rust_prost = use_extension("//rs/experimental:rules_rust_prost.bzl", "rules_rust_prost")
91+
use_repo(rules_rust_prost, "rules_rust_prost")
92+
6193
bazel_dep(name = "rules_go", version = "0.59.0", dev_dependency = True)
6294
bazel_dep(name = "gazelle", version = "0.47.0", dev_dependency = True)
6395
bazel_dep(name = "bazel_skylib_gazelle_plugin", version = "1.8.2", dev_dependency = True)

MODULE.bazel.lock

Lines changed: 166 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,23 @@ If you import `rules_rust` via this extension, existing `load("@rules_rust//..."
165165
Using this extension is STRONGLY ENCOURAGED because it carries fixes that improve Windows behavior, rust-analyzer integration, and related compatibility work.
166166
In addition, when using the `rules_rs` toolchains, loading the compilation rules from `@rules_rs` directly and using the extension is REQUIRED for toolchain resolution to work correctly, at least until https://github.com/bazelbuild/rules_rust/pull/3857 is accepted by rules_rust maintainers. See the Migration section for more info.
167167

168+
## Import `rules_rust_prost` from `rules_rs`
169+
170+
`rules_rs` also exports a `rules_rust_prost` module extension for the prost integration:
171+
172+
```bzl
173+
bazel_dep(name = "rules_proto", version = "7.1.0")
174+
bazel_dep(name = "protobuf", version = "34.0.bcr.1", repo_name = "com_google_protobuf")
175+
176+
rules_rust_prost = use_extension("@rules_rs//rs/experimental:rules_rust_prost.bzl", "rules_rust_prost")
177+
use_repo(rules_rust_prost, "rules_rust_prost")
178+
179+
register_toolchains("@rules_rust_prost//:default_prost_toolchain")
180+
register_toolchains("@//path/to/proto_toolchain")
181+
```
182+
183+
The default prost toolchain and its cargo dependencies are provided by `rules_rs`. If you need different prost, tonic, or plugin versions, you can still define your own `rust_prost_toolchain` from `@rules_rust_prost//:defs.bzl`.
184+
168185
## Platform Configuration
169186

170187
For reliable toolchain resolution, ABI choices should be explicit on every platform participating in your build, including the host platform.

rs/experimental/BUILD.bazel

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,12 @@ bzl_library(
1010
"@bazel_tools//tools/build_defs/repo:utils.bzl",
1111
],
1212
)
13+
14+
bzl_library(
15+
name = "rules_rust_prost",
16+
srcs = ["rules_rust_prost.bzl"],
17+
visibility = ["//visibility:public"],
18+
deps = [
19+
"@bazel_tools//tools/build_defs/repo:local.bzl",
20+
],
21+
)

rs/experimental/rules_rust.bzl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ def _rules_rust_impl(mctx):
3131

3232
http_archive(
3333
name = "rules_rust",
34-
integrity = "sha256-72j2ji/HaSnpKEKM0DZ/HWhk8PD4jZ6aXIIf0ZSuV4Y=",
35-
strip_prefix = "rules_rust-af83221c2b87b80b0178bfc7a87da877246644f5",
36-
url = "https://github.com/hermeticbuild/rules_rust/archive/af83221c2b87b80b0178bfc7a87da877246644f5.tar.gz",
34+
integrity = "sha256-xT7zyL35CDK5b7iKdKL+WchslRZsnXDXuBMHiqVD0ps=",
35+
strip_prefix = "rules_rust-7ed8a24a37be47378b8a266ae3016148b9cb5c49",
36+
url = "https://github.com/hermeticbuild/rules_rust/archive/7ed8a24a37be47378b8a266ae3016148b9cb5c49.tar.gz",
3737
patches = patches,
3838
patch_strip = strip,
3939
)
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
"""Module extension that provisions the rules_rust_prost repository."""
2+
3+
load("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository")
4+
5+
def _rules_rust_prost_repo_impl(rctx):
6+
rctx.file("BUILD.bazel", """\
7+
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
8+
9+
package(default_visibility = ["//visibility:public"])
10+
11+
exports_files([
12+
"defs.bzl",
13+
"providers.bzl",
14+
])
15+
16+
toolchain_type(
17+
name = "toolchain_type",
18+
)
19+
20+
toolchain(
21+
name = "default_prost_toolchain",
22+
toolchain = "@rules_rs//rs/private/prost:default_prost_toolchain_impl",
23+
toolchain_type = ":toolchain_type",
24+
)
25+
26+
bzl_library(
27+
name = "bzl_lib",
28+
srcs = [
29+
"defs.bzl",
30+
"providers.bzl",
31+
],
32+
deps = [
33+
"@rules_rust_prost_upstream//:bzl_lib",
34+
],
35+
)
36+
""")
37+
38+
rctx.file("defs.bzl", """\
39+
load(
40+
"@rules_rust_prost_upstream//:defs.bzl",
41+
_rust_prost_library = "rust_prost_library",
42+
_rust_prost_toolchain = "rust_prost_toolchain",
43+
_rust_prost_transform = "rust_prost_transform",
44+
)
45+
46+
rust_prost_library = _rust_prost_library
47+
rust_prost_toolchain = _rust_prost_toolchain
48+
rust_prost_transform = _rust_prost_transform
49+
""")
50+
51+
rctx.file("private/BUILD.bazel", """\
52+
alias(
53+
name = "protoc_wrapper",
54+
actual = "@rules_rs//rs/private/prost:protoc_wrapper",
55+
visibility = ["//visibility:public"],
56+
)
57+
58+
alias(
59+
name = "protoc_wrapper_source",
60+
actual = "@rules_rust_prost_upstream//private:protoc_wrapper.rs",
61+
visibility = ["//visibility:public"],
62+
)
63+
""")
64+
65+
rctx.file("providers.bzl", """\
66+
load("@rules_rust_prost_upstream//:providers.bzl", _ProstProtoInfo = "ProstProtoInfo")
67+
68+
ProstProtoInfo = _ProstProtoInfo
69+
""")
70+
71+
return rctx.repo_metadata(reproducible = True)
72+
73+
_rules_rust_prost_repo = repository_rule(
74+
implementation = _rules_rust_prost_repo_impl,
75+
)
76+
77+
def _rules_rust_prost_impl(mctx):
78+
local_repository(
79+
name = "rules_rust_prost_upstream",
80+
path = str(mctx.path(Label("@rules_rust//:extensions/prost/WORKSPACE.bzlmod")).dirname),
81+
)
82+
83+
_rules_rust_prost_repo(
84+
name = "rules_rust_prost",
85+
)
86+
87+
return mctx.extension_metadata(
88+
root_module_direct_deps = ["rules_rust_prost"],
89+
root_module_direct_dev_deps = [],
90+
reproducible = True,
91+
)
92+
93+
rules_rust_prost = module_extension(
94+
implementation = _rules_rust_prost_impl,
95+
)

rs/extensions.bzl

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -821,9 +821,8 @@ crate.annotation(
821821

822822
hub_contents = []
823823
for name, versions in versions_by_name.items():
824-
binaries = annotation_for(annotations, name, version).gen_binaries
825-
826824
for version in versions:
825+
binaries = annotation_for(annotations, name, version).gen_binaries
827826
spoke_repo = _spoke_repo(hub_name, name, version)
828827

829828
hub_contents.append("""
@@ -842,6 +841,8 @@ alias(
842841
workspace_versions = workspace_dep_versions_by_name.get(name)
843842
if workspace_versions:
844843
fq = sorted(workspace_versions)[-1]
844+
default_version = fq[len(name) + 1:]
845+
binaries = annotation_for(annotations, name, default_version).gen_binaries
845846

846847
hub_contents.append("""
847848
alias(
@@ -1139,18 +1140,23 @@ def _crate_impl(mctx):
11391140

11401141
packages_by_hub_name = {}
11411142
cargo_toml_by_hub_name = {}
1143+
cargo_credentials_by_hub_name = {}
1144+
annotations_by_hub_name = {}
11421145

11431146
for mod in mctx.modules:
11441147
if not mod.tags.from_cargo:
11451148
fail("`.from_cargo` is required. Please update %s" % mod.name)
11461149

11471150
for cfg in mod.tags.from_cargo:
11481151
annotations = build_annotation_map(mod, cfg.name)
1152+
annotations_by_hub_name[cfg.name] = annotations
11491153
mctx.watch(cfg.cargo_lock)
11501154
mctx.watch(cfg.cargo_toml)
11511155
cargo_toml_by_hub_name[cfg.name] = run_toml2json(mctx, cfg.cargo_toml)
11521156
cargo_lock = run_toml2json(mctx, cfg.cargo_lock)
11531157
parsed_packages = cargo_lock.get("package", [])
1158+
for package in parsed_packages:
1159+
package["hub_name"] = cfg.name
11541160
packages_by_hub_name[cfg.name] = parsed_packages
11551161

11561162
# Process git downloads first because they may require a followup download if the repo is a workspace,
@@ -1169,12 +1175,13 @@ def _crate_impl(mctx):
11691175
else:
11701176
cargo_credentials = {}
11711177

1178+
cargo_credentials_by_hub_name[cfg.name] = cargo_credentials
11721179
start_crate_registry_downloads(mctx, downloader_state, annotations, packages_by_hub_name[cfg.name], cargo_credentials, cfg.debug)
11731180

11741181
for fetch_state in downloader_state.in_flight_git_crate_fetches_by_url.values():
11751182
fetch_state.download_token.wait()
11761183

1177-
download_metadata_for_git_crates(mctx, downloader_state, annotations)
1184+
download_metadata_for_git_crates(mctx, downloader_state, annotations_by_hub_name)
11781185

11791186
# TODO(zbarsky): Unfortunate that we block on the download for crates.io even though it's well-known.
11801187
# Should we hardcode it?
@@ -1186,12 +1193,14 @@ def _crate_impl(mctx):
11861193

11871194
for mod in mctx.modules:
11881195
for cfg in mod.tags.from_cargo:
1189-
if mctx.is_dev_dependency(cfg):
1190-
direct_dev_deps.append(cfg.name)
1191-
else:
1192-
direct_deps.append(cfg.name)
1196+
if mod.is_root:
1197+
if mctx.is_dev_dependency(cfg):
1198+
direct_dev_deps.append(cfg.name)
1199+
else:
1200+
direct_deps.append(cfg.name)
11931201

11941202
hub_packages = packages_by_hub_name[cfg.name]
1203+
cargo_credentials = cargo_credentials_by_hub_name[cfg.name]
11951204

11961205
annotations = build_annotation_map(mod, cfg.name)
11971206

rs/private/downloader.bzl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,21 @@ def _compute_strip_prefix(annotation, cargo_toml_json, name):
291291
# TODO(zbarsky): any more cases to handle here?
292292
return strip_prefix
293293

294+
def _annotations_for_package(annotations_by_hub_name, package):
295+
hub_name = package.get("hub_name")
296+
if not hub_name:
297+
fail("Missing hub_name for package %s" % package.get("name", "<unknown>"))
298+
299+
annotations = annotations_by_hub_name.get(hub_name)
300+
if annotations == None:
301+
fail("Missing annotations for hub %s" % hub_name)
302+
303+
return annotations
304+
294305
def download_metadata_for_git_crates(
295306
mctx,
296307
state,
297-
annotations):
308+
annotations_by_hub_name):
298309
for url, fetch_state in state.in_flight_git_crate_fetches_by_url.items():
299310
cargo_toml_path = _sanitize_path_fragment(url)
300311
_ensure_cargo_toml_exists(mctx.path(cargo_toml_path), fetch_state)
@@ -304,6 +315,7 @@ def download_metadata_for_git_crates(
304315

305316
for package in fetch_state.packages:
306317
name = package["name"]
318+
annotations = _annotations_for_package(annotations_by_hub_name, package)
307319

308320
if cargo_toml_json.get("package", {}).get("name") != name:
309321
annotation = annotation_for(annotations, name, package["version"])
@@ -342,6 +354,7 @@ def download_metadata_for_git_crates(
342354

343355
# TODO(zbarsky): multiple crates?
344356
first_pkg = clone_state.packages[0]
357+
annotations = _annotations_for_package(annotations_by_hub_name, first_pkg)
345358
annotation = annotation_for(annotations, first_pkg["name"], first_pkg["version"])
346359
cargo_toml_path = clone_dir.get_child(annotation.workspace_cargo_toml)
347360
_ensure_cargo_toml_exists(cargo_toml_path, clone_state)
@@ -350,6 +363,7 @@ def download_metadata_for_git_crates(
350363

351364
for package in clone_state.packages:
352365
name = package["name"]
366+
annotations = _annotations_for_package(annotations_by_hub_name, package)
353367

354368
if cargo_toml_json.get("package", {}).get("name") != name:
355369
annotation = annotation_for(annotations, name, package["version"])

rs/private/prost/BUILD.bazel

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
2+
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library_group")
3+
load("@rules_rust_prost//:defs.bzl", "rust_prost_toolchain")
4+
5+
package(default_visibility = ["//visibility:public"])
6+
7+
PROST_RUST_EDITION = "2021"
8+
9+
exports_files([
10+
"Cargo.lock",
11+
"Cargo.toml",
12+
])
13+
14+
bool_flag(
15+
name = "compile_well_known_types",
16+
build_setting_default = True,
17+
)
18+
19+
config_setting(
20+
name = "compile_well_known_types_setting",
21+
flag_values = {
22+
":compile_well_known_types": "true",
23+
},
24+
)
25+
26+
rust_binary(
27+
name = "protoc_wrapper",
28+
srcs = ["@rules_rust_prost//private:protoc_wrapper_source"],
29+
edition = PROST_RUST_EDITION,
30+
deps = [
31+
"@rrprd//:heck-0.5.0",
32+
"@rrprd//:prost",
33+
"@rrprd//:prost-types",
34+
],
35+
)
36+
37+
rust_library_group(
38+
name = "prost_runtime",
39+
deps = [
40+
"@rrprd//:prost",
41+
],
42+
)
43+
44+
rust_library_group(
45+
name = "tonic_runtime",
46+
deps = [
47+
":prost_runtime",
48+
"@rrprd//:tonic",
49+
],
50+
)
51+
52+
rust_prost_toolchain(
53+
name = "default_prost_toolchain_impl",
54+
compile_well_known_types = select({
55+
":compile_well_known_types_setting": True,
56+
"//conditions:default": False,
57+
}),
58+
prost_plugin = "@rrprd//:protoc-gen-prost__protoc-gen-prost",
59+
prost_plugin_flag = "--plugin=protoc-gen-prost=%s",
60+
prost_runtime = ":prost_runtime",
61+
prost_types = "@rrprd//:prost-types",
62+
tonic_plugin = "@rrprd//:protoc-gen-tonic__protoc-gen-tonic",
63+
tonic_plugin_flag = "--plugin=protoc-gen-tonic=%s",
64+
tonic_runtime = ":tonic_runtime",
65+
)

0 commit comments

Comments
 (0)