use std::env; use std::fs; use std::path::Path; fn main() -> Result<(), Box> { let args: Vec = env::args().collect(); if args.len() != 4 { eprintln!("Usage: {} ", args[0]); std::process::exit(1); } let proto_file = &args[1]; let _descriptor_file = &args[2]; // For future use if needed let output_file = &args[3]; // Generate Rust code using proper prost-build generate_prost_code(proto_file, output_file)?; Ok(()) } fn generate_prost_code(proto_file: &str, output_file: &str) -> Result<(), Box> { // Create a temporary directory for prost-build output let temp_dir = tempfile::tempdir()?; let temp_path = temp_dir.path(); // Configure prost-build let mut config = prost_build::Config::new(); // Set output directory config.out_dir(temp_path); // Configure derive traits - prost::Message provides Debug automatically config.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)]"); // Try to find protoc in the environment (Bazel should provide this) if let Ok(protoc_path) = env::var("PROTOC") { config.protoc_executable(&protoc_path); } // Get the directory containing the proto file for include path let proto_path = Path::new(proto_file); let include_dir = proto_path.parent().unwrap_or(Path::new(".")); // Try to compile the protos match config.compile_protos(&[proto_file], &[include_dir]) { Ok(_) => { // Find and read the generated files let generated_content = find_and_read_generated_files(temp_path)?; fs::write(output_file, generated_content)?; } Err(e) => { eprintln!("prost-build failed: {}", e); eprintln!("Available environment variables:"); for (key, value) in env::vars() { if key.contains("PROTOC") || key.contains("PATH") { eprintln!(" {}: {}", key, value); } } // This error should be surfaced to help debug the protoc issue return Err(format!("prost-build compilation failed: {}. This indicates protoc is not available in the Bazel sandbox. Consider passing protoc path via environment or simplifying the proto dependencies.", e).into()); } } Ok(()) } fn find_and_read_generated_files(dir: &Path) -> Result> { let mut content = String::from("// Generated by prost-build\n\n"); let mut found_files = false; for entry in fs::read_dir(dir)? { let entry = entry?; let path = entry.path(); if path.extension().and_then(|s| s.to_str()) == Some("rs") { let file_content = fs::read_to_string(&path)?; content.push_str(&file_content); content.push('\n'); found_files = true; } } if !found_files { return Err("No generated Rust files found from prost-build".into()); } Ok(content) }