use std::env; fn main() -> Result<(), Box> { let rev = get_value_from_env("GIT_VERSION") .or_else(|| get_value_from_command("git", ["rev-parse", "--short", "HEAD"])) .unwrap_or_else(|| "unknown".to_owned()); let branch = get_value_from_env("GIT_BRANCH") .or_else(|| get_value_from_command("git", ["rev-parse", "--abbrev-ref", "HEAD"])) .unwrap_or_else(|| "unknown".to_owned()); println!("cargo:rustc-env=GIT_REVISION={}", rev); println!("cargo:rustc-env=GIT_BRANCH={}", branch); println!("cargo:rerun-if-env-changed=GIT_REVISION"); if let Ok(data) = std::fs::read_to_string(".env") { data.split('\n').for_each(|v| { let kv: Vec<&str> = v.split('=').collect(); if kv.len() != 2 { return; } let (key, value) = (kv[0], kv[1]); if key == "DATABASE_URL" { return; } println!("cargo:rustc-env={}={}", key, value); println!("cargo:rerun-if-env-changed={}", key); }) } Ok(()) } fn get_value_from_env(key: &str) -> Option { env::var(key).ok() } fn get_value_from_command, S: AsRef>( cmd: &str, args: I, ) -> Option { std::process::Command::new(cmd) .args(args) .output() .map_or_else( |_| None, |out| { if !out.status.success() { return None; } match std::str::from_utf8(&out.stdout) { Ok(value) => Some(value.to_owned()), Err(_) => None, } }, ) }