diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..e7044b3 --- /dev/null +++ b/build.rs @@ -0,0 +1,22 @@ +use std::process::Command; + +fn main() { + println!("cargo:rerun-if-changed=.git/HEAD"); + if let Ok(head) = std::fs::read_to_string(".git/HEAD") { + if let Some(reference) = head.strip_prefix("ref: ") { + println!("cargo:rerun-if-changed=.git/{}", reference.trim()); + } + } + + let short = Command::new("git") + .args(["rev-parse", "--short=8", "HEAD"]) + .output() + .ok() + .filter(|output| output.status.success()) + .and_then(|output| String::from_utf8(output.stdout).ok()) + .map(|value| value.trim().to_string()) + .filter(|value| !value.is_empty()) + .unwrap_or_else(|| "unknown".to_string()); + + println!("cargo:rustc-env=PEERSPEAK_GIT_SHORT={short}"); +} diff --git a/src/app/mod.rs b/src/app/mod.rs index ef6f6c6..3c704f4 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -34,6 +34,17 @@ use tokio::sync::Mutex; static UI_RX: OnceLock>>> = OnceLock::new(); +const APP_VERSION: &str = env!("CARGO_PKG_VERSION"); +const GIT_SHORT: &str = env!("PEERSPEAK_GIT_SHORT"); + +fn app_build_label() -> String { + if GIT_SHORT == "unknown" { + format!("PeerSpeak v{APP_VERSION}") + } else { + format!("PeerSpeak v{APP_VERSION} ({GIT_SHORT})") + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Screen { Home, @@ -1100,10 +1111,7 @@ fn effective_background_bytes( } pub fn run_gui() -> iced::Result { - crate::log_msg(&format!( - "PeerSpeak v{} starting", - env!("CARGO_PKG_VERSION") - )); + crate::log_msg(&format!("{} starting", app_build_label())); // Restore the last window size (saved on close). Position is restored too, // but only on X11 — Wayland's xdg-shell gives clients no way to set their own // position, so we center there and leave placement to the compositor. @@ -3810,6 +3818,7 @@ fn connect_card(state: &AppState) -> Element<'_, AppMessage> { let subtitle = text("NAT-traversing full-mesh voice chat") .size(16) .color(color_subtext); + let build_label = text(app_build_label()).size(11).color(color_subtext); let nickname_input = column![ text("Nickname").size(14).color(color_subtext), @@ -3865,6 +3874,7 @@ fn connect_card(state: &AppState) -> Element<'_, AppMessage> { column![ logo, subtitle, + build_label, vertical_space(20.0), nickname_input, vertical_space(16.0), @@ -5246,11 +5256,7 @@ fn view(state: &AppState) -> Element<'_, AppMessage> { } settings_nav = settings_nav .push(iced::widget::Space::new().height(iced::Length::Fill)) - .push( - text(format!("PeerSpeak v{}", env!("CARGO_PKG_VERSION"))) - .size(11) - .color(color_subtext), - ); + .push(text(app_build_label()).size(11).color(color_subtext)); let settings_nav = container(settings_nav) .padding(12) .width(iced::Length::Fixed(220.0)) @@ -5270,9 +5276,7 @@ fn view(state: &AppState) -> Element<'_, AppMessage> { vertical_space(10.0), settings_body, vertical_space(10.0), - text(format!("PeerSpeak v{}", env!("CARGO_PKG_VERSION"))) - .size(11) - .color(color_subtext), + text(app_build_label()).size(11).color(color_subtext), ] .spacing(8) .width(iced::Length::Fill),