From afe07f0b9ae43e3fcaeebd3c9c66b01fcf22adfe Mon Sep 17 00:00:00 2001 From: Nils Andreas Svee Date: Wed, 10 Jun 2026 15:19:34 +0700 Subject: [PATCH] refactor(cli): reorganize feature flags and update distribution config --- README.md | 4 ++ crates/irtt-cli/Cargo.toml | 8 ++-- crates/irtt-cli/src/cmd/tui/args.rs | 65 ++++++++++++++++++++--------- crates/irtt-cli/src/shared/mod.rs | 2 +- dist-workspace.toml | 2 +- 5 files changed, 57 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index f033e2d..3a7c3a2 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,10 @@ only `irtt-rs` and symlink or hardlink applet names such as `irtt-cli`, `irtt-tui`, and future server applet names to it. Applet dispatch is based on the invoked binary name. +cargo-dist release archives currently bundle all enabled applets for a target. +That is separate from space-sensitive package layouts, which may still ship one +binary plus applet-name symlinks or hardlinks. + ## CLI usage Basic test: diff --git a/crates/irtt-cli/Cargo.toml b/crates/irtt-cli/Cargo.toml index 6fea810..6479554 100644 --- a/crates/irtt-cli/Cargo.toml +++ b/crates/irtt-cli/Cargo.toml @@ -30,9 +30,11 @@ required-features = ["tui"] [features] default = ["client", "stats"] -client = ["dep:irtt-client", "dep:irtt-proto"] -stats = ["client", "dep:irtt-stats"] -tui = ["client", "stats", "dep:ratatui", "dep:crossterm"] +client-runtime = ["dep:irtt-client", "dep:irtt-proto"] +client = ["client-runtime"] +stats = ["client-runtime", "dep:irtt-stats"] +tui = ["client-runtime", "stats", "dep:ratatui", "dep:crossterm"] +full = ["client", "stats", "tui"] [dependencies] clap = { version = "4.6.1", features = ["derive"] } diff --git a/crates/irtt-cli/src/cmd/tui/args.rs b/crates/irtt-cli/src/cmd/tui/args.rs index b6937cc..e226628 100644 --- a/crates/irtt-cli/src/cmd/tui/args.rs +++ b/crates/irtt-cli/src/cmd/tui/args.rs @@ -54,19 +54,24 @@ impl std::ops::Deref for TuiArgs { #[cfg(test)] mod tests { use super::*; - use crate::cmd::client::ClientArgs; use clap::{CommandFactory, Parser}; + #[derive(Parser)] + struct SharedOnlyArgs { + #[command(flatten)] + common: CommonClientArgs, + } + fn parse(args: &[&str]) -> Result { let mut argv = vec!["irtt-tui"]; argv.extend_from_slice(args); TuiArgs::try_parse_from(argv) } - fn parse_client(args: &[&str]) -> Result { - let mut argv = vec!["irtt-cli"]; + fn parse_shared(args: &[&str]) -> Result { + let mut argv = vec!["shared-only"]; argv.extend_from_slice(args); - ClientArgs::try_parse_from(argv) + SharedOnlyArgs::try_parse_from(argv) } #[test] @@ -90,8 +95,29 @@ mod tests { } #[test] - fn shared_client_options_match_between_stream_and_tui_parsers() { + fn shared_client_options_match_tui_config_mapping() { let shared = [ + "--interval", + "250ms", + "--length", + "128", + "--hmac", + "secret", + "--clock", + "monotonic", + "--tstamp", + "receive", + "--stats", + "count", + "--sfill", + "abc", + "--dscp", + "46", + "--ttl", + "64", + "--loose", + ]; + let tui_args = [ "--duration", "30s", "--interval", @@ -115,20 +141,21 @@ mod tests { "--loose", "127.0.0.1:2112", ]; - let client = parse_client(&shared).unwrap().to_client_config(); - let tui = parse(&shared).unwrap().to_client_config(); + let tui = parse(&tui_args).unwrap().to_client_config(); + let common = parse_shared(&shared).unwrap().common; + let shared = common.to_client_config("127.0.0.1:2112", Duration::from_secs(30)); - assert_eq!(client.server_addr, tui.server_addr); - assert_eq!(client.duration, tui.duration); - assert_eq!(client.interval, tui.interval); - assert_eq!(client.length, tui.length); - assert_eq!(client.received_stats, tui.received_stats); - assert_eq!(client.stamp_at, tui.stamp_at); - assert_eq!(client.clock, tui.clock); - assert_eq!(client.dscp, tui.dscp); - assert_eq!(client.hmac_key, tui.hmac_key); - assert_eq!(client.server_fill, tui.server_fill); - assert_eq!(client.negotiation_policy, tui.negotiation_policy); - assert_eq!(client.socket_config.ttl, tui.socket_config.ttl); + assert_eq!(shared.server_addr, tui.server_addr); + assert_eq!(shared.duration, tui.duration); + assert_eq!(shared.interval, tui.interval); + assert_eq!(shared.length, tui.length); + assert_eq!(shared.received_stats, tui.received_stats); + assert_eq!(shared.stamp_at, tui.stamp_at); + assert_eq!(shared.clock, tui.clock); + assert_eq!(shared.dscp, tui.dscp); + assert_eq!(shared.hmac_key, tui.hmac_key); + assert_eq!(shared.server_fill, tui.server_fill); + assert_eq!(shared.negotiation_policy, tui.negotiation_policy); + assert_eq!(shared.socket_config.ttl, tui.socket_config.ttl); } } diff --git a/crates/irtt-cli/src/shared/mod.rs b/crates/irtt-cli/src/shared/mod.rs index 2433a61..9a59e8c 100644 --- a/crates/irtt-cli/src/shared/mod.rs +++ b/crates/irtt-cli/src/shared/mod.rs @@ -1,2 +1,2 @@ -#[cfg(feature = "client")] +#[cfg(feature = "client-runtime")] pub mod client; diff --git a/dist-workspace.toml b/dist-workspace.toml index b25e6a0..e059d93 100644 --- a/dist-workspace.toml +++ b/dist-workspace.toml @@ -11,4 +11,4 @@ ci = "github" installers = [] # Target platforms to build apps for (Rust target-triple syntax) targets = ["aarch64-apple-darwin", "aarch64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl", "x86_64-pc-windows-msvc"] -features = ["tui"] +features = ["full"]