diff --git a/crates/irtt-app/Cargo.toml b/crates/irtt-app/Cargo.toml index 2ffafa7..69dc6e2 100644 --- a/crates/irtt-app/Cargo.toml +++ b/crates/irtt-app/Cargo.toml @@ -43,7 +43,7 @@ doc = false [features] default = ["client", "server", "tui"] client = ["dep:humantime", "dep:tokio", "dep:irtt-client", "irtt-client/ancillary", "irtt-client/tokio", "dep:irtt-proto", "dep:irtt-stats"] -server = ["dep:irtt-server", "dep:tokio"] +server = ["dep:irtt-server", "dep:irtt-proto", "dep:tokio"] tui =["dep:humantime", "dep:tokio", "dep:futures-core", "dep:irtt-client", "irtt-client/ancillary", "irtt-client/tokio", "dep:irtt-proto", "dep:irtt-stats", "dep:ratatui", "dep:crossterm", "dep:chrono"] [dependencies] diff --git a/crates/irtt-app/src/applet.rs b/crates/irtt-app/src/applet.rs index c797019..a657802 100644 --- a/crates/irtt-app/src/applet.rs +++ b/crates/irtt-app/src/applet.rs @@ -55,10 +55,7 @@ pub fn dispatch_from_argv(argv: Vec) -> Result }; match command { - "-V" | "--version" => Ok(AppletDispatch::Help(format!( - "irtt-rs {}", - env!("CARGO_PKG_VERSION") - ))), + "-V" | "--version" => Ok(AppletDispatch::Help(crate::version::app())), "-h" | "--help" => Ok(AppletDispatch::Help(dispatcher_help())), "client" => Ok(AppletDispatch::Run { applet: RequestedApplet::Client, diff --git a/crates/irtt-app/src/entry.rs b/crates/irtt-app/src/entry.rs index 6ec1f8a..771948a 100644 --- a/crates/irtt-app/src/entry.rs +++ b/crates/irtt-app/src/entry.rs @@ -89,11 +89,10 @@ fn with_shutdown_flag( #[cfg(feature = "client")] fn run_client_applet(argv: Vec) -> Result<(), Box> { - use clap::Parser; - let shutdown = crate::signal::install_async_signal_handler() .map_err(|err| format!("failed to install signal handler: {err}"))?; - let args = crate::cmd::client::ClientArgs::parse_from(argv); + let args = + crate::version::parse::(argv, crate::version::client); tokio::runtime::Builder::new_current_thread() .enable_all() .build()? @@ -107,10 +106,9 @@ fn run_client_applet(_argv: Vec) -> Result<(), Box) -> Result<(), Box> { - use clap::Parser; - with_shutdown_flag(|shutdown_requested| { - let args = crate::cmd::server::ServerArgs::parse_from(argv); + let args = + crate::version::parse::(argv, crate::version::server); crate::cmd::server::run_server(args, shutdown_requested) }) } @@ -122,11 +120,9 @@ fn run_server_applet(_argv: Vec) -> Result<(), Box) -> Result<(), Box> { - use clap::Parser; - let shutdown = crate::signal::install_async_signal_handler() .map_err(|err| format!("failed to install signal handler: {err}"))?; - let args = crate::cmd::tui::TuiArgs::parse_from(argv); + let args = crate::version::parse::(argv, crate::version::client); tokio::runtime::Builder::new_current_thread() .enable_all() .build()? diff --git a/crates/irtt-app/src/lib.rs b/crates/irtt-app/src/lib.rs index 03debfc..8b82454 100644 --- a/crates/irtt-app/src/lib.rs +++ b/crates/irtt-app/src/lib.rs @@ -6,3 +6,5 @@ pub mod cmd; pub mod entry; pub mod shared; pub mod signal; + +mod version; diff --git a/crates/irtt-app/src/version.rs b/crates/irtt-app/src/version.rs new file mode 100644 index 0000000..ae2063d --- /dev/null +++ b/crates/irtt-app/src/version.rs @@ -0,0 +1,40 @@ +#[cfg(any(feature = "client", feature = "tui", feature = "server"))] +use std::ffi::OsString; + +pub(crate) fn app() -> String { + clap::Command::new("irtt-rs") + .version(env!("CARGO_PKG_VERSION")) + .render_version() +} + +// Preserve Clap's version banner and append the compiled component versions. +#[cfg(any(feature = "client", feature = "tui", feature = "server"))] +pub(crate) fn parse(argv: Vec, report: fn() -> String) -> T { + match T::try_parse_from(argv) { + Ok(args) => args, + Err(err) if err.kind() == clap::error::ErrorKind::DisplayVersion => { + print!("{}{}", err.render().ansi(), report()); + std::process::exit(0) + } + Err(err) => err.exit(), + } +} + +#[cfg(any(feature = "client", feature = "tui"))] +pub(crate) fn client() -> String { + format!( + " client: {}\n stats: {}\n proto: {}\n", + irtt_client::VERSION, + irtt_stats::VERSION, + irtt_proto::VERSION, + ) +} + +#[cfg(feature = "server")] +pub(crate) fn server() -> String { + format!( + " server: {}\n proto: {}\n", + irtt_server::VERSION, + irtt_proto::VERSION, + ) +} diff --git a/crates/irtt-client/src/lib.rs b/crates/irtt-client/src/lib.rs index b9b1d05..8d513cd 100644 --- a/crates/irtt-client/src/lib.rs +++ b/crates/irtt-client/src/lib.rs @@ -47,6 +47,9 @@ //! #![forbid(unsafe_code)] +/// Cargo package version of this compiled library. +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); + #[cfg(feature = "tokio")] mod async_client; mod auth; diff --git a/crates/irtt-proto/src/lib.rs b/crates/irtt-proto/src/lib.rs index d100953..c0416ff 100644 --- a/crates/irtt-proto/src/lib.rs +++ b/crates/irtt-proto/src/lib.rs @@ -77,6 +77,9 @@ //! #![forbid(unsafe_code)] +/// Cargo package version of this compiled library. +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); + pub mod echo; mod envelope; pub mod error; diff --git a/crates/irtt-server/src/lib.rs b/crates/irtt-server/src/lib.rs index a9f568d..524a18e 100644 --- a/crates/irtt-server/src/lib.rs +++ b/crates/irtt-server/src/lib.rs @@ -108,6 +108,9 @@ //! payload bytes never reach a reply under any mode. #![forbid(unsafe_code)] +/// Cargo package version of this compiled library. +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); + mod clock; mod config; mod core; diff --git a/crates/irtt-stats/src/lib.rs b/crates/irtt-stats/src/lib.rs index b5a6742..a9caf20 100644 --- a/crates/irtt-stats/src/lib.rs +++ b/crates/irtt-stats/src/lib.rs @@ -25,6 +25,9 @@ #![warn(missing_docs)] #![warn(rustdoc::missing_crate_level_docs)] +/// Cargo package version of this compiled library. +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); + use std::time::Duration; use irtt_client::ClientEvent;