use serde::{Deserialize, Serialize};
use std::fmt;
const MAIN_BRANCH: &str = "main";
const MASTER_BRANCH: &str = "master";
const SHORT_COMMIT_LEN: usize = 7;
const GIT_BRANCH: &str = env!("GIT_BRANCH");
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct VersionInfo {
pub version: String,
pub git_commit: String,
pub git_branch: String,
pub build_time: String,
pub rust_version: String,
pub is_release: bool,
}
impl fmt::Display for VersionInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.full_version())
}
}
impl VersionInfo {
pub fn package_version(&self) -> &str {
&self.version
}
pub fn semver(&self) -> Option<crate::semver::Version> {
crate::semver::parse_version(&self.version)
}
pub fn matches_requirement(&self, requirement: &str) -> Option<bool> {
crate::semver::matches_requirement(&self.version, requirement)
}
pub fn short_git_commit(&self) -> Option<&str> {
if self.git_commit.is_empty() {
None
} else {
Some(short_commit(&self.git_commit))
}
}
pub fn short_version(&self) -> String {
self.short_git_commit().map_or_else(
|| self.version.clone(),
|commit| format!("{}-{commit}", self.version),
)
}
pub fn full_version(&self) -> String {
let mut parts = vec![self.version.clone()];
if let Some(commit) = self.short_git_commit() {
parts.push(commit.to_owned());
}
if !self.git_branch.is_empty()
&& self.git_branch != MAIN_BRANCH
&& self.git_branch != MASTER_BRANCH
{
parts.push(self.git_branch.clone());
}
let mut version = parts.join("-");
if !self.build_time.is_empty() {
use std::fmt::Write;
let _ = write!(version, " (built {})", self.build_time);
}
version
}
}
fn short_commit(commit: &str) -> &str {
commit
.char_indices()
.nth(SHORT_COMMIT_LEN)
.map_or(commit, |(idx, _)| &commit[..idx])
}
pub const fn package_version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
pub fn package_semver() -> Option<crate::semver::Version> {
crate::semver::parse_version(package_version())
}
pub fn get_version_info() -> VersionInfo {
let version = package_version().to_owned();
let git_commit = env!("GIT_COMMIT").to_owned();
let git_branch = if GIT_BRANCH.is_empty() {
String::new()
} else {
GIT_BRANCH.to_owned()
};
let build_time = env!("BUILD_EPOCH")
.parse::<i64>()
.ok()
.and_then(rskit_util::time::format_rfc3339)
.unwrap_or_default();
let rust_version = env!("RUST_VERSION_STR").to_owned();
let is_release = version != "dev" && !version.contains("dirty");
VersionInfo {
version,
git_commit,
git_branch,
build_time,
rust_version,
is_release,
}
}
pub fn get_short_version() -> String {
get_version_info().short_version()
}
pub fn get_full_version() -> String {
get_version_info().full_version()
}
pub fn is_release() -> bool {
get_version_info().is_release
}