use std::process::Command;
use cargo_toml::Manifest;
fn main() {
let toml_contents = std::fs::read("Cargo.toml").expect("Failed to find Cargo.toml");
let manifest =
Manifest::from_slice(&toml_contents).expect("Failed to parse Cargo.toml as Manifest");
let curl_version = {
let curl = manifest
.dependencies
.get("curl")
.expect("Couldn't find curl in parsed manifest");
match curl {
cargo_toml::Dependency::Simple(ver) => ver,
cargo_toml::Dependency::Detailed(detail) => &detail.version.as_ref().unwrap().clone(),
cargo_toml::Dependency::Inherited(_) => {
panic!("Couldn't determine curl version since it appears as inherited.")
},
}
};
println!("cargo:rustc-env=CURL_VERSION={}", curl_version);
println!(
"cargo:rustc-env=TARGET={}",
std::env::var("TARGET").expect("Failed to obtain $TARGET triple constant.")
);
let build_script = std::env::var("OUT_DIR").unwrap();
write_command_to_file(&["cargo", "--version"], &(build_script.clone() + "/cargo_version.in"));
std::fs::write(build_script + "/git_revision.in", git_revision())
.expect("Failed to write git_revision.in");
}
fn git_revision() -> String {
println!("cargo:rerun-if-changed=.git/HEAD");
println!("cargo:rerun-if-changed=.git/index");
println!("cargo:rerun-if-changed=.cargo_vcs_info.json");
let from_git = Command::new("git")
.args(["rev-parse", "--verify", "HEAD"])
.output()
.ok()
.filter(|output| output.status.success())
.and_then(|output| String::from_utf8(output.stdout).ok())
.map(|sha| sha.trim().to_string())
.filter(|sha| !sha.is_empty());
let from_vcs_info = || {
let contents = std::fs::read_to_string(".cargo_vcs_info.json").ok()?;
let info: serde_json::Value = serde_json::from_str(&contents).ok()?;
info["git"]["sha1"].as_str().map(str::to_string)
};
from_git.or_else(from_vcs_info).unwrap_or_else(|| "unknown".to_string())
}
fn write_command_to_file(command: &[&str], file: &str) {
let full_command =
command.iter().fold(String::new(), |acc, argument| format!("{acc} {argument}"));
let output = {
let command =
Command::new(command.first().expect("command must have at leaste one element"))
.args(command.iter().skip(1))
.output()
.unwrap_or_else(|err| {
panic!("Couldn't run {full_command} because of: {err}");
})
.stdout;
String::from_utf8(command).unwrap_or_else(|err| {
panic!("failed to parse {full_command} output as string, because of {err}")
})
};
std::fs::write(file, output.trim())
.unwrap_or_else(|err| panic!("Failed to write to {file}: {err}"));
}