Skip to content

cli/serviceability: move per-resource subcommand wrappers into module crate#3779

Closed
juan-malbeclabs wants to merge 6 commits into
mainfrom
jo/7-cli-serviceability-move-cli-files
Closed

cli/serviceability: move per-resource subcommand wrappers into module crate#3779
juan-malbeclabs wants to merge 6 commits into
mainfrom
jo/7-cli-serviceability-move-cli-files

Conversation

@juan-malbeclabs
Copy link
Copy Markdown
Contributor

@juan-malbeclabs juan-malbeclabs commented May 27, 2026

RFC-20 implementation stack

This PR is part of a 9-PR chain delivering RFC-20: CLI standardization. Each PR's diff is only its own contribution; reviewers should consume them in order.

# PR Scope
1 #3753 doublezero-cli-core foundation crate + solana_l1_rpc_url
2 #3754 --solana-url + --log-verbose global flags + tracing init
3 #3755 CliContext built in main + centralized error rendering
4 #3756 rename doublezero_clidoublezero-serviceability-cli
5 #3757 rewrite location get as the async + CliContext reference verb
6 #3758 docs/cli-standard.md + CLAUDE.md pointer
7 #3779 move per-resource subcommand wrappers into the module crate
8 #3760 add ServiceabilityCommand enum + async dispatcher
9 #3761 #[command(flatten)] + collapse binary dispatch

This PR: #3779 — position 7 of 9. Previous: #3758 · Next: #3760

Replaces #3759, which was accidentally merged and then rewound from jo/6-docs-cli-standard. Same head branch, same diff.


Summary of Changes

  • Moves the 13 per-resource serviceability subcommand wrapper files (accesspass, config, contributor, device, exchange, globalconfig, link, location, multicastgroup, permission, resource, tenant, user) from client/doublezero/src/cli/ into the doublezero-serviceability-cli module crate at smartcontract/cli/src/cli/, per RFC-20 §Module contract item 2 ("the module crate exports the subcommand enum").
  • Adds smartcontract/cli/src/cli/mod.rs and pub mod cli; in the library's lib.rs so the new module is reachable.
  • Rewrites import paths in the moved files (doublezero_serviceability_cli::<resource>::* -> crate::<resource>::*) and in the binary (client/doublezero/src/{cli/command.rs,main.rs} switch to doublezero_serviceability_cli::cli::<resource>::* for the moved types).
  • cli/multicast.rs stays in the binary: its Subscribe, Unsubscribe, Publish, and Unpublish variants are async and their execute impls live in client/doublezero/src/command/multicast.rs (binary-local), depending on ServiceControllerImpl and crate::command::helpers::resolve_client_ip. The binary's cli/multicast.rs now imports MulticastGroupCliCommand from the library.
  • No Command enum reshape, no main.rs dispatch change. Pure file relocation. The next PR adds the top-level ServiceabilityCommand enum; the PR after that wires it into the binary via #[command(flatten)] and collapses the dispatch.

Diff Breakdown

Category Files Lines (+/-) Net
Scaffolding 19 +75 / -32 +43
Docs 1 +1 / -0 +1
Total 20 +76 / -32 +44

Pure file moves (tracked as renames in git, ~95% similarity each) plus import-path rewrites in the binary and the new library cli/mod.rs. Behavior unchanged.

Key files (click to expand)
  • smartcontract/cli/src/cli/mod.rs (new) - declares the 13 moved modules.
  • smartcontract/cli/src/lib.rs - adds pub mod cli;.
  • client/doublezero/src/cli/mod.rs - keeps only command, geolocation, and multicast (the binary-local ones).
  • client/doublezero/src/cli/command.rs - imports MulticastCliCommand from crate::cli and the 13 moved types from doublezero_serviceability_cli::cli::*.
  • client/doublezero/src/cli/multicast.rs - imports MulticastGroupCliCommand from the library.
  • client/doublezero/src/main.rs - imports the moved subcommand enums (DeviceCommands, LinkCommands, ...) from doublezero_serviceability_cli::cli::*; the per-resource match arms switch from cli::<resource>::*Commands::* to doublezero_serviceability_cli::cli::<resource>::*Commands::*.

Testing Verification

  • cargo check --workspace clean.
  • make rust-test green workspace-wide (including the cargo test -p doublezero-serviceability-cli location::get reference verb).
  • make rust-lint clean.
  • cargo run -p doublezero -- --help and cargo run -p doublezero -- device list --help produce the same command tree as before; the relocation is invisible to users.
  • Targets jo/6-docs-cli-standard; the diff shown is only this PR's contribution. Follow-ups #PR8 (add ServiceabilityCommand enum) and #PR9 (flatten in binary + collapse dispatch) complete the RFC-20 §Module contract item 2 work.

@juan-malbeclabs juan-malbeclabs force-pushed the jo/6-docs-cli-standard branch from 0a2319d to e096e1e Compare May 27, 2026 20:31
juan-malbeclabs added a commit that referenced this pull request May 27, 2026
## RFC-20 implementation stack

This PR is part of a 9-PR chain delivering [RFC-20: CLI
standardization](https://github.com/malbeclabs/doublezero/blob/main/rfcs/rfc20-cli-standardization.md).
Each PR's diff is **only its own contribution**; reviewers should
consume them in order.

| # | PR | Scope |
|---|----|-------|
| 1 | [#3753](#3753) |
`doublezero-cli-core` foundation crate + `solana_l1_rpc_url` |
| 2 | [#3754](#3754) |
`--solana-url` + `--log-verbose` global flags + tracing init |
| 3 | [#3755](#3755) |
`CliContext` built in `main` + centralized error rendering |
| 4 | [#3756](#3756) |
rename `doublezero_cli` → `doublezero-serviceability-cli` |
| 5 | [#3757](#3757) |
rewrite `location get` as the async + `CliContext` reference verb |
| **6** | [#3758](#3758) |
`docs/cli-standard.md` + `CLAUDE.md` pointer |
| 7 | [#3779](#3779) | move
per-resource subcommand wrappers into the module crate |
| 8 | [#3760](#3760) | add
`ServiceabilityCommand` enum + async dispatcher |
| 9 | [#3761](#3761) |
`#[command(flatten)]` + collapse binary dispatch |

**This PR: #3758** — position **6** of 9. Previous:
[#3757](#3757) · Next:
[#3779](#3779)

---

## Summary of Changes
- Adds `docs/cli-standard.md`, the contributor-facing summary of RFC-20
([rfcs/rfc20-cli-standardization.md](../rfcs/rfc20-cli-standardization.md)).
Covers the module contract, argument and output conventions, the global
flag set, the diagnostic-logging facade, the preflight
`RequirementCheck` bitflags, and walks through
`smartcontract/cli/src/location/get.rs` as the worked example.
- Updates `CLAUDE.md` with a CLI-standard section pointing at RFC-20,
the new contributor doc, and the reference verb so future contributors
land on the standard quickly.

## Diff Breakdown
| Category     | Files | Lines (+/-) | Net  |
|--------------|-------|-------------|------|
| Docs         |     3 | +253 / -0   | +253 |
| **Total**    |     3 | +253 / -0   | +253 |

Pure documentation: a single new contributor doc plus a short pointer
added to `CLAUDE.md` and the CHANGELOG entry recording it.

<details>
<summary>Key files (click to expand)</summary>

- `docs/cli-standard.md` - new file. Roughly 240 lines covering the
module contract, argument/output conventions, global flags, logging, the
`location get` worked example, the `RequirementCheck` bitflag mapping,
authorization rules, and the explicit open follow-ups (Command enum
move, geolocation module crate, daemon-control module crate, JSON schema
versioning, shell completion).
- `CLAUDE.md` - new "CLI Standard (RFC-20)" section between "RFCs and
Documentation" and "Style & Terminology" with four bullets pointing at
the RFC, the contributor doc, the core crate, and the migration cadence.

</details>

## Testing Verification
- `make rust-test` green workspace-wide (no code changes; sanity check
that the docs commit does not break anything).
- Manually previewed the rendered markdown of both
`docs/cli-standard.md` and the updated `CLAUDE.md` section for headings,
lists, and the code block in the worked example.
- Targets `jo/5-cli-location-get-conforming-verb`; the diff shown is
only this PR's docs.
Base automatically changed from jo/6-docs-cli-standard to main May 27, 2026 20:49
juan-malbeclabs added a commit that referenced this pull request May 27, 2026
…her (#3760)

## RFC-20 implementation stack

This PR is part of a 9-PR chain delivering [RFC-20: CLI
standardization](https://github.com/malbeclabs/doublezero/blob/main/rfcs/rfc20-cli-standardization.md).
Each PR's diff is **only its own contribution**; reviewers should
consume them in order.

| # | PR | Scope |
|---|----|-------|
| 1 | [#3753](#3753) |
`doublezero-cli-core` foundation crate + `solana_l1_rpc_url` |
| 2 | [#3754](#3754) |
`--solana-url` + `--log-verbose` global flags + tracing init |
| 3 | [#3755](#3755) |
`CliContext` built in `main` + centralized error rendering |
| 4 | [#3756](#3756) |
rename `doublezero_cli` → `doublezero-serviceability-cli` |
| 5 | [#3757](#3757) |
rewrite `location get` as the async + `CliContext` reference verb |
| 6 | [#3758](#3758) |
`docs/cli-standard.md` + `CLAUDE.md` pointer |
| 7 | [#3779](#3779) | move
per-resource subcommand wrappers into the module crate |
| **8** | [#3760](#3760) |
add `ServiceabilityCommand` enum + async dispatcher |
| 9 | [#3761](#3761) |
`#[command(flatten)]` + collapse binary dispatch |

**This PR: #3760** — position **8** of 9. Previous:
[#3779](#3779) · Next:
[#3761](#3761)

---

## Summary of Changes
- Adds `doublezero_serviceability_cli::cli::ServiceabilityCommand`, the
module crate's top-level subcommand enum per RFC-20 §Module contract
item 2.
- Aggregates 17 serviceability variants: `Init`, `Migrate`, `Address`,
`Balance`, `Config`, `GlobalConfig`, `Location`, `Exchange`,
`Contributor`, `Permission`, `Tenant`, `Device`, `Link`, `AccessPass`,
`User`, `Export`, `Keygen`, `Resource`.
- Implements `async fn execute(ctx: &CliContext, client: &impl
CliCommand, out: &mut impl Write)` that owns the full per-resource
dispatch tree currently inlined in `client/doublezero/src/main.rs`. The
`Location::Get` arm forwards `&ctx` and is `.await`ed (matches the
RFC-20 reference verb from #3757); all other resource arms are sync.
- Not yet wired into the unified binary. The next PR (#9) adds
`#[command(flatten)] Serviceability(ServiceabilityCommand)` to the
binary's `Command` enum and collapses `main.rs`'s ~270-line match block
to a single dispatch arm.

## Diff Breakdown
| Category     | Files | Lines (+/-) | Net  |
|--------------|-------|-------------|------|
| Core logic   |     1 | +242 / -0   | +242 |
| Scaffolding  |     1 | +1 / -0     |   +1 |
| Docs         |     1 | +1 / -0     |   +1 |
| **Total**    |     3 | +244 / -1   | +243 |

Single new file in the library plus a one-line `pub mod` in
`cli/mod.rs`. The enum is `pub` and reachable but currently has no
in-tree consumer; it surfaces as the module crate's public mounting
point ready for the binary to flatten.

<details>
<summary>Key files (click to expand)</summary>

- `smartcontract/cli/src/cli/command.rs` (new) - the
`ServiceabilityCommand` enum + `async fn execute` dispatcher. Forwards
`&CliContext` only to verbs that consume it (today only
`LocationCommands::Get` per #3757); other arms ignore `ctx`. The
`AccessPassCommands::Fund` arm preserves the existing stdin-reading
behavior (`std::io::stdin().lock()`) since that interaction is part of
the verb's contract today.
- `smartcontract/cli/src/cli/mod.rs` - adds `pub mod command;`.

</details>

## Testing Verification
- `cargo check --workspace` clean.
- `make rust-test` green workspace-wide (no behavior change — the new
enum is unused by the binary in this PR).
- `make rust-lint` clean.
- `cargo doc --no-deps -p doublezero-serviceability-cli` succeeds and
the new module appears.
- Targets `jo/7-cli-serviceability-move-cli-files`; the diff shown is
only this PR's contribution. Final PR #9 will flatten this enum into the
binary and collapse `main.rs` dispatch.
@ben-dz
Copy link
Copy Markdown
Contributor

ben-dz commented May 27, 2026

I think this PR may be stale– If I rebase on the current head-of-main, this branch comes out to no-change.

@ben-dz ben-dz closed this May 28, 2026
juan-malbeclabs added a commit that referenced this pull request May 28, 2026
## RFC-20 implementation stack

This PR is part of a 9-PR chain delivering [RFC-20: CLI
standardization](https://github.com/malbeclabs/doublezero/blob/main/rfcs/rfc20-cli-standardization.md).
Each PR's diff is **only its own contribution**; reviewers should
consume them in order.

| # | PR | Scope |
|---|----|-------|
| 1 | [#3753](#3753) |
`doublezero-cli-core` foundation crate + `solana_l1_rpc_url` |
| 2 | [#3754](#3754) |
`--solana-url` + `--log-verbose` global flags + tracing init |
| 3 | [#3755](#3755) |
`CliContext` built in `main` + centralized error rendering |
| 4 | [#3756](#3756) |
rename `doublezero_cli` → `doublezero-serviceability-cli` |
| 5 | [#3757](#3757) |
rewrite `location get` as the async + `CliContext` reference verb |
| 6 | [#3758](#3758) |
`docs/cli-standard.md` + `CLAUDE.md` pointer |
| 7 | [#3779](#3779) | move
per-resource subcommand wrappers into the module crate |
| 8 | [#3760](#3760) | add
`ServiceabilityCommand` enum + async dispatcher |
| **9** | [#3761](#3761) |
`#[command(flatten)]` + collapse binary dispatch |

**This PR: #3761** — position **9** of 9. Previous:
[#3760](#3760) · Next:
(none — tip of stack)

---

## Summary of Changes
- Hoists `doublezero_serviceability_cli::cli::ServiceabilityCommand`
(added in #3760) into the unified `doublezero` binary via
`#[command(flatten)]` on the top-level `Command` enum. RFC-20 §Module
contract item 2 is now complete: the module crate owns the
serviceability subcommand enum, the binary mounts it.
- Drops 17 explicit serviceability variants from the binary's `Command`
enum: `Init`, `Migrate`, `Address`, `Balance`, `Config`, `GlobalConfig`,
`Location`, `Exchange`, `Contributor`, `Permission`, `Tenant`, `Device`,
`Link`, `AccessPass`, `User`, `Export`, `Keygen`, `Resource`. They now
surface at the top level via the flattened
`Serviceability(ServiceabilityCommand)` variant.
- Collapses the `main.rs` dispatch match block from roughly 270 lines
(the original per-resource explicit dispatch) to about 90 lines, with
one new arm doing the work for all serviceability verbs:
`Command::Serviceability(cmd) => cmd.execute(&ctx, &client, &mut
handle).await`. The remaining arms cover binary-local concerns:
daemon-control verbs (`Connect`, `Enable`, `Disable`, `Status`,
`Disconnect`, `Latency`, `Routes`), raw-`DZClient` diagnostics
(`Account`, `Accounts`, `Log`), the binary-local geolocation tree,
`InitGeolocationConfig`, the multicast dispatch (whose
`Subscribe`/`Unsubscribe`/`Publish`/`Unpublish` async arms depend on
daemon-control infrastructure), and the `Completion` generator.
- Re-exports `ServiceabilityCommand` from
`smartcontract/cli/src/cli/mod.rs` (`pub use
command::ServiceabilityCommand;`) so the binary imports through
`doublezero_serviceability_cli::cli::ServiceabilityCommand`.
- Updates the version-check skip list (`matches!`) in `main.rs` to match
against the flattened variants (`ServiceabilityCommand::Address`,
`::Balance`, `::Export`) instead of the now-gone top-level variants.

## Diff Breakdown
| Category     | Files | Lines (+/-) | Net  |
|--------------|-------|-------------|------|
| Core logic   |     2 | +84 / -313  | -229 |
| Scaffolding  |     1 | +2 / -0     |   +2 |
| Docs         |     1 | +1 / -0     |   +1 |
| **Total**    |     4 | +87 / -313  | -226 |

Substantial net deletion in the binary: the 270-line per-resource
dispatch in `main.rs` is replaced by one line, and 17 explicit variants
in `cli/command.rs` are replaced by one `#[command(flatten)]` variant.

<details>
<summary>Key files (click to expand)</summary>

- `client/doublezero/src/cli/command.rs` - top-level `Command` enum
reduces to 14 variants (7 daemon-control + 3 raw-`DZClient` + 1
geolocation + 1 `InitGeolocationConfig` + 1 multicast + 1 completion + 1
flattened serviceability). Adds a doc comment explaining the RFC-20
mounting strategy.
- `client/doublezero/src/main.rs` - replaces the ~270-line per-resource
match block with binary-stay arms + one `Command::Serviceability(cmd) =>
cmd.execute(&ctx, &client, &mut handle).await` arm. Imports for the
moved subcommand enums (`DeviceCommands`, `LinkCommands`, ...) are gone
— only multicast-group enums remain since the binary still dispatches
the Group subtree locally.
- `smartcontract/cli/src/cli/mod.rs` - `pub use
command::ServiceabilityCommand;` so the binary's import path is
`doublezero_serviceability_cli::cli::ServiceabilityCommand` (not
`::cli::command::ServiceabilityCommand`).

</details>

## Testing Verification
- `cargo check --workspace` clean.
- `make rust-test` green workspace-wide.
- `make rust-lint` clean.
- `./target/debug/doublezero --help` shows 29 visible top-level
commands, byte-identical to the pre-refactor output. Hidden variants
(`Init`, `Migrate`, `InitGeolocationConfig`, `Accounts`) remain hidden
via `#[command(hide = true)]`.
- `./target/debug/doublezero device --help`, `./target/debug/doublezero
location --help`, and `./target/debug/doublezero multicast --help`
produce the same nested verb trees.
- The `location get` async ctx-consuming reference verb still works (the
new dispatcher forwards `&ctx` to the relevant arm).
- Targets `jo/8-cli-serviceability-command-enum`; the diff shown is only
this PR's contribution. Once the chain merges to `main`, RFC-20 §Module
contract item 2 is fully delivered for the serviceability module.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants