use std::io::Result; use std::process::Command; fn main() -> Result<()> { // Compile protobuf definitions prost_build::compile_protos(&["../proto/guruconnect.proto"], &["../proto/"])?; // Rerun if proto changes println!("cargo:rerun-if-changed=../proto/guruconnect.proto"); // Rerun if git HEAD changes (new commits) println!("cargo:rerun-if-changed=../.git/HEAD"); println!("cargo:rerun-if-changed=../.git/index"); // Build timestamp (UTC) let build_timestamp = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S UTC").to_string(); println!("cargo:rustc-env=BUILD_TIMESTAMP={}", build_timestamp); // Git commit hash (short) let git_hash = Command::new("git") .args(["rev-parse", "--short=8", "HEAD"]) .output() .ok() .and_then(|o| String::from_utf8(o.stdout).ok()) .map(|s| s.trim().to_string()) .unwrap_or_else(|| "unknown".to_string()); println!("cargo:rustc-env=GIT_HASH={}", git_hash); // Git commit hash (full) let git_hash_full = Command::new("git") .args(["rev-parse", "HEAD"]) .output() .ok() .and_then(|o| String::from_utf8(o.stdout).ok()) .map(|s| s.trim().to_string()) .unwrap_or_else(|| "unknown".to_string()); println!("cargo:rustc-env=GIT_HASH_FULL={}", git_hash_full); // Git branch name let git_branch = Command::new("git") .args(["rev-parse", "--abbrev-ref", "HEAD"]) .output() .ok() .and_then(|o| String::from_utf8(o.stdout).ok()) .map(|s| s.trim().to_string()) .unwrap_or_else(|| "unknown".to_string()); println!("cargo:rustc-env=GIT_BRANCH={}", git_branch); // Git dirty state (uncommitted changes) let git_dirty = Command::new("git") .args(["status", "--porcelain"]) .output() .ok() .map(|o| !o.stdout.is_empty()) .unwrap_or(false); println!("cargo:rustc-env=GIT_DIRTY={}", if git_dirty { "dirty" } else { "clean" }); // Git commit date let git_commit_date = Command::new("git") .args(["log", "-1", "--format=%ci"]) .output() .ok() .and_then(|o| String::from_utf8(o.stdout).ok()) .map(|s| s.trim().to_string()) .unwrap_or_else(|| "unknown".to_string()); println!("cargo:rustc-env=GIT_COMMIT_DATE={}", git_commit_date); // Build profile (debug/release) let profile = std::env::var("PROFILE").unwrap_or_else(|_| "unknown".to_string()); println!("cargo:rustc-env=BUILD_PROFILE={}", profile); // Target triple let target = std::env::var("TARGET").unwrap_or_else(|_| "unknown".to_string()); println!("cargo:rustc-env=BUILD_TARGET={}", target); // On Windows, embed the manifest for UAC elevation #[cfg(target_os = "windows")] { println!("cargo:rerun-if-changed=guruconnect.manifest"); let mut res = winres::WindowsResource::new(); res.set_manifest_file("guruconnect.manifest"); res.set("ProductName", "GuruConnect Agent"); res.set("FileDescription", "GuruConnect Remote Desktop Agent"); res.set("LegalCopyright", "Copyright (c) AZ Computer Guru"); res.set_icon("guruconnect.ico"); // Optional: add icon if available // Only compile if the manifest exists if std::path::Path::new("guruconnect.manifest").exists() { if let Err(e) = res.compile() { // Don't fail the build if resource compilation fails eprintln!("Warning: Failed to compile Windows resources: {}", e); } } } Ok(()) }