at ccc40f5
use chrono::{DateTime, Utc}; use miette::{Result, bail}; use serde::Deserialize; pub mod cargo; pub mod git; use cargo::{CargoVersion, CargoVersionConfig}; use git::{GitVersion, GitVersionConfig}; /// A version string paired with an optional release date. /// /// Returned by [`VersionExtractor::get_last_version`] and /// [`VersionExtractor::get_all_versions`] so that callers can propagate /// date information (e.g. to Atom feed entries) without a second round-trip. #[derive(Debug, Clone)] pub struct VersionInfo { /// The human-readable version string (e.g. `"1.2.3"`). pub version: String, /// The UTC date/time at which this version was released, if known. pub date: Option<DateTime<Utc>>, } #[allow(async_fn_in_trait)] pub trait VersionExtractor { type ConfigType: Default + for<'de> Deserialize<'de> + Clone; async fn get_last_version(&self, config: Self::ConfigType) -> Result<VersionInfo>; async fn get_all_versions(&self, _config: Self::ConfigType) -> Result<Vec<VersionInfo>> { bail!("get_all_versions is not supported by this version extractor") } } #[derive(Debug, Deserialize)] #[serde(tag = "type", rename_all = "snake_case")] pub enum AnyVersionExtractor { /// Reads the version from the `version` field in the `[package]` section /// of a `Cargo.toml` file. /// /// ```toml /// [version_extractor] /// type = "cargo" /// manifest_path = "Cargo.toml" # optional, defaults to ./Cargo.toml /// ``` Cargo(CargoVersionConfig), /// Derives the version from the most recent Git tag using /// `git describe --tags --always`. /// Supports stripping a tag prefix (e.g. `"v"`) and customising the /// suffix appended when the working tree has uncommitted changes. /// /// ```toml /// [version_extractor] /// type = "git" /// tag_prefix = "v" # optional, strips leading "v" /// dirty_suffix = "-dev" # optional, defaults to "-dirty" /// ``` Git(GitVersionConfig), } impl AnyVersionExtractor { pub async fn extract(&self) -> Result<VersionInfo> { match self { Self::Cargo(config) => CargoVersion.get_last_version(config.clone()).await, Self::Git(config) => GitVersion.get_last_version(config.clone()).await, } } pub async fn extract_all(&self) -> Result<Vec<VersionInfo>> { match self { Self::Cargo(config) => CargoVersion.get_all_versions(config.clone()).await, Self::Git(config) => GitVersion.get_all_versions(config.clone()).await, } } }