refactor(cli): unify target argument syntax #108

Merged
Lochnair merged 1 commits from refactor/positional-target-labels into main 2026-08-15 14:08:08 +00:00
Lochnair commented 2026-08-15 13:57:00 +00:00 (Migrated from github.com)

Summary

  • removes the separate --target LABEL=TARGET option from both client applets;
  • positional targets now accept either TARGET or LABEL=TARGET;
  • labeled and unlabeled targets can be freely mixed in one ordered argument list;
  • existing generated labels and duplicate-label validation are preserved.

Before

irtt-cli host.example

irtt-cli --target eu=host.example

Two mechanisms represented by separate argument collections.

After

irtt-cli host.example

irtt-cli eu=host.example

One positional grammar:

[LABEL=]TARGET

Ordering

One target vector now preserves user argument order directly, including mixed labeled/unlabeled targets. There is no longer a separate positional/labelled split to reconcile.

Labels

  • unlabeled target defaults to its target string;
  • repeated unlabeled target gains #2/#3 suffixes;
  • explicit labels are preserved exactly;
  • final labels must be unique (rejecting collisions with generated labels too).

Breaking syntax

--target has been removed rather than retained as an alias or deprecated option. Migration is mechanical:

OLD: irtt-cli --target eu=a.example --target us=b.example
NEW: irtt-cli eu=a.example us=b.example

Output

#107 behavior is unchanged: logical target labels remain present in default output for both single- and multi-target runs.

TUI

irtt-tui uses the same unified positional syntax; it still requires at least one target, now enforced via required = true on the positional argument instead of required_unless_present.

Compatibility

No:

  • irtt-client API change;
  • protocol change;
  • address-resolution change;
  • stats change;
  • Cargo/dependency change.

Tests

  • parser unit tests (parse_target) for labeled/unlabeled/invalid forms;
  • normalization unit tests (target_specs) for ordering, repeated-unlabeled suffixing, explicit labels, and duplicate-label rejection (including generated-suffix collisions);
  • client/TUI arg-parsing tests for mixed ordering and old --target rejection;
  • integration test for mixed labeled/unlabeled positional targets in one run;
  • integration test asserting --target is now an unknown argument.

Verification

  • cargo test -p irtt-cli --all-features --locked — pass
  • cargo fmt --all -- --check — pass
  • cargo check --workspace --all-targets --all-features --locked — pass
  • cargo test --workspace --all-targets --all-features --locked — pass
  • cargo clippy --workspace --all-targets --all-features --locked -- -D warnings — pass
  • RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps --locked — pass
  • cargo check -p irtt-cli --no-default-features --features {client,tui,server} --all-targets --locked — pass
  • git diff --check — pass
  • manual --help/parse audit for both irtt-cli and irtt-tui confirms --target is gone and [LABEL=]TARGET forms parse as expected
## Summary - removes the separate `--target LABEL=TARGET` option from both client applets; - positional targets now accept either `TARGET` or `LABEL=TARGET`; - labeled and unlabeled targets can be freely mixed in one ordered argument list; - existing generated labels and duplicate-label validation are preserved. ## Before ``` irtt-cli host.example irtt-cli --target eu=host.example ``` Two mechanisms represented by separate argument collections. ## After ``` irtt-cli host.example irtt-cli eu=host.example ``` One positional grammar: ``` [LABEL=]TARGET ``` ## Ordering One target vector now preserves user argument order directly, including mixed labeled/unlabeled targets. There is no longer a separate positional/labelled split to reconcile. ## Labels - unlabeled target defaults to its target string; - repeated unlabeled target gains `#2`/`#3` suffixes; - explicit labels are preserved exactly; - final labels must be unique (rejecting collisions with generated labels too). ## Breaking syntax `--target` has been removed rather than retained as an alias or deprecated option. Migration is mechanical: ``` OLD: irtt-cli --target eu=a.example --target us=b.example NEW: irtt-cli eu=a.example us=b.example ``` ## Output #107 behavior is unchanged: logical target labels remain present in default output for both single- and multi-target runs. ## TUI `irtt-tui` uses the same unified positional syntax; it still requires at least one target, now enforced via `required = true` on the positional argument instead of `required_unless_present`. ## Compatibility No: - `irtt-client` API change; - protocol change; - address-resolution change; - stats change; - Cargo/dependency change. ## Tests - parser unit tests (`parse_target`) for labeled/unlabeled/invalid forms; - normalization unit tests (`target_specs`) for ordering, repeated-unlabeled suffixing, explicit labels, and duplicate-label rejection (including generated-suffix collisions); - client/TUI arg-parsing tests for mixed ordering and old `--target` rejection; - integration test for mixed labeled/unlabeled positional targets in one run; - integration test asserting `--target` is now an unknown argument. ## Verification - `cargo test -p irtt-cli --all-features --locked` — pass - `cargo fmt --all -- --check` — pass - `cargo check --workspace --all-targets --all-features --locked` — pass - `cargo test --workspace --all-targets --all-features --locked` — pass - `cargo clippy --workspace --all-targets --all-features --locked -- -D warnings` — pass - `RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps --locked` — pass - `cargo check -p irtt-cli --no-default-features --features {client,tui,server} --all-targets --locked` — pass - `git diff --check` — pass - manual `--help`/parse audit for both `irtt-cli` and `irtt-tui` confirms `--target` is gone and `[LABEL=]TARGET` forms parse as expected
Sign in to join this conversation.