Skip to main content

thru_base/
version.rs

1//! Version string utilities for thru binaries.
2//!
3//! Provides a macro to generate version strings with git info.
4//! The macro must be used because env vars are resolved per-crate at compile time.
5
6/// Generate a version string with git info.
7///
8/// Returns format: "0.1.0+abc12345" for release builds, or
9/// "0.1.0-local+abc12345.dirty" for local dirty builds.
10///
11/// # Example
12/// ```ignore
13/// use thru_base::get_version;
14/// let version: &'static str = get_version!();
15/// ```
16#[macro_export]
17macro_rules! get_version {
18    () => {{
19        use std::sync::OnceLock;
20        static VERSION: OnceLock<&'static str> = OnceLock::new();
21
22        *VERSION.get_or_init(|| {
23            if let Some(version) = option_env!("THRU_BUILD_VERSION") {
24                return version;
25            }
26
27            let base = env!("CARGO_PKG_VERSION");
28            let sha = option_env!("VERGEN_GIT_SHA").unwrap_or("unknown");
29            let sha_short = if sha.len() > 8 { &sha[..8] } else { sha };
30            let dirty = option_env!("VERGEN_GIT_DIRTY") == Some("true");
31            let describe = option_env!("VERGEN_GIT_DESCRIBE").unwrap_or("");
32            let release_tag = format!("v{}", base);
33            let inferred_release = !dirty && (describe == base || describe == release_tag);
34            let release = match option_env!("THRU_BUILD_CHANNEL") {
35                Some("release") => true,
36                Some("local") => false,
37                _ => inferred_release,
38            };
39            let local_suffix = if release { "" } else { "-local" };
40            let dirty_suffix = if dirty { ".dirty" } else { "" };
41            let version = format!("{}{}+{}{}", base, local_suffix, sha_short, dirty_suffix);
42            Box::leak(version.into_boxed_str())
43        })
44    }};
45}