refactor(app): clarify application and binary roles #124

Merged
Lochnair merged 2 commits from refactor/application-binaries into main 2026-08-20 05:09:10 +00:00
Lochnair commented 2026-08-20 04:45:34 +00:00 (Migrated from github.com)

Summary

  • rename the application package from irtt-cli to irtt-rs;
  • rename the scriptable client binary from irtt-cli to irtt-client;
  • give dedicated binaries role-specific entry points;
  • move future application releases to irtt-rs/vX.Y.Z.

Binary linkage

Before this change, every dedicated binary's main() called the same
entry::main(), which dispatched by argv0/subcommand and referenced every
applet role enabled by the active feature set. With --all-features, that
meant irtt-cli, irtt-tui, and irtt-server were byte-identical to the
irtt-rs dispatcher — each one linked all three applet roles regardless of
which binary it was.

Binary (all-features release build) Before (bytes) After (bytes)
irtt-rs (dispatcher) 1,039,520 1,039,536
irtt-cli / irtt-client 1,039,520 737,616
irtt-tui 1,039,520 939,152
irtt-server 1,039,520 587,632
Binary (minimal single-feature build) Before (bytes) After (bytes) Delta vs. all-features (after)
irtt-cli / irtt-client (client only) 737,616 737,600 +16 B (0.002%)
irtt-tui (tui only) 939,184 939,136 +16 B (0.002%)
irtt-server (server only) 587,680 587,648 -16 B (noise)

Each dedicated binary now gets its own entry point (entry::client_main,
entry::tui_main, entry::server_main) that goes straight to its role's
clap parsing and run function, never touching applet::dispatch_from_argv
or argv0 detection at all. irtt-rs keeps a separate entry::dispatcher_main
that owns argv0/subcommand dispatch and may reference every enabled role. A
small shared with_shutdown_flag helper installs the Ctrl-C handler common to
all three roles without duplicating it.

strings on the release binaries confirms no cross-contamination: irtt-client
contains no server/TUI help text, irtt-server contains no client/TUI help
text, and vice versa. Renaming or copying a dedicated binary to an arbitrary
filename (including irtt-cli, the old name) does not change its role —
covered by new regression tests in applet_dispatch.rs.

Naming

  • irtt-client crate = the reusable client library (crates/irtt-client), unchanged, still 0.5.0.
  • irtt-client binary = the scriptable stream-client application, produced by the irtt-rs package. It is a coincidence of naming that the executable and the library share a name; the executable does not come from the library crate.
  • irtt-rs package = the application suite (crates/irtt-app, library name irtt_app), bumped to 0.6.0 as a breaking distribution rename. Its four [[bin]] targets are irtt-rs (multicall dispatcher), irtt-client, irtt-tui, irtt-server.

crates.io confirmed irtt-rs is unclaimed via the registry API before the rename.

Feature boundaries

irtt-rs stays feature-selectable: --no-default-features --features client builds a working irtt-rs client subcommand while server/tui report unavailable through the existing dispatcher policy (no build/link errors). Same for --features server and --features tui. Dedicated binaries carry required-features matching their role (client, server, tui).

Release migration

  • old: irtt-cli/v0.5.0 (historical, untouched)
  • future: irtt-rs/v0.6.0 (not tagged in this PR)

dist-workspace.toml's tag-namespace moved to irtt-rs, and the cargo-dist
GitHub Actions workflow was regenerated (dist generate), renaming
.github/workflows/irtt-cli-release.yml to irtt-rs-release.yml (only the
tag-matching regex differs from the old file). semver.yml's tag list and
renovate.json's ignorePaths were updated to match.

Verification

  • cargo fmt --all -- --check
  • cargo check --workspace --all-targets --all-features --locked
  • cargo check -p irtt-rs --no-default-features --features {client,server,tui} --all-targets --locked (each in isolation)
  • cargo test --workspace --all-targets --all-features --locked (all green, including new entry-point/role regression tests)
  • cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
  • RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps --locked
  • git diff --check
  • cargo publish -p {irtt-rs,irtt-client,irtt-server,irtt-proto,irtt-stats} --dry-run --locked — all package/verify cleanly
  • Runtime smoke: irtt-rs {client,tui,server} --help, irtt-client/-tui/-server --help, selective-feature dispatcher builds, renamed/copied dedicated binaries
  • strings inspection of release binaries for cross-role help text leakage — none found

No tag or release was created. No irtt alias was added. No OpenWrt packaging was added. This PR is not merged.

## Summary - rename the application package from irtt-cli to irtt-rs; - rename the scriptable client binary from irtt-cli to irtt-client; - give dedicated binaries role-specific entry points; - move future application releases to irtt-rs/vX.Y.Z. ## Binary linkage Before this change, every dedicated binary's `main()` called the same `entry::main()`, which dispatched by argv0/subcommand and referenced every applet role enabled by the active feature set. With `--all-features`, that meant `irtt-cli`, `irtt-tui`, and `irtt-server` were byte-identical to the `irtt-rs` dispatcher — each one linked all three applet roles regardless of which binary it was. | Binary (all-features release build) | Before (bytes) | After (bytes) | | --- | ---: | ---: | | `irtt-rs` (dispatcher) | 1,039,520 | 1,039,536 | | `irtt-cli` / `irtt-client` | 1,039,520 | 737,616 | | `irtt-tui` | 1,039,520 | 939,152 | | `irtt-server` | 1,039,520 | 587,632 | | Binary (minimal single-feature build) | Before (bytes) | After (bytes) | Delta vs. all-features (after) | | --- | ---: | ---: | ---: | | `irtt-cli` / `irtt-client` (`client` only) | 737,616 | 737,600 | +16 B (0.002%) | | `irtt-tui` (`tui` only) | 939,184 | 939,136 | +16 B (0.002%) | | `irtt-server` (`server` only) | 587,680 | 587,648 | -16 B (noise) | Each dedicated binary now gets its own entry point (`entry::client_main`, `entry::tui_main`, `entry::server_main`) that goes straight to its role's `clap` parsing and run function, never touching `applet::dispatch_from_argv` or argv0 detection at all. `irtt-rs` keeps a separate `entry::dispatcher_main` that owns argv0/subcommand dispatch and may reference every enabled role. A small shared `with_shutdown_flag` helper installs the Ctrl-C handler common to all three roles without duplicating it. `strings` on the release binaries confirms no cross-contamination: `irtt-client` contains no server/TUI help text, `irtt-server` contains no client/TUI help text, and vice versa. Renaming or copying a dedicated binary to an arbitrary filename (including `irtt-cli`, the old name) does not change its role — covered by new regression tests in `applet_dispatch.rs`. ## Naming - `irtt-client` **crate** = the reusable client library (`crates/irtt-client`), unchanged, still 0.5.0. - `irtt-client` **binary** = the scriptable stream-client application, produced by the `irtt-rs` package. It is a coincidence of naming that the executable and the library share a name; the executable does not come from the library crate. - `irtt-rs` **package** = the application suite (`crates/irtt-app`, library name `irtt_app`), bumped to 0.6.0 as a breaking distribution rename. Its four `[[bin]]` targets are `irtt-rs` (multicall dispatcher), `irtt-client`, `irtt-tui`, `irtt-server`. crates.io confirmed `irtt-rs` is unclaimed via the registry API before the rename. ## Feature boundaries `irtt-rs` stays feature-selectable: `--no-default-features --features client` builds a working `irtt-rs client` subcommand while `server`/`tui` report unavailable through the existing dispatcher policy (no build/link errors). Same for `--features server` and `--features tui`. Dedicated binaries carry `required-features` matching their role (`client`, `server`, `tui`). ## Release migration - old: `irtt-cli/v0.5.0` (historical, untouched) - future: `irtt-rs/v0.6.0` (not tagged in this PR) `dist-workspace.toml`'s `tag-namespace` moved to `irtt-rs`, and the cargo-dist GitHub Actions workflow was regenerated (`dist generate`), renaming `.github/workflows/irtt-cli-release.yml` to `irtt-rs-release.yml` (only the tag-matching regex differs from the old file). `semver.yml`'s tag list and `renovate.json`'s `ignorePaths` were updated to match. ## Verification - [x] `cargo fmt --all -- --check` - [x] `cargo check --workspace --all-targets --all-features --locked` - [x] `cargo check -p irtt-rs --no-default-features --features {client,server,tui} --all-targets --locked` (each in isolation) - [x] `cargo test --workspace --all-targets --all-features --locked` (all green, including new entry-point/role regression tests) - [x] `cargo clippy --workspace --all-targets --all-features --locked -- -D warnings` - [x] `RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps --locked` - [x] `git diff --check` - [x] `cargo publish -p {irtt-rs,irtt-client,irtt-server,irtt-proto,irtt-stats} --dry-run --locked` — all package/verify cleanly - [x] Runtime smoke: `irtt-rs {client,tui,server} --help`, `irtt-client/-tui/-server --help`, selective-feature dispatcher builds, renamed/copied dedicated binaries - [x] `strings` inspection of release binaries for cross-role help text leakage — none found No tag or release was created. No `irtt` alias was added. No OpenWrt packaging was added. This PR is not merged.
Sign in to join this conversation.