Files
mxaccessgw/clients/rust/build.rs
Joseph Doherty 219fa6ddb4 fix(CLI-02): make Rust crate buildable outside the repository
build.rs resolved the .proto files via a monorepo-relative path and packaging
relied on `cargo publish --no-verify` to hide the resulting failure. Vendor the
three canonical protos into clients/rust/protos/, resolve them via
CARGO_MANIFEST_DIR (in-repo path preferred, vendored fallback for the packaged
crate), ship them via Cargo.toml `include`, and drop `--no-verify` from
pack-clients.ps1.

archreview: CLI-02 (P1). Verified: cargo fmt/check/test (28) + clippy -D warnings,
and `cargo package` (no --no-verify) compiles standalone in the isolated staging
dir — the out-of-repo proof. Vendored-proto drift is guarded by check-codegen.ps1.
2026-07-09 06:17:56 -04:00

80 lines
2.7 KiB
Rust

use std::env;
use std::error::Error;
use std::path::{Path, PathBuf};
fn main() -> Result<(), Box<dyn Error>> {
configure_protoc();
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?);
// Resolve the proto source directory. In-repo builds prefer the canonical
// Contracts protos (two levels above clients/rust) so local `.proto` edits
// are picked up live. When that path is absent — e.g. a consumer building
// the crate unpacked from a published tarball — fall back to the vendored
// copies shipped in `clients/rust/protos/` (see build.rs staleness note and
// CLI-02 in archreview/remediation/50-clients.md). Vendored copies are
// build inputs only; the canonical source remains in Contracts and must be
// refreshed here whenever the `.proto` files change.
let repo_proto_root = manifest_dir
.parent()
.and_then(Path::parent)
.map(|repo_root| repo_root.join("src/ZB.MOM.WW.MxGateway.Contracts/Protos"));
let vendored_proto_root = manifest_dir.join("protos");
let proto_root = match repo_proto_root {
Some(path) if path.is_dir() => path,
_ => vendored_proto_root,
};
let gateway_proto = proto_root.join("mxaccess_gateway.proto");
let worker_proto = proto_root.join("mxaccess_worker.proto");
let galaxy_proto = proto_root.join("galaxy_repository.proto");
let descriptor_path = PathBuf::from(env::var("OUT_DIR")?).join("mxaccessgw-client-v1.protoset");
println!("cargo:rerun-if-changed={}", gateway_proto.display());
println!("cargo:rerun-if-changed={}", worker_proto.display());
println!("cargo:rerun-if-changed={}", galaxy_proto.display());
tonic_build::configure()
.build_server(true)
.build_client(true)
.file_descriptor_set_path(descriptor_path)
.compile_protos(
&[
gateway_proto.as_path(),
worker_proto.as_path(),
galaxy_proto.as_path(),
],
&[proto_root.as_path()],
)?;
Ok(())
}
fn configure_protoc() {
if env::var_os("PROTOC").is_some() {
return;
}
for candidate in protoc_candidates() {
if candidate.is_file() {
env::set_var("PROTOC", candidate);
return;
}
}
}
fn protoc_candidates() -> Vec<PathBuf> {
let mut candidates = Vec::new();
if cfg!(windows) {
if let Some(local_app_data) = env::var_os("LOCALAPPDATA") {
candidates.push(PathBuf::from(local_app_data).join(
"Microsoft/WinGet/Packages/Google.Protobuf_Microsoft.Winget.Source_8wekyb3d8bbwe/bin/protoc.exe",
));
}
}
candidates.push(PathBuf::from("protoc"));
candidates
}