cli

Command-line interface for Radroots
git clone https://radroots.dev/git/cli.git
Log | Files | Refs | README | LICENSE

commit 40a38d8c7e84d61a3a02e0a5413ae633a3dad1bd
parent 904af9764976d7546c92bac36448e4ec9f61b75f
Author: triesap <tyson@radroots.org>
Date:   Sat, 25 Apr 2026 01:29:02 +0000

build: restore cli validation apps

- scope fmt to the radroots_cli package boundary
- add the release-acceptance flake app for candidate checks
- serialize Cargo tests by binary and test thread
- format the committed CLI files covered by the fmt lane

Diffstat:
Mflake.nix | 13++++++++++---
Msrc/cli.rs | 15+++++++++------
Msrc/commands/identity.rs | 8++++----
Msrc/runtime/accounts.rs | 9+++++++--
Mtests/identity_commands.rs | 25++++++++++++++++---------
5 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/flake.nix b/flake.nix @@ -103,13 +103,20 @@ }; fmt = mkApp "fmt" { text = '' - cargo fmt --all --check + cargo fmt --package radroots_cli --check + ''; + }; + release-acceptance = mkApp "release-acceptance" { + text = '' + cargo fmt --package radroots_cli --check + cargo metadata --format-version 1 --no-deps + cargo check + cargo test -j1 -- --test-threads=1 ''; }; test = mkApp "test" { text = '' - # serialize integration test binaries; plain cargo test is flaky here - cargo test -j1 + cargo test -j1 -- --test-threads=1 ''; }; } diff --git a/src/cli.rs b/src/cli.rs @@ -1564,8 +1564,13 @@ mod tests { _ => panic!("unexpected command variant"), } - let import = - CliArgs::parse_from(["radroots", "account", "import", "./identity.json", "--default"]); + let import = CliArgs::parse_from([ + "radroots", + "account", + "import", + "./identity.json", + "--default", + ]); match import.command { Command::Account(account) => match account.command { AccountCommand::Import(args) => { @@ -2240,16 +2245,14 @@ mod tests { assert_eq!(account_import.command.display_name(), "account import"); assert!(!account_import.command.supports_dry_run()); - let account_clear_default = - CliArgs::parse_from(["radroots", "account", "clear-default"]); + let account_clear_default = CliArgs::parse_from(["radroots", "account", "clear-default"]); assert_eq!( account_clear_default.command.display_name(), "account clear-default" ); assert!(!account_clear_default.command.supports_dry_run()); - let account_remove = - CliArgs::parse_from(["radroots", "account", "remove", "market-main"]); + let account_remove = CliArgs::parse_from(["radroots", "account", "remove", "market-main"]); assert_eq!(account_remove.command.display_name(), "account remove"); assert!(!account_remove.command.supports_dry_run()); diff --git a/src/commands/identity.rs b/src/commands/identity.rs @@ -1,7 +1,8 @@ +use crate::cli::AccountImportArgs; use crate::domain::runtime::{ - AccountClearDefaultView, AccountImportView, AccountListView, AccountNewView, - AccountRemoveView, AccountSummaryView, AccountUseView, AccountWhoamiView, - CommandDisposition, CommandOutput, CommandView, IdentityPublicView, + AccountClearDefaultView, AccountImportView, AccountListView, AccountNewView, AccountRemoveView, + AccountSummaryView, AccountUseView, AccountWhoamiView, CommandDisposition, CommandOutput, + CommandView, IdentityPublicView, }; use crate::runtime::RuntimeError; use crate::runtime::accounts::{ @@ -10,7 +11,6 @@ use crate::runtime::accounts::{ import_public_identity, remove_account as remove_stored_account, resolve_account_resolution, select_account, snapshot, unresolved_account_reason, }; -use crate::cli::AccountImportArgs; use crate::runtime::config::RuntimeConfig; pub fn init(config: &RuntimeConfig) -> Result<AccountNewView, RuntimeError> { diff --git a/src/runtime/accounts.rs b/src/runtime/accounts.rs @@ -131,7 +131,8 @@ pub fn import_public_identity( format_identity_error(error) )) })?; - let imported_account_id = manager.upsert_public_identity(public_identity, None, make_default)?; + let imported_account_id = + manager.upsert_public_identity(public_identity, None, make_default)?; let snapshot = snapshot_from_manager(&manager)?; snapshot_account( &snapshot, @@ -207,7 +208,11 @@ pub fn clear_default_account( ) -> Result<AccountClearDefaultResult, RuntimeError> { let manager = account_manager(config)?; let snapshot = snapshot_from_manager(&manager)?; - let cleared_account = snapshot.accounts.iter().find(|account| account.is_default).cloned(); + let cleared_account = snapshot + .accounts + .iter() + .find(|account| account.is_default) + .cloned(); manager.clear_default_account()?; let remaining_account_count = snapshot_from_manager(&manager)?.accounts.len(); Ok(AccountClearDefaultResult { diff --git a/tests/identity_commands.rs b/tests/identity_commands.rs @@ -159,15 +159,18 @@ fn account_import_json_creates_watch_only_account_without_secret_material() { let secrets_dir = secrets_root(dir.path()).join("shared/accounts"); assert!(!secrets_dir.join(format!("{account_id}.secret")).exists()); - assert!(!secrets_dir.join(format!("{account_id}.secret.json")).exists()); + assert!( + !secrets_dir + .join(format!("{account_id}.secret.json")) + .exists() + ); let whoami = cli_command_in(dir.path()) .args(["--json", "account", "whoami"]) .output() .expect("run account whoami"); assert!(whoami.status.success()); - let whoami_json: Value = - serde_json::from_slice(whoami.stdout.as_slice()).expect("whoami json"); + let whoami_json: Value = serde_json::from_slice(whoami.stdout.as_slice()).expect("whoami json"); assert_eq!( whoami_json["account_resolution"]["resolved_account"]["id"], account_id @@ -342,10 +345,12 @@ fn account_clear_default_json_clears_stored_default_without_removing_accounts() .output() .expect("run account whoami"); assert_eq!(whoami.status.code(), Some(3)); - let whoami_json: Value = - serde_json::from_slice(whoami.stdout.as_slice()).expect("whoami json"); + let whoami_json: Value = serde_json::from_slice(whoami.stdout.as_slice()).expect("whoami json"); assert_eq!(whoami_json["account_resolution"]["source"], "none"); - assert_eq!(whoami_json["account_resolution"]["default_account"], Value::Null); + assert_eq!( + whoami_json["account_resolution"]["default_account"], + Value::Null + ); } #[test] @@ -508,10 +513,12 @@ fn account_remove_json_clears_default_when_removing_default_account() { .output() .expect("run account whoami"); assert_eq!(whoami.status.code(), Some(3)); - let whoami_json: Value = - serde_json::from_slice(whoami.stdout.as_slice()).expect("whoami json"); + let whoami_json: Value = serde_json::from_slice(whoami.stdout.as_slice()).expect("whoami json"); assert_eq!(whoami_json["account_resolution"]["source"], "none"); - assert_eq!(whoami_json["account_resolution"]["default_account"], Value::Null); + assert_eq!( + whoami_json["account_resolution"]["default_account"], + Value::Null + ); } #[test]