use serde::Deserialize;
use std::{
fs, io,
process::{Command, Stdio},
};
fn try_get_sha() -> Result<String, String> {
match fs::read_to_string(".cargo_vcs_info.json") {
Ok(vcs_json) => {
#[derive(Debug, Clone, Deserialize)]
struct VcsInfo {
git: VcsInfoGit,
}
#[derive(Debug, Clone, Deserialize)]
struct VcsInfoGit {
sha1: String,
}
let vcs_info = serde_json::from_str::<VcsInfo>(&vcs_json)
.map_err(|e| format!("Failed to parse .cargo_vcs_info.json: {}", e))?;
Ok(vcs_info.git.sha1)
}
Err(e) if e.kind() == io::ErrorKind::NotFound => {
let cmd = Command::new("git")
.stdin(Stdio::null())
.stderr(Stdio::inherit())
.stdout(Stdio::piped())
.args(&["rev-parse", "HEAD"])
.output()
.map_err(|e| format!("Unable to run git: {}", e))?;
if !cmd.status.success() {
return Err(format!("git rev-parse failed with {}", cmd.status));
}
let sha = std::str::from_utf8(&cmd.stdout)
.map_err(|e| format!("git output: {}", e))?
.trim();
Ok(sha.to_owned())
}
Err(e) => {
return Err(format!("Failed to read .cargo_vcs_info.json: {}", e));
}
}
}
fn main() -> Result<(), String> {
let short = &try_get_sha()?[0..10];
println!("cargo:rustc-env=GIT_SHA={}", short);
println!("cargo:rerun-if-changed=../.git");
Ok(())
}