use std::env; use std::error::Error; use std::path::{Path, PathBuf}; fn main() -> Result<(), Box> { 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 { 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 }