use std::fmt;
use serde::Serialize;
#[derive(Serialize)]
pub(crate) struct CommitInfo {
pub(crate) short_commit_hash: String,
pub(crate) commit_hash: String,
pub(crate) commit_date: String,
pub(crate) last_tag: Option<String>,
pub(crate) commits_since_last_tag: u32,
}
#[derive(Serialize)]
pub(crate) struct VersionInfo {
pub(crate) version: String,
pub(crate) commit_info: Option<CommitInfo>,
}
impl fmt::Display for VersionInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.version)?;
if let Some(ref ci) = self.commit_info {
if ci.commits_since_last_tag > 0 {
write!(f, "+{}", ci.commits_since_last_tag)?;
}
write!(f, " ({} {})", ci.short_commit_hash, ci.commit_date)?;
}
Ok(())
}
}
impl From<VersionInfo> for clap::builder::Str {
fn from(val: VersionInfo) -> Self {
val.to_string().into()
}
}
pub fn version() -> VersionInfo {
macro_rules! option_env_str {
($name:expr) => {
option_env!($name).map(|s| s.to_string())
};
}
let version = env!("CARGO_PKG_VERSION").to_string();
let commit_info = option_env_str!("PREK_COMMIT_HASH").map(|commit_hash| CommitInfo {
short_commit_hash: option_env_str!("PREK_COMMIT_SHORT_HASH").unwrap(),
commit_hash,
commit_date: option_env_str!("PREK_COMMIT_DATE").unwrap(),
last_tag: option_env_str!("PREK_LAST_TAG"),
commits_since_last_tag: option_env_str!("PREK_LAST_TAG_DISTANCE")
.as_deref()
.map_or(0, |value| value.parse::<u32>().unwrap_or(0)),
});
VersionInfo {
version,
commit_info,
}
}