use std::io::Result;
fn main() -> Result<()> {
println!("cargo:rerun-if-env-changed=PROTOC");
println!("cargo:rerun-if-env-changed=FLARE_CORE_REGENERATE_PROTO");
std::fs::create_dir_all("src/common/protocol")?;
let flare_core_path = "src/common/protocol/flare.core.rs";
let commands_path = "src/common/protocol/flare.core.commands.rs";
let files_exist = std::path::Path::new(flare_core_path).exists()
&& std::path::Path::new(commands_path).exists();
let regenerate_proto = std::env::var_os("FLARE_CORE_REGENERATE_PROTO").is_some();
if files_exist && !regenerate_proto {
println!("cargo:rerun-if-changed=proto/frame.proto");
println!("cargo:rerun-if-changed=proto/commands.proto");
return Ok(());
}
let has_protoc = std::env::var("PROTOC").is_ok();
let has_protoc_on_path = std::process::Command::new("protoc")
.arg("--version")
.output()
.map(|output| output.status.success())
.unwrap_or(false);
if files_exist && !regenerate_proto && !has_protoc && !has_protoc_on_path {
println!("cargo:warning=protoc not found, using pre-generated protobuf files");
println!("cargo:warning=If you modify proto files, install protoc: brew install protobuf");
println!("cargo:rerun-if-changed=proto/frame.proto");
println!("cargo:rerun-if-changed=proto/commands.proto");
return Ok(());
}
if regenerate_proto || has_protoc || has_protoc_on_path || !files_exist {
let mut config = prost_build::Config::new();
config.out_dir("src/common/protocol");
config.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]");
config.type_attribute(".", "#[serde(rename_all = \"snake_case\")]");
if let Err(e) = config.compile_protos(&["frame.proto", "commands.proto"], &["proto/"]) {
if files_exist {
println!(
"cargo:warning=protoc compilation failed: {}, using pre-generated files",
e
);
println!(
"cargo:warning=If you modify proto files, ensure protoc is installed: brew install protobuf"
);
} else {
return Err(std::io::Error::other(format!(
"Failed to compile protobuf files: {}. Please install protoc: brew install protobuf",
e
)));
}
}
}
if std::path::Path::new(flare_core_path).exists() {
let content = std::fs::read_to_string(flare_core_path)?;
let fixed_content = content
.replace(
"super::super::commands::Command",
"super::commands::Command",
)
.replace("commands::Command", "super::commands::Command");
if fixed_content != content {
std::fs::write(flare_core_path, fixed_content)?;
}
}
println!("cargo:rerun-if-changed=proto/frame.proto");
println!("cargo:rerun-if-changed=proto/commands.proto");
Ok(())
}