refactor: Move git version info gather in into a build script

This commit is contained in:
Jade Ellis 2025-05-01 00:38:35 +01:00
parent e1655edd83
commit a98da7d942
No known key found for this signature in database
GPG key ID: 8705A2A3EBF77BD2
14 changed files with 231 additions and 123 deletions

View file

@ -143,7 +143,10 @@ pub(crate) async fn get_message_events_route(
if let Some(registration) = body.appservice_info.as_ref() {
<&DeviceId>::from(registration.registration.id.as_str())
} else {
panic!("No device_id provided and no appservice registration found, this should be unreachable");
panic!(
"No device_id provided and no appservice registration found, this \
should be unreachable"
);
},
},
room_id,

View file

@ -0,0 +1,34 @@
[package]
name = "conduwuit_build_metadata"
categories.workspace = true
description.workspace = true
edition.workspace = true
keywords.workspace = true
license.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
build = "build.rs"
# [[bin]]
# path = "main.rs"
# name = "conduwuit_build_metadata"
[lib]
path = "mod.rs"
crate-type = [
"rlib",
# "dylib",
]
[features]
[dependencies]
[build-dependencies]
built = {version = "0.7", features = ["cargo-lock", "dependency-tree"]}
[lints]
workspace = true

View file

@ -0,0 +1,92 @@
use std::process::Command;
fn run_git_command(args: &[&str]) -> Option<String> {
Command::new("git")
.args(args)
.output()
.ok()
.filter(|output| output.status.success())
.and_then(|output| String::from_utf8(output.stdout).ok())
.map(|s| s.trim().to_owned())
.filter(|s| !s.is_empty())
}
fn get_env(env_var: &str) -> Option<String> {
match std::env::var(env_var) {
| Ok(val) if !val.is_empty() => Some(val),
| _ => None,
}
}
fn main() {
// built gets the default crate from the workspace. Not sure if this is intended
// behavior, but it's what we want.
built::write_built_file().expect("Failed to acquire build-time information");
// --- Git Information ---
let mut commit_hash = None;
let mut commit_hash_short = None;
let mut remote_url_web = None;
// Get full commit hash
if let Some(hash) =
get_env("GIT_COMMIT_HASH").or_else(|| run_git_command(&["rev-parse", "HEAD"]))
{
println!("cargo:rustc-env=GIT_COMMIT_HASH={hash}");
commit_hash = Some(hash);
}
// Get short commit hash
if let Some(short_hash) = get_env("GIT_COMMIT_HASH_SHORT")
.or_else(|| run_git_command(&["rev-parse", "--short", "HEAD"]))
{
println!("cargo:rustc-env=GIT_COMMIT_HASH_SHORT={short_hash}");
commit_hash_short = Some(short_hash);
}
// Get remote URL and convert to web URL
if let Some(remote_url_raw) = get_env("GIT_REMOTE_URL")
.or_else(|| run_git_command(&["config", "--get", "remote.origin.url"]))
{
println!("cargo:rustc-env=GIT_REMOTE_URL={remote_url_raw}");
let web_url = if remote_url_raw.starts_with("https://") {
remote_url_raw.trim_end_matches(".git").to_owned()
} else if remote_url_raw.starts_with("git@") {
remote_url_raw
.trim_end_matches(".git")
.replacen(':', "/", 1)
.replacen("git@", "https://", 1)
} else if remote_url_raw.starts_with("ssh://") {
remote_url_raw
.trim_end_matches(".git")
.replacen("git@", "", 1)
.replacen("ssh:", "https:", 1)
} else {
// Assume it's already a web URL or unknown format
remote_url_raw
};
println!("cargo:rustc-env=GIT_REMOTE_WEB_URL={web_url}");
remote_url_web = Some(web_url);
}
// Construct remote commit URL
if let Some(remote_commit_url) = get_env("GIT_REMOTE_COMMIT_URL") {
println!("cargo:rustc-env=GIT_REMOTE_COMMIT_URL={remote_commit_url}");
} else if let (Some(base_url), Some(hash)) =
(&remote_url_web, commit_hash.as_ref().or(commit_hash_short.as_ref()))
{
let commit_page = format!("{base_url}/commit/{hash}");
println!("cargo:rustc-env=GIT_REMOTE_COMMIT_URL={commit_page}");
}
// --- Rerun Triggers ---
// Rerun if the git HEAD changes
println!("cargo:rerun-if-changed=.git/HEAD");
// Rerun if the ref pointed to by HEAD changes (e.g., new commit on branch)
if let Some(ref_path) = run_git_command(&["symbolic-ref", "--quiet", "HEAD"]) {
println!("cargo:rerun-if-changed=.git/{ref_path}");
}
println!("cargo:rerun-if-env-changed=GIT_COMMIT_HASH");
println!("cargo:rerun-if-env-changed=GIT_COMMIT_HASH_SHORT");
println!("cargo:rerun-if-env-changed=GIT_REMOTE_URL");
println!("cargo:rerun-if-env-changed=GIT_REMOTE_COMMIT_URL");
}

23
src/build_metadata/mod.rs Normal file
View file

@ -0,0 +1,23 @@
pub mod built {
include!(concat!(env!("OUT_DIR"), "/built.rs"));
}
pub static GIT_COMMIT_HASH: Option<&str> = option_env!("GIT_COMMIT_HASH");
pub static GIT_COMMIT_HASH_SHORT: Option<&str> = option_env!("GIT_COMMIT_HASH_SHORT");
// this would be a lot better if Option::or was const.
pub static VERSION_EXTRA: Option<&str> =
if let v @ Some(_) = option_env!("CONTINUWUITY_VERSION_EXTRA") {
v
} else if let v @ Some(_) = option_env!("CONDUWUIT_VERSION_EXTRA") {
v
} else if let v @ Some(_) = option_env!("CONDUIT_VERSION_EXTRA") {
v
} else {
GIT_COMMIT_HASH_SHORT
};
pub static GIT_REMOTE_WEB_URL: Option<&str> = option_env!("GIT_REMOTE_WEB_URL");
pub static GIT_REMOTE_COMMIT_URL: Option<&str> = option_env!("GIT_REMOTE_COMMIT_URL");
// TODO: Mark dirty builds within the version string

View file

@ -67,6 +67,7 @@ checked_ops.workspace = true
chrono.workspace = true
clap.workspace = true
conduwuit-macros.workspace = true
conduwuit-build-metadata.workspace = true
const-str.workspace = true
core_affinity.workspace = true
ctor.workspace = true

View file

@ -26,13 +26,6 @@ pub fn user_agent() -> &'static str { USER_AGENT.get_or_init(init_user_agent) }
fn init_user_agent() -> String { format!("{}/{}", name(), version()) }
fn init_version() -> String {
option_env!("CONDUWUIT_VERSION_EXTRA")
.or(option_env!("CONDUIT_VERSION_EXTRA"))
.map_or(SEMANTIC.to_owned(), |extra| {
if extra.is_empty() {
SEMANTIC.to_owned()
} else {
format!("{SEMANTIC} ({extra})")
}
})
conduwuit_build_metadata::VERSION_EXTRA
.map_or(SEMANTIC.to_owned(), |extra| format!("{SEMANTIC} ({extra})"))
}

View file

@ -20,6 +20,8 @@ crate-type = [
[dependencies]
conduwuit-build-metadata.workspace = true
askama = "0.14.0"
axum.workspace = true

View file

@ -5,6 +5,7 @@ use axum::{
response::{Html, IntoResponse, Response},
routing::get,
};
use conduwuit_build_metadata::{GIT_REMOTE_COMMIT_URL, GIT_REMOTE_WEB_URL, VERSION_EXTRA};
pub fn build<S>() -> Router<()> { Router::new().route("/", get(index_handler)) }

View file

@ -18,8 +18,8 @@
{%~ block footer ~%}
<footer>
<p>Powered by <a href="https://continuwuity.org">Continuwuity</a>
{%~ if let Some(version_info) = option_env!("CONDUWUIT_VERSION_EXTRA").or(option_env!("SHORT_COMMIT_SHA")) ~%}
{%~ if let Some(url) = option_env!("REMOTE_COMMIT_URL").or(option_env!("REMOTE_URL")) ~%}
{%~ if let Some(version_info) = VERSION_EXTRA ~%}
{%~ if let Some(url) = GIT_REMOTE_COMMIT_URL.or(GIT_REMOTE_WEB_URL) ~%}
(<a href="{{ url }}">{{ version_info }}</a>)
{%~ else ~%}
({{ version_info }})