use std::{fs::read_to_string, path::Path, process::Command, str};
pub fn init() {
let _res = __init(&mut std::io::stdout(), &std::env::current_dir().unwrap());
}
fn __init(w: &mut impl std::io::Write, current_dir: &Path) -> std::io::Result<()> {
let mut git_sha: Option<String> = None;
if let Ok(vcs_info) = read_to_string(current_dir.join(".cargo_vcs_info.json")) {
let vcs_info: Result<CargoVcsInfo, _> = serde_json::from_str(&vcs_info);
if let Ok(vcs_info) = vcs_info {
git_sha = Some(vcs_info.git.sha1);
}
}
if git_sha.is_none() {
match Command::new("git")
.current_dir(current_dir)
.arg("rev-parse")
.arg("--git-dir")
.output()
.map(|o| o.stdout)
{
Err(e) => {
writeln!(
w,
"cargo:warning=Error getting git directory to get git revision: {e:?}"
)?;
}
Ok(git_dir) => {
let git_dir = String::from_utf8_lossy(&git_dir);
let git_dir = git_dir.trim();
writeln!(w, "cargo:rerun-if-changed={git_dir}/index")?;
writeln!(w, "cargo:rerun-if-changed={git_dir}/HEAD")?;
writeln!(w, "cargo:rerun-if-changed={git_dir}/refs")?;
match Command::new("git")
.current_dir(current_dir)
.arg("describe")
.arg("--always")
.arg("--exclude='*'")
.arg("--long")
.arg("--abbrev=1000")
.arg("--dirty")
.output()
.map(|o| o.stdout)
{
Err(e) => {
writeln!(
w,
"cargo:warning=Error getting git revision from {current_dir:?}: {e:?}"
)?;
}
Ok(git_describe) => {
git_sha = str::from_utf8(&git_describe).ok().map(str::to_string);
}
}
}
}
}
if let Some(git_sha) = git_sha {
writeln!(w, "cargo:rustc-env=GIT_REVISION={git_sha}")?;
}
Ok(())
}
#[derive(serde_derive::Serialize, serde_derive::Deserialize, Default)]
struct CargoVcsInfo {
git: CargoVcsInfoGit,
}
#[derive(serde_derive::Serialize, serde_derive::Deserialize, Default)]
struct CargoVcsInfoGit {
sha1: String,
}
mod test;