feat: embed git SHA in version string #110
48
build.rs
Normal file
48
build.rs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
fn main() {
|
||||||
|
// --long forces "TAG-N-gSHA[-dirty]" format even on exact tag matches,
|
||||||
|
// making parsing unambiguous for pre-release tags like v0.14.0-rc1.
|
||||||
|
let git_version = std::process::Command::new("git")
|
||||||
|
.args(["describe", "--tags", "--always", "--dirty", "--long"])
|
||||||
|
.output()
|
||||||
|
.ok()
|
||||||
|
.filter(|o| o.status.success())
|
||||||
|
.and_then(|o| String::from_utf8(o.stdout).ok())
|
||||||
|
.and_then(|raw| parse_git_describe(raw.trim()));
|
||||||
|
|
||||||
|
if let Some(v) = git_version {
|
||||||
|
println!("cargo:rustc-env=NUMA_BUILD_VERSION={}", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("cargo:rerun-if-changed=.git/HEAD");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse `git describe --long` output into a SemVer-compatible string.
|
||||||
|
/// "v0.13.1-0-ga87f907" → "0.13.1"
|
||||||
|
/// "v0.13.1-9-ga87f907" → "0.13.1+a87f907"
|
||||||
|
/// "v0.14.0-rc1-0-ga87f907" → "0.14.0-rc1"
|
||||||
|
/// "v0.14.0-rc1-3-ga87f907-dirty" → "0.14.0-rc1+a87f907-dirty"
|
||||||
|
/// "a87f907" → "0.0.0+a87f907"
|
||||||
|
fn parse_git_describe(s: &str) -> Option<String> {
|
||||||
|
let s = s.strip_prefix('v').unwrap_or(s);
|
||||||
|
let dirty = s.ends_with("-dirty");
|
||||||
|
let s = s.strip_suffix("-dirty").unwrap_or(s);
|
||||||
|
|
||||||
|
// --long format: TAG-N-gSHA. Split from the right so tags with hyphens work.
|
||||||
|
let gpos = s.rfind("-g")?;
|
||||||
|
let sha = &s[gpos + 2..];
|
||||||
|
let rest = &s[..gpos];
|
||||||
|
let npos = rest.rfind('-')?;
|
||||||
|
let n: u32 = rest[npos + 1..].parse().ok()?;
|
||||||
|
let tag = &rest[..npos];
|
||||||
|
|
||||||
|
if tag.is_empty() {
|
||||||
|
return Some(format!("0.0.0+{}", sha));
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(match (n, dirty) {
|
||||||
|
(0, false) => tag.to_string(),
|
||||||
|
(0, true) => format!("{}+{}-dirty", tag, sha),
|
||||||
|
(_, false) => format!("{}+{}", tag, sha),
|
||||||
|
(_, true) => format!("{}+{}-dirty", tag, sha),
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -540,7 +540,7 @@ async fn stats(State(ctx): State<Arc<ServerCtx>>) -> Json<StatsResponse> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Json(StatsResponse {
|
Json(StatsResponse {
|
||||||
version: env!("CARGO_PKG_VERSION"),
|
version: crate::version(),
|
||||||
uptime_secs: snap.uptime_secs,
|
uptime_secs: snap.uptime_secs,
|
||||||
upstream,
|
upstream,
|
||||||
mode: ctx.upstream_mode.as_str(),
|
mode: ctx.upstream_mode.as_str(),
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ impl HealthMeta {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn test_fixture() -> Self {
|
pub fn test_fixture() -> Self {
|
||||||
HealthMeta {
|
HealthMeta {
|
||||||
version: env!("CARGO_PKG_VERSION"),
|
version: crate::version(),
|
||||||
hostname: "test-host".to_string(),
|
hostname: "test-host".to_string(),
|
||||||
sni: "numa.numa".to_string(),
|
sni: "numa.numa".to_string(),
|
||||||
dot_enabled: false,
|
dot_enabled: false,
|
||||||
@@ -99,7 +99,7 @@ impl HealthMeta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HealthMeta {
|
HealthMeta {
|
||||||
version: env!("CARGO_PKG_VERSION"),
|
version: crate::version(),
|
||||||
hostname: crate::hostname(),
|
hostname: crate::hostname(),
|
||||||
sni: "numa.numa".to_string(),
|
sni: "numa.numa".to_string(),
|
||||||
dot_enabled,
|
dot_enabled,
|
||||||
|
|||||||
@@ -34,6 +34,14 @@ pub(crate) mod testutil;
|
|||||||
pub type Error = Box<dyn std::error::Error + Send + Sync>;
|
pub type Error = Box<dyn std::error::Error + Send + Sync>;
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
/// Build version string. On tagged releases: `0.13.1`. On commits ahead
|
||||||
|
/// of a tag: `0.13.1+a87f907`. With uncommitted changes: `0.13.1+a87f907-dirty`.
|
||||||
|
/// Falls back to `CARGO_PKG_VERSION` when built outside a git repo (e.g.
|
||||||
|
/// from a source tarball).
|
||||||
|
pub fn version() -> &'static str {
|
||||||
|
option_env!("NUMA_BUILD_VERSION").unwrap_or(env!("CARGO_PKG_VERSION"))
|
||||||
|
}
|
||||||
|
|
||||||
/// Detect the machine hostname via the `hostname` command. Returns the
|
/// Detect the machine hostname via the `hostname` command. Returns the
|
||||||
/// full hostname (e.g., `macbook-pro.local`), or `"numa"` if the command
|
/// full hostname (e.g., `macbook-pro.local`), or `"numa"` if the command
|
||||||
/// fails. Call sites that need the short form (e.g., mDNS instance
|
/// fails. Call sites that need the short form (e.g., mDNS instance
|
||||||
|
|||||||
10
src/main.rs
10
src/main.rs
@@ -72,7 +72,7 @@ async fn main() -> numa::Result<()> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
"version" | "--version" | "-V" => {
|
"version" | "--version" | "-V" => {
|
||||||
eprintln!("numa {}", env!("CARGO_PKG_VERSION"));
|
eprintln!("numa {}", numa::version());
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
"help" | "--help" | "-h" => {
|
"help" | "--help" | "-h" => {
|
||||||
@@ -383,12 +383,10 @@ async fn main() -> numa::Result<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Title row: center within the box
|
// Title row: center within the box
|
||||||
let title = format!(
|
let ver = numa::version();
|
||||||
"{b}NUMA{r} {it}DNS that governs itself{r} {d}v{}{r}",
|
let title = format!("{b}NUMA{r} {it}DNS that governs itself{r} {d}v{ver}{r}",);
|
||||||
env!("CARGO_PKG_VERSION")
|
|
||||||
);
|
|
||||||
// The title contains ANSI codes; visible length is ~38 chars. Pad to fill the box.
|
// The title contains ANSI codes; visible length is ~38 chars. Pad to fill the box.
|
||||||
let title_visible_len = 4 + 2 + 24 + 2 + 1 + env!("CARGO_PKG_VERSION").len() + 1;
|
let title_visible_len = 4 + 2 + 24 + 2 + 1 + ver.len() + 1;
|
||||||
let title_pad = w.saturating_sub(title_visible_len);
|
let title_pad = w.saturating_sub(title_visible_len);
|
||||||
eprintln!("\n{o} ╔{bar_top}╗{r}");
|
eprintln!("\n{o} ╔{bar_top}╗{r}");
|
||||||
eprint!("{o} ║{r} {title}");
|
eprint!("{o} ║{r} {title}");
|
||||||
|
|||||||
Reference in New Issue
Block a user