diff --git a/Cargo.toml b/Cargo.toml index 4cbf57f..6352100 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [features] default = [] tracing = ["dep:const_format", "dep:tracing", "dep:tracing-appender", "dep:tracing-subscriber"] +version = ["dep:const_format"] [dependencies] const_format = { version = "0.2.32", optional = true } diff --git a/README.md b/README.md index cd3b48e..bb0bfdf 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,56 @@ list of features: | Feature | Description | | --------- | ----------------------------------------------- | | `tracing` | Tracing setup function with rolling log support | +| `version` | Standardized clap & tracing version messages | + +### Version + +To use the version feature, you will need the following `build.rs`: + +```rust +use vergen_git2::{CargoBuilder, Emitter, Git2Builder, RustcBuilder}; + +fn main() { + let cargo = CargoBuilder::all_cargo().unwrap(); + let git2 = Git2Builder::default().all().sha(true).build().unwrap(); + let rustc = RustcBuilder::all_rustc().unwrap(); + + Emitter::default() + .add_instructions(&cargo) + .unwrap() + .add_instructions(&rustc) + .unwrap() + .add_instructions(&git2) + .unwrap() + .emit() + .unwrap(); +} +``` + +The following clap derive: + +```rust +#[derive(Parser)] +#[command(version = toolbox::version!(), long_version = toolbox::long_version!())] +pub(crate) struct Args {} +``` + +Produces the following version outputs: + +`my-crate -V`: + +```txt +my-crate 2.0.0 (b142e42 2024-09-09T12:52:12.000000000Z) +``` + +`my-crate --version`: + +```txt +my-crate +Version: 2.0.0 (b142e42 2024-09-09T12:52:12.000000000Z) +Rustc Version: 1.86.0 +Rustc Host: x86_64-unknown-linux-gnu +Cargo Target: x86_64-unknown-linux-gnu + +feat: support message-pack encoding +``` diff --git a/src/lib.rs b/src/lib.rs index 195305e..ab185d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,4 @@ #[cfg(feature = "tracing")] pub mod tracing; +#[cfg(feature = "version")] +pub mod version; diff --git a/src/version.rs b/src/version.rs new file mode 100644 index 0000000..399e0bd --- /dev/null +++ b/src/version.rs @@ -0,0 +1,133 @@ +#[doc(hidden)] +pub use const_format::formatcp as __formatcp; + +// TODO: Can this just be rewritten as const functions? + +#[doc(hidden)] +#[macro_export] +macro_rules! __load_build_info { + () => { + const CARGO_PKG_VERSION: &str = match option_env!("CARGO_PKG_VERSION") { + Some(val) => val, + None => "", + }; + const GIT_SHA: &str = match option_env!("VERGEN_GIT_SHA") { + Some(val) => val, + None => "", + }; + const GIT_COMMIT_TIMESTAMP: &str = match option_env!("VERGEN_GIT_COMMIT_TIMESTAMP") { + Some(val) => val, + None => "", + }; + const GIT_COMMIT_MESSAGE: &str = match option_env!("VERGEN_GIT_COMMIT_MESSAGE") { + Some(val) => val, + None => "", + }; + const RUSTC_SEMVER: &str = match option_env!("VERGEN_RUSTC_SEMVER") { + Some(val) => val, + None => "", + }; + const RUSTC_HOST_TRIPLE: &str = match option_env!("VERGEN_RUSTC_HOST_TRIPLE") { + Some(val) => val, + None => "", + }; + const CARGO_TARGET_TRIPLE: &str = match option_env!("VERGEN_CARGO_TARGET_TRIPLE") { + Some(val) => val, + None => "", + }; + }; +} + +/// Version info for the current program. +/// +/// # Example +/// `my-crate 2.0.0 (b142e42 2024-09-09T12:52:12.000000000Z)` +#[macro_export] +macro_rules! version { + () => {{ + $crate::__load_build_info!(); + + $crate::version::__formatcp!("{} ({} {})", CARGO_PKG_VERSION, GIT_SHA, GIT_COMMIT_TIMESTAMP) + }}; +} + +/// Detailed version info for the current program. +/// +/// # Example +/// ```notrust +/// my-crate +/// Version: 2.0.0 (b142e42 2024-09-09T12:52:12.000000000Z) +/// Rustc Version: 1.86.0 +/// Rustc Host: x86_64-unknown-linux-gnu +/// Cargo Target: x86_64-unknown-linux-gnu +/// +/// feat: support message-pack encoding +/// ``` +#[macro_export] +macro_rules! long_version { + () => {{ + $crate::__load_build_info!(); + + $crate::version::__formatcp!( + r#" +Version: {} +Rustc Version: {RUSTC_SEMVER} +Rustc Host: {RUSTC_HOST_TRIPLE} +Cargo Target: {CARGO_TARGET_TRIPLE} + +{GIT_COMMIT_MESSAGE}"#, + $crate::version!(), + ) + }}; +} + +/// Log build info using [`tracing`]. +/// +/// The following values are logged if `vergen` has been run as part of the +/// project's build.rs: +/// +/// - `CARGO_PKG_VERSION` +/// - `GIT_SHA` +/// - `GIT_COMMIT_TIMESTAMP` +/// - `GIT_COMMIT_MESSAGE` +/// - `RUSTC_SEMVER` +/// - `RUSTC_HOST_TRIPLE` +/// - `CARGO_TARGET_TRIPLE` +#[macro_export] +macro_rules! log_build_info { + () => {{ + $crate::__load_build_info!(); + + $crate::version::_log_build_info( + CARGO_PKG_VERSION, + GIT_SHA, + GIT_COMMIT_TIMESTAMP, + GIT_COMMIT_MESSAGE, + RUSTC_SEMVER, + RUSTC_HOST_TRIPLE, + CARGO_TARGET_TRIPLE, + ) + }}; +} + +#[doc(hidden)] +pub fn _log_build_info( + cargo_pkg_version: &str, + git_sha: &str, + git_commit_timestamp: &str, + git_commit_message: &str, + rustc_semver: &str, + rustc_host_triple: &str, + cargo_target_triple: &str, +) { + tracing::info!( + cargo_pkg_version, + git_sha, + git_commit_timestamp, + git_commit_message, + rustc_semver, + rustc_host_triple, + cargo_target_triple, + "Build information" + ) +}