From 7a7dd3af487ad4e8f0d09362c9b76d5c52179136 Mon Sep 17 00:00:00 2001 From: Peter Goodspeed-Niklaus Date: Tue, 21 Oct 2025 21:14:25 +0200 Subject: [PATCH 1/2] feat: add version / build information This is just a nice little QOL feature for users of the program. Lets them know what version they're running, and the git status at build time. --- Cargo.lock | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 2 + build.rs | 21 +++++- src/main.rs | 40 ++++++++++- 4 files changed, 259 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5679893..b395f32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,9 +62,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "ascii-canvas" @@ -125,6 +125,7 @@ dependencies = [ "rustyline", "strum", "thiserror", + "vergen-gitcl", ] [[package]] @@ -196,6 +197,81 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "deranged" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn", +] + [[package]] name = "derive_more" version = "2.0.1" @@ -302,6 +378,12 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "futures-core" version = "0.3.31" @@ -383,6 +465,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "indexmap" version = "2.11.4" @@ -426,6 +514,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + [[package]] name = "lalrpop" version = "0.20.2" @@ -533,6 +627,12 @@ dependencies = [ "libc", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-runtime-fmt" version = "0.1.2" @@ -554,6 +654,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "once_cell" version = "1.20.2" @@ -620,6 +729,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "precomputed-hash" version = "0.1.1" @@ -771,9 +886,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rustyline" @@ -819,6 +934,15 @@ version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -945,6 +1069,39 @@ dependencies = [ "syn", ] +[[package]] +name = "time" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -1014,6 +1171,44 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "vergen" +version = "9.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b2bf58be11fc9414104c6d3a2e464163db5ef74b12296bda593cac37b6e4777" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", + "time", + "vergen-lib", +] + +[[package]] +name = "vergen-gitcl" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9dfc1de6eb2e08a4ddf152f1b179529638bedc0ea95e6d667c014506377aefe" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", + "time", + "vergen", + "vergen-lib", +] + +[[package]] +name = "vergen-lib" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b07e6010c0f3e59fcb164e0163834597da68d1f864e2b8ca49f74de01e9c166" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", +] + [[package]] name = "walkdir" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index 7ddcfc9..5333f7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ categories = [ "mathematics", ] keywords = ["calculator", "cli"] +build = "build.rs" [dependencies] anyhow = { version = "1.0.94", optional = true } @@ -28,6 +29,7 @@ thiserror = "1.0.69" [build-dependencies] lalrpop = "0.20.2" +vergen-gitcl = { version = "1.0.8", features = ["build"] } [features] default = ["cli"] diff --git a/build.rs b/build.rs index ca5c283..f586b8f 100644 --- a/build.rs +++ b/build.rs @@ -1,3 +1,22 @@ -fn main() { +use vergen_gitcl::{BuildBuilder, Emitter, GitclBuilder}; + +fn main() -> Result<(), Box> { + // regenerate lalrpop parser lalrpop::process_root().unwrap(); + + // gather build info + let build = BuildBuilder::default().build_timestamp(true).build()?; + let git = GitclBuilder::default() + .branch(true) + .sha(false) + .dirty(false) + .build()?; + + // emit build data into the build environment + Emitter::new() + .add_instructions(&build)? + .add_instructions(&git)? + .emit()?; + + Ok(()) } diff --git a/src/main.rs b/src/main.rs index 4e85bce..05b8ca1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,39 @@ -use anyhow::{bail, Result}; +use anyhow::{bail, Context as _, Result}; use calc::{Context, Error}; use clap::Parser; +const BIN_NAME: &str = env!("CARGO_BIN_NAME"); +const PKG_VERSION: &str = env!("CARGO_PKG_VERSION"); +const BUILD_TIMESTAMP: &str = env!("VERGEN_BUILD_TIMESTAMP"); +const GIT_BRANCH: &str = env!("VERGEN_GIT_BRANCH"); +const GIT_SHA: &str = env!("VERGEN_GIT_SHA"); +const GIT_DIRTY: &str = env!("VERGEN_GIT_DIRTY"); + +fn formatted_version_data() -> Result { + use std::fmt::Write; + + let dirty = if GIT_DIRTY == "true" { "(dirty)" } else { "" }; + + let mut out = String::new(); + writeln!(&mut out, "{BIN_NAME} v{PKG_VERSION}")?; + writeln!(&mut out)?; + writeln!( + &mut out, + "git branch: {GIT_BRANCH} @ {GIT_SHA} {dirty}" + )?; + writeln!(&mut out, "build timestamp: {BUILD_TIMESTAMP}")?; + + Ok(out) +} + #[derive(Debug, Parser)] -#[structopt(about)] struct Opt { /// Expression to evaluate expression: Vec, + + /// Emit version and build information. + #[arg(short = 'V', long)] + version: bool, } impl Opt { @@ -83,6 +110,15 @@ fn shell() -> Result<()> { fn main() -> Result<()> { let opt = Opt::parse(); + + if opt.version { + print!( + "{}", + formatted_version_data().context("failed to format version data")? + ); + return Ok(()); + } + if opt.expression.is_empty() { shell() } else { From f2d2ad020eb74f65e8ba4cee5dec0167735241eb Mon Sep 17 00:00:00 2001 From: Peter Goodspeed-Niklaus Date: Tue, 21 Oct 2025 21:19:15 +0200 Subject: [PATCH 2/2] chore: update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7990f0..0b3f0fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [0.5.0] - UNRELEASED Feat [#5](https://github.com/coriolinus/calc/issues/5): choose backing value type at evaluation time, not CLI +Feat [#25](https://github.com/coriolinus/calc/issues/25): add version/build info and `-V`/`--version` flags ## [0.4.0] - 2022-08-07