Skip to main content

tandem_server/util/
build.rs

1use std::time::UNIX_EPOCH;
2
3use serde::Serialize;
4
5pub fn build_id() -> String {
6    if let Some(explicit) = option_env!("TANDEM_BUILD_ID") {
7        let trimmed = explicit.trim();
8        if !trimmed.is_empty() {
9            return trimmed.to_string();
10        }
11    }
12    if let Some(git_sha) = option_env!("VERGEN_GIT_SHA") {
13        let trimmed = git_sha.trim();
14        if !trimmed.is_empty() {
15            return format!("{}+{}", env!("CARGO_PKG_VERSION"), trimmed);
16        }
17    }
18    env!("CARGO_PKG_VERSION").to_string()
19}
20
21pub fn git_sha() -> Option<String> {
22    option_env!("VERGEN_GIT_SHA")
23        .map(str::trim)
24        .filter(|value| !value.is_empty())
25        .map(str::to_string)
26}
27
28pub fn binary_path_for_health() -> Option<String> {
29    std::env::current_exe()
30        .ok()
31        .map(|p| p.to_string_lossy().to_string())
32}
33
34pub fn binary_modified_at_ms() -> Option<u64> {
35    let path = std::env::current_exe().ok()?;
36    let metadata = std::fs::metadata(path).ok()?;
37    let modified = metadata.modified().ok()?;
38    let duration = modified.duration_since(UNIX_EPOCH).ok()?;
39    u64::try_from(duration.as_millis()).ok()
40}
41
42#[derive(Debug, Clone, Serialize)]
43pub struct BuildProvenance {
44    pub version: String,
45    pub build_id: String,
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub git_sha: Option<String>,
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub binary_path: Option<String>,
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub binary_modified_at_ms: Option<u64>,
52}
53
54pub fn build_provenance() -> BuildProvenance {
55    BuildProvenance {
56        version: env!("CARGO_PKG_VERSION").to_string(),
57        build_id: build_id(),
58        git_sha: git_sha(),
59        binary_path: binary_path_for_health(),
60        binary_modified_at_ms: binary_modified_at_ms(),
61    }
62}