From 4fd6613dfa38f1f95e50b43dbd9660fc1ee2a7f8 Mon Sep 17 00:00:00 2001 From: Matt Keeter Date: Wed, 13 May 2026 11:15:31 -0700 Subject: [PATCH 1/3] Dispatch on an `enum Subcommand` --- Cargo.lock | 50 +------------- Cargo.toml | 1 + cmd/auxflash/Cargo.toml | 1 - cmd/auxflash/src/lib.rs | 20 +++--- cmd/console-proxy/Cargo.toml | 1 - cmd/console-proxy/src/lib.rs | 18 +++-- cmd/console-proxy/src/posix.rs | 7 +- cmd/counters/Cargo.toml | 1 - cmd/counters/src/lib.rs | 20 +++--- cmd/dashboard/Cargo.toml | 1 - cmd/dashboard/src/lib.rs | 24 ++++--- cmd/debugmailbox/Cargo.toml | 1 - cmd/debugmailbox/src/lib.rs | 23 ++++--- cmd/diagnose/Cargo.toml | 1 - cmd/diagnose/src/lib.rs | 25 +++---- cmd/discover/Cargo.toml | 1 - cmd/discover/src/lib.rs | 22 +++---- cmd/doc/Cargo.toml | 1 - cmd/doc/src/lib.rs | 18 ++--- cmd/dump/Cargo.toml | 1 - cmd/dump/src/lib.rs | 17 ++--- cmd/ereport/Cargo.toml | 1 - cmd/ereport/src/lib.rs | 17 ++--- cmd/exec/Cargo.toml | 1 - cmd/exec/src/lib.rs | 17 ++--- cmd/extract/Cargo.toml | 1 - cmd/extract/src/lib.rs | 17 ++--- cmd/flash/Cargo.toml | 1 - cmd/flash/src/lib.rs | 21 +++--- cmd/gimlet/src/lib.rs | 17 ++--- cmd/gpio/Cargo.toml | 1 - cmd/gpio/src/lib.rs | 17 ++--- cmd/hash/Cargo.toml | 1 - cmd/hash/src/lib.rs | 17 ++--- cmd/hiffy/src/lib.rs | 18 ++--- cmd/host/Cargo.toml | 3 +- cmd/host/src/lib.rs | 17 ++--- cmd/hydrate/Cargo.toml | 1 - cmd/hydrate/src/lib.rs | 16 ++--- cmd/i2c/src/lib.rs | 16 +++-- cmd/ibc/src/lib.rs | 17 ++--- cmd/jefe/Cargo.toml | 1 - cmd/jefe/src/lib.rs | 17 ++--- cmd/lpc55gpio/src/lib.rs | 17 ++--- cmd/lsusb/Cargo.toml | 1 - cmd/lsusb/src/lib.rs | 16 ++--- cmd/manifest/Cargo.toml | 1 - cmd/manifest/src/lib.rs | 21 +++--- cmd/map/Cargo.toml | 1 - cmd/map/src/lib.rs | 16 +++-- cmd/monorail/Cargo.toml | 1 - cmd/monorail/src/lib.rs | 22 +++---- cmd/mwocp/Cargo.toml | 1 - cmd/mwocp/src/lib.rs | 17 ++--- cmd/net/Cargo.toml | 1 - cmd/net/src/lib.rs | 20 +++--- cmd/pmbus/Cargo.toml | 1 - cmd/pmbus/src/lib.rs | 17 ++--- cmd/power/Cargo.toml | 1 - cmd/power/src/lib.rs | 17 ++--- cmd/powershelf/Cargo.toml | 1 - cmd/powershelf/src/lib.rs | 22 +++---- cmd/probe/Cargo.toml | 1 - cmd/probe/src/lib.rs | 17 ++--- cmd/qspi/src/lib.rs | 18 ++--- cmd/readmem/src/lib.rs | 18 ++--- cmd/readvar/Cargo.toml | 1 - cmd/readvar/src/lib.rs | 17 ++--- cmd/rebootleby/Cargo.toml | 1 - cmd/rebootleby/src/lib.rs | 21 +++--- cmd/registers/Cargo.toml | 1 - cmd/registers/src/lib.rs | 20 +++--- cmd/rencm/src/lib.rs | 18 ++--- cmd/rendmp/Cargo.toml | 1 - cmd/rendmp/src/lib.rs | 17 ++--- cmd/reset/Cargo.toml | 1 - cmd/reset/src/lib.rs | 17 ++--- cmd/ringbuf/Cargo.toml | 1 - cmd/ringbuf/src/lib.rs | 17 ++--- cmd/sbrmi/Cargo.toml | 1 - cmd/sbrmi/src/lib.rs | 17 ++--- cmd/sensors/Cargo.toml | 1 - cmd/sensors/src/lib.rs | 17 ++--- cmd/spctrl/src/lib.rs | 18 ++--- cmd/spd/Cargo.toml | 1 - cmd/spd/src/lib.rs | 17 ++--- cmd/spi/src/lib.rs | 18 ++--- cmd/stackmargin/src/lib.rs | 22 +++---- cmd/stmsecure/Cargo.toml | 1 - cmd/stmsecure/src/lib.rs | 46 ++++++++----- cmd/tasks/Cargo.toml | 1 - cmd/tasks/src/lib.rs | 17 ++--- cmd/test/Cargo.toml | 1 - cmd/test/src/lib.rs | 17 ++--- cmd/tofino-eeprom/Cargo.toml | 1 - cmd/tofino-eeprom/src/lib.rs | 17 ++--- cmd/validate/Cargo.toml | 1 - cmd/validate/src/lib.rs | 20 +++--- cmd/vpd/src/lib.rs | 18 ++--- cmd/writeword/Cargo.toml | 1 - cmd/writeword/src/lib.rs | 20 +++--- humility-bin/Cargo.toml | 4 +- humility-bin/build.rs | 82 ++++++++++++++++------- humility-bin/src/cmd.rs | 47 +------------ humility-bin/src/main.rs | 116 +++++++++++++++------------------ humility-cli/src/lib.rs | 21 ++---- humility-cmd/Cargo.toml | 7 -- humility-cmd/src/lib.rs | 15 ----- 108 files changed, 689 insertions(+), 746 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c31baa86f..b65aa0219 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1636,6 +1636,7 @@ dependencies = [ "colored", "csv", "env_logger", + "heck", "hif", "humility-cli", "humility-cmd", @@ -1731,12 +1732,6 @@ dependencies = [ [[package]] name = "humility-cmd" version = "0.1.0" -dependencies = [ - "anyhow", - "clap", - "humility-cli", - "humility-core", -] [[package]] name = "humility-cmd-auxflash" @@ -1748,7 +1743,6 @@ dependencies = [ "hif", "humility-auxflash", "humility-cli", - "humility-cmd", "humility-core", "idol", "log", @@ -1764,7 +1758,6 @@ dependencies = [ "clap", "crossbeam-channel", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-idol", @@ -1780,7 +1773,6 @@ dependencies = [ "clap", "colored", "humility-cli", - "humility-cmd", "humility-core", "humility-doppel", "indexmap 2.14.0", @@ -1797,7 +1789,6 @@ dependencies = [ "crossterm 0.29.0", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-idol", @@ -1814,7 +1805,6 @@ dependencies = [ "byteorder", "clap", "humility-cli", - "humility-cmd", "humility-cortex", "parse_int", "probe-rs", @@ -1827,7 +1817,6 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-core", "humility-doppel", "humility-jefe", @@ -1843,7 +1832,6 @@ dependencies = [ "colored", "hubpack", "humility-cli", - "humility-cmd", "humility-core", "parse_int", "serde", @@ -1858,7 +1846,6 @@ dependencies = [ "cargo_metadata", "clap", "humility-cli", - "humility-cmd", "termimad 0.34.1", ] @@ -1872,7 +1859,6 @@ dependencies = [ "hubpack", "humility-arch-arm", "humility-cli", - "humility-cmd", "humility-core", "humility-dump-agent", "humpty", @@ -1895,7 +1881,6 @@ dependencies = [ "clap", "hex", "humility-cli", - "humility-cmd", "humility-core", "humility-doppel", "serde", @@ -1910,7 +1895,6 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-log", "serde_json", "splitty", @@ -1923,7 +1907,6 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-log", "zip", ] @@ -1937,7 +1920,6 @@ dependencies = [ "goblin", "humility-auxflash", "humility-cli", - "humility-cmd", "humility-core", "humility-cortex", "humility-probes-core", @@ -1976,7 +1958,6 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", "humility-hiffy", "parse_int", ] @@ -1989,7 +1970,6 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "indicatif", @@ -2023,7 +2003,6 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-doppel", "humility-hiffy", @@ -2043,7 +2022,6 @@ dependencies = [ "hubpack", "humility-arch-arm", "humility-cli", - "humility-cmd", "humility-core", "humility-log", "humpty", @@ -2097,7 +2075,6 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-core", "humility-jefe", "parse_int", @@ -2123,7 +2100,6 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-core", "rusb", ] @@ -2135,7 +2111,6 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-core", "serde_json", ] @@ -2147,7 +2122,6 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-core", ] @@ -2160,7 +2134,6 @@ dependencies = [ "colored", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-idol", @@ -2181,7 +2154,6 @@ dependencies = [ "colored", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-i2c", @@ -2204,7 +2176,6 @@ dependencies = [ "colored", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-idol", @@ -2220,7 +2191,6 @@ dependencies = [ "colored", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-i2c", @@ -2239,7 +2209,6 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-idol", @@ -2257,7 +2226,6 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-idol", @@ -2276,7 +2244,6 @@ dependencies = [ "clap", "humility-arch-arm", "humility-cli", - "humility-cmd", "humility-core", "humility-cortex", "num-traits", @@ -2321,7 +2288,6 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-core", ] @@ -2333,7 +2299,6 @@ dependencies = [ "clap", "humility-arch-arm", "humility-cli", - "humility-cmd", "humility-core", "humility-cortex", "ihex", @@ -2352,7 +2317,6 @@ dependencies = [ "clap", "humility-arch-arm", "humility-cli", - "humility-cmd", "humility-core", "humility-cortex", "humility-stack", @@ -2388,7 +2352,6 @@ dependencies = [ "colored", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-i2c", @@ -2412,7 +2375,6 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-core", "humility-probes-core", ] @@ -2424,7 +2386,6 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-core", "humility-doppel", ] @@ -2438,7 +2399,6 @@ dependencies = [ "colored", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-idol", @@ -2456,7 +2416,6 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-doppel", "humility-hiffy", @@ -2487,7 +2446,6 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-i2c", @@ -2531,7 +2489,6 @@ dependencies = [ "clap", "humility-arch-arm", "humility-cli", - "humility-cmd", "humility-core", "parse_int", ] @@ -2544,7 +2501,6 @@ dependencies = [ "clap", "humility-arch-arm", "humility-cli", - "humility-cmd", "humility-core", "humility-doppel", "humility-stack", @@ -2562,7 +2518,6 @@ dependencies = [ "colored", "hif", "humility-cli", - "humility-cmd", "humility-cmd-tasks", "humility-core", "humility-cortex", @@ -2577,7 +2532,6 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-idol", @@ -2594,7 +2548,6 @@ dependencies = [ "colored", "hif", "humility-cli", - "humility-cmd", "humility-core", "humility-hiffy", "humility-i2c", @@ -2633,7 +2586,6 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-core", "parse-size", "parse_int", diff --git a/Cargo.toml b/Cargo.toml index 5ce4297f9..b82bac501 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -205,6 +205,7 @@ ctrlc = "3.1.5" env_logger = "0.11.10" gimli = "0.33.0" goblin = "0.10" +heck = "0.5" hex = "0.4.3" hubpack = "0.1.1" ihex = "3.0" diff --git a/cmd/auxflash/Cargo.toml b/cmd/auxflash/Cargo.toml index 90738c23f..bd7cec17f 100644 --- a/cmd/auxflash/Cargo.toml +++ b/cmd/auxflash/Cargo.toml @@ -17,5 +17,4 @@ parse_int.workspace = true humility.workspace = true humility-auxflash.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true diff --git a/cmd/auxflash/src/lib.rs b/cmd/auxflash/src/lib.rs index 00f8af0c6..4f7a12d91 100644 --- a/cmd/auxflash/src/lib.rs +++ b/cmd/auxflash/src/lib.rs @@ -10,16 +10,15 @@ //! program auxiliary flash when needed. use anyhow::Result; -use clap::{CommandFactory, Parser}; +use clap::Parser; use colored::Colorize; -use humility_cli::ExecutionContext; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_auxflash::AuxFlashHandler; -use humility_cmd::Command; #[derive(Parser, Debug)] #[clap(name = "auxflash", about = env!("CARGO_PKG_DESCRIPTION"))] -struct AuxFlashArgs { +pub struct AuxFlashArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 15000, value_name = "timeout_ms", @@ -97,8 +96,10 @@ fn auxflash_status(mut worker: AuxFlashHandler, verbose: bool) -> Result<()> { Ok(()) } -fn auxflash(context: &mut ExecutionContext) -> Result<()> { - let subargs = AuxFlashArgs::try_parse_from(&context.cli.cmd)?; +fn auxflash( + subargs: AuxFlashArgs, + context: &mut ExecutionContext, +) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; let mut worker = AuxFlashHandler::new(hubris, core, subargs.timeout)?; @@ -130,6 +131,9 @@ fn auxflash(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: AuxFlashArgs::command(), name: "auxflash", run: auxflash } +pub type Args = AuxFlashArgs; +impl HumilitySubcommand for AuxFlashArgs { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + auxflash(args, context) + } } diff --git a/cmd/console-proxy/Cargo.toml b/cmd/console-proxy/Cargo.toml index cc9e6f0f1..4d039897a 100644 --- a/cmd/console-proxy/Cargo.toml +++ b/cmd/console-proxy/Cargo.toml @@ -11,7 +11,6 @@ crossbeam-channel.workspace = true parse_int.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true diff --git a/cmd/console-proxy/src/lib.rs b/cmd/console-proxy/src/lib.rs index caf09c5bb..aa22d8804 100644 --- a/cmd/console-proxy/src/lib.rs +++ b/cmd/console-proxy/src/lib.rs @@ -6,12 +6,10 @@ //! //! Act as a proxy for the host serial console when it is jumpered to the SP. +use clap::Parser; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use std::path::PathBuf; -use clap::{CommandFactory, Parser}; - -use humility_cmd::Command; - #[cfg(not(windows))] mod posix; @@ -20,6 +18,7 @@ use posix::console_proxy; #[cfg(windows)] fn console_proxy( + _args: UartConsoleArgs, _context: &mut humility_cli::ExecutionContext, ) -> anyhow::Result<()> { anyhow::bail!("the console-proxy subcommand is not available on Windows") @@ -27,7 +26,7 @@ fn console_proxy( #[derive(Parser, Debug)] #[clap(name = "console-proxy", about = env!("CARGO_PKG_DESCRIPTION"))] -struct UartConsoleArgs { +pub struct UartConsoleArgs { #[clap( long, short = 'T', @@ -108,10 +107,9 @@ enum UartConsoleCommand { Client, } -pub fn init() -> Command { - Command { - app: UartConsoleArgs::command(), - name: "console-proxy", - run: console_proxy, +pub type Args = UartConsoleArgs; +impl HumilitySubcommand for UartConsoleArgs { + fn run(args: Args, context: &mut ExecutionContext) -> anyhow::Result<()> { + console_proxy(args, context) } } diff --git a/cmd/console-proxy/src/posix.rs b/cmd/console-proxy/src/posix.rs index 273bc3726..e469bd3e2 100644 --- a/cmd/console-proxy/src/posix.rs +++ b/cmd/console-proxy/src/posix.rs @@ -11,7 +11,6 @@ use std::time::Duration; use std::{io, thread}; use anyhow::{Context, Result}; -use clap::Parser; use crossbeam_channel::{Sender, select}; use picocom_map::RemapRules; use termios::Termios; @@ -284,8 +283,10 @@ impl UnrawTermiosGuard { } } -pub(super) fn console_proxy(context: &mut ExecutionContext) -> Result<()> { - let subargs = UartConsoleArgs::try_parse_from(&context.cli.cmd)?; +pub(super) fn console_proxy( + subargs: UartConsoleArgs, + context: &mut ExecutionContext, +) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; let mut worker = UartConsoleHandler::new( diff --git a/cmd/counters/Cargo.toml b/cmd/counters/Cargo.toml index be71743cb..f2d6b31bc 100644 --- a/cmd/counters/Cargo.toml +++ b/cmd/counters/Cargo.toml @@ -14,5 +14,4 @@ serde_json = { workspace = true } humility = { workspace = true } humility-doppel = { workspace = true, features = ["serde"] } -humility-cmd = { workspace = true } humility-cli = { workspace = true } diff --git a/cmd/counters/src/lib.rs b/cmd/counters/src/lib.rs index 55f6c1554..e6f9e899a 100644 --- a/cmd/counters/src/lib.rs +++ b/cmd/counters/src/lib.rs @@ -200,13 +200,12 @@ //! show only the calls to specific IPC interfaces from specific tasks. use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser, ValueEnum}; +use clap::{Parser, ValueEnum}; use colored::Colorize; use humility::core::Core; use humility::hubris::*; use humility::reflect::{self, Load, Value}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_doppel::{CountedRingbuf, CounterVariant, Counters}; use indexmap::IndexMap; use std::collections::BTreeMap; @@ -218,7 +217,7 @@ mod ipc; // This attribute means that any the args defined in `Options` will conflict // with the `list` subcommand. #[clap(args_conflicts_with_subcommands = true)] -struct CountersArgs { +pub struct CountersArgs { #[clap(subcommand)] command: Option, @@ -323,9 +322,11 @@ enum Output { const LIST_HINT: &str = "use `humility counters list` to list all \ available counters"; -fn counters(context: &mut ExecutionContext) -> Result<()> { +fn counters( + subargs: CountersArgs, + context: &mut ExecutionContext, +) -> Result<()> { let hubris = &context.cli.archive()?; - let subargs = CountersArgs::try_parse_from(&context.cli.cmd)?; if let Some(Subcmd::Ipc(ipc)) = subargs.command { let core = &mut *context.cli.attach_live_or_dump_match(hubris)?; @@ -622,6 +623,9 @@ fn hint() -> impl std::fmt::Display { "hint:".bold() } -pub fn init() -> Command { - Command { app: CountersArgs::command(), name: "counters", run: counters } +pub type Args = CountersArgs; +impl HumilitySubcommand for Args { + fn run(args: Self, context: &mut ExecutionContext) -> Result<()> { + counters(args, context) + } } diff --git a/cmd/dashboard/Cargo.toml b/cmd/dashboard/Cargo.toml index 5970dd82d..a807cb4fd 100644 --- a/cmd/dashboard/Cargo.toml +++ b/cmd/dashboard/Cargo.toml @@ -14,7 +14,6 @@ crossterm.workspace = true ratatui.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true diff --git a/cmd/dashboard/src/lib.rs b/cmd/dashboard/src/lib.rs index 22e5d222c..b606ec5c0 100644 --- a/cmd/dashboard/src/lib.rs +++ b/cmd/dashboard/src/lib.rs @@ -13,7 +13,7 @@ //! use anyhow::{Result, anyhow, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use crossterm::{ event::{ self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, @@ -28,8 +28,7 @@ use crossterm::{ use hif::*; use humility::core::Core; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::*; use humility_idol::{self as idol, HubrisIdol}; use ratatui::{ @@ -51,7 +50,7 @@ use std::time::{Duration, Instant}; #[derive(Parser, Debug)] #[clap(name = "dashboard", about = env!("CARGO_PKG_DESCRIPTION"))] -struct DashboardArgs { +pub struct DashboardArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -735,8 +734,10 @@ where } } -fn dashboard(context: &mut ExecutionContext) -> Result<()> { - let subargs = DashboardArgs::try_parse_from(&context.cli.cmd)?; +fn dashboard( + subargs: DashboardArgs, + context: &mut ExecutionContext, +) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; @@ -765,10 +766,6 @@ fn dashboard(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: DashboardArgs::command(), name: "dashboard", run: dashboard } -} - fn sensor_ops( hubris: &HubrisArchive, context: &mut HiffyContext, @@ -1085,3 +1082,10 @@ fn draw(f: &mut Frame, dashboard: &mut Dashboard) { draw_graphs(f, screen[0], dashboard); draw_status(f, screen[1], &dashboard.status()); } + +pub type Args = DashboardArgs; +impl HumilitySubcommand for Args { + fn run(args: Self, context: &mut ExecutionContext) -> Result<()> { + dashboard(args, context) + } +} diff --git a/cmd/debugmailbox/Cargo.toml b/cmd/debugmailbox/Cargo.toml index a485a477c..2fd66f775 100644 --- a/cmd/debugmailbox/Cargo.toml +++ b/cmd/debugmailbox/Cargo.toml @@ -12,5 +12,4 @@ parse_int.workspace = true probe-rs.workspace = true humility-cortex.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true diff --git a/cmd/debugmailbox/src/lib.rs b/cmd/debugmailbox/src/lib.rs index 6de6a9011..3533efa9f 100644 --- a/cmd/debugmailbox/src/lib.rs +++ b/cmd/debugmailbox/src/lib.rs @@ -30,9 +30,8 @@ use std::{ use anyhow::{Context, Result, bail}; use byteorder::{ByteOrder, LittleEndian, WriteBytesExt}; -use clap::{CommandFactory, Parser}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use clap::Parser; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use probe_rs::{ DebugProbeError, DebugProbeSelector, Probe, architecture::arm::{ApAddress, ArmProbeInterface, DapError, DpAddress}, @@ -265,9 +264,10 @@ fn read_return<'a>( .context("Reading debugmailbox RETURN register") } -fn debugmailboxcmd(context: &mut ExecutionContext) -> Result<()> { - let subargs = DebugMailboxArgs::try_parse_from(&context.cli.cmd)?; - +fn debugmailboxcmd( + subargs: DebugMailboxArgs, + context: &mut ExecutionContext, +) -> Result<()> { // Get a list of all available debug probes. let probes = Probe::list_all(); @@ -454,15 +454,14 @@ fn debugmailboxcmd(context: &mut ExecutionContext) -> Result<()> { } #[derive(Parser, Debug)] #[clap(name = "debugmailbox", about = env!("CARGO_PKG_DESCRIPTION"))] -struct DebugMailboxArgs { +pub struct DebugMailboxArgs { #[clap(subcommand)] cmd: DebugMailboxCmd, } -pub fn init() -> Command { - Command { - app: DebugMailboxArgs::command(), - name: "debugmailbox", - run: debugmailboxcmd, +pub type Args = DebugMailboxArgs; +impl HumilitySubcommand for Args { + fn run(args: Self, context: &mut ExecutionContext) -> Result<()> { + debugmailboxcmd(args, context) } } diff --git a/cmd/diagnose/Cargo.toml b/cmd/diagnose/Cargo.toml index 734262d11..bb666c421 100644 --- a/cmd/diagnose/Cargo.toml +++ b/cmd/diagnose/Cargo.toml @@ -10,7 +10,6 @@ anyhow.workspace = true parse_int.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-doppel.workspace = true humility-jefe.workspace = true diff --git a/cmd/diagnose/src/lib.rs b/cmd/diagnose/src/lib.rs index fc2f7ccfa..7a090391a 100644 --- a/cmd/diagnose/src/lib.rs +++ b/cmd/diagnose/src/lib.rs @@ -15,23 +15,17 @@ //! at the OS level, like faults. use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::core::Core; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_doppel::{GenOrRestartCount, Task, TaskDesc, TaskState}; use std::num::NonZeroU32; use std::time::Duration; -/// Command registration. -pub fn init() -> Command { - Command { app: DiagnoseArgs::command(), name: "diagnose", run: diagnose } -} - #[derive(Parser, Debug)] #[clap(name = "diagnose", about = env!("CARGO_PKG_DESCRIPTION"))] -struct DiagnoseArgs { +pub struct DiagnoseArgs { /// timeout to wait for interactions with the supervisor task to complete #[clap( long, short, default_value_t = 5000, value_name = "timeout_ms", @@ -72,8 +66,10 @@ fn section(title: &str) { println!("\n--- {} ---\n", title); } -fn diagnose(context: &mut ExecutionContext) -> Result<()> { - let subargs = DiagnoseArgs::try_parse_from(&context.cli.cmd)?; +fn diagnose( + subargs: DiagnoseArgs, + context: &mut ExecutionContext, +) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_or_dump_booted(hubris)?; @@ -381,3 +377,10 @@ fn find_task_names<'a>( }) .collect()) } + +pub type Args = DiagnoseArgs; +impl HumilitySubcommand for Args { + fn run(args: Self, context: &mut ExecutionContext) -> Result<()> { + diagnose(args, context) + } +} diff --git a/cmd/discover/Cargo.toml b/cmd/discover/Cargo.toml index ee7b54bc1..38fb4134d 100644 --- a/cmd/discover/Cargo.toml +++ b/cmd/discover/Cargo.toml @@ -6,7 +6,6 @@ description = "listen for compatible SPs on a network" [dependencies] humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true hubpack.workspace = true diff --git a/cmd/discover/src/lib.rs b/cmd/discover/src/lib.rs index 8d981ba51..e1f116d1b 100644 --- a/cmd/discover/src/lib.rs +++ b/cmd/discover/src/lib.rs @@ -40,12 +40,11 @@ use std::net::{IpAddr, Ipv6Addr, UdpSocket}; use std::time::{Duration, Instant}; use anyhow::{Result, bail}; -use clap::{ArgGroup, CommandFactory, Parser}; +use clap::{ArgGroup, Parser}; use colored::Colorize; use hubpack::SerializedSize; use humility::net::decode_iface; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use serde::{Deserialize, Serialize}; #[derive(Parser, Debug)] @@ -53,7 +52,7 @@ use serde::{Deserialize, Serialize}; name = "discover", about = env!("CARGO_PKG_DESCRIPTION"), group = ArgGroup::new("target").multiple(false) )] -struct DiscoverArgs { +pub struct DiscoverArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 2000, value_name = "timeout_ms", @@ -311,8 +310,10 @@ fn discover_dump(seen: BTreeSet, image_id: Option<&[u8]>) { } } -fn discover_run(context: &mut ExecutionContext) -> Result<()> { - let subargs = DiscoverArgs::try_parse_from(&context.cli.cmd)?; +fn discover_run( + subargs: DiscoverArgs, + context: &mut ExecutionContext, +) -> Result<()> { let hubris = &context.cli.try_archive()?; let image_id = hubris.as_ref().map(|h| h.image_id()); @@ -325,10 +326,9 @@ fn discover_run(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { - app: DiscoverArgs::command(), - name: "discover", - run: discover_run, +pub type Args = DiscoverArgs; +impl HumilitySubcommand for Args { + fn run(args: Self, context: &mut ExecutionContext) -> Result<()> { + discover_run(args, context) } } diff --git a/cmd/doc/Cargo.toml b/cmd/doc/Cargo.toml index 341ec551a..a7a29d1d6 100644 --- a/cmd/doc/Cargo.toml +++ b/cmd/doc/Cargo.toml @@ -10,7 +10,6 @@ cargo-readme = { workspace = true } anyhow = { workspace = true } [dependencies] -humility-cmd = { workspace = true } humility-cli = { workspace = true } clap = { workspace = true } anyhow = { workspace = true } diff --git a/cmd/doc/src/lib.rs b/cmd/doc/src/lib.rs index 7a5982d61..0e23f51ca 100644 --- a/cmd/doc/src/lib.rs +++ b/cmd/doc/src/lib.rs @@ -11,9 +11,8 @@ //! use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use clap::Parser; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use std::collections::HashMap; use termimad::*; @@ -21,15 +20,13 @@ include!(concat!(env!("OUT_DIR"), "/docs.rs")); #[derive(Parser, Debug)] #[clap(name = "doc", about = env!("CARGO_PKG_DESCRIPTION"))] -struct DocArgs { +pub struct DocArgs { /// Humility command for which to get documentation #[clap(value_name = "command")] command: Option, } -fn doc(context: &mut ExecutionContext) -> Result<()> { - let subargs = DocArgs::try_parse_from(&context.cli.cmd)?; - +fn doc(subargs: DocArgs, _context: &mut ExecutionContext) -> Result<()> { let text = match subargs.command { Some(ref cmd) => match cmd_docs(cmd) { Some(text) => text, @@ -63,6 +60,9 @@ fn doc(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: DocArgs::command(), name: "doc", run: doc } +pub type Args = DocArgs; +impl HumilitySubcommand for Args { + fn run(args: Self, context: &mut ExecutionContext) -> Result<()> { + doc(args, context) + } } diff --git a/cmd/dump/Cargo.toml b/cmd/dump/Cargo.toml index 3e601dcd2..a99a6a2e7 100644 --- a/cmd/dump/Cargo.toml +++ b/cmd/dump/Cargo.toml @@ -20,7 +20,6 @@ zerocopy.workspace = true zip.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-dump-agent.workspace = true humility-arch-arm.workspace = true diff --git a/cmd/dump/src/lib.rs b/cmd/dump/src/lib.rs index b2de98c63..35958adb1 100644 --- a/cmd/dump/src/lib.rs +++ b/cmd/dump/src/lib.rs @@ -66,12 +66,11 @@ //! use anyhow::{Result, bail}; -use clap::{ArgGroup, CommandFactory, Parser}; +use clap::{ArgGroup, Parser}; use humility::core::Core; use humility::hubris::*; use humility_arch_arm::ARMRegister; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_dump_agent::{ DumpAgent, DumpAgentCore, DumpAgentExt, DumpArea, DumpBreakdown, HiffyDumpAgent, UdpDumpAgent, task_areas, @@ -89,7 +88,7 @@ use std::time::Instant; group = ArgGroup::new("simulation").multiple(false) .required(false).requires("force_dump_agent") )] -struct DumpArgs { +pub struct DumpArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 20000, value_name = "timeout_ms", @@ -850,8 +849,7 @@ fn dump_agent_status( Ok(()) } -fn dumpcmd(context: &mut ExecutionContext) -> Result<()> { - let subargs = DumpArgs::try_parse_from(&context.cli.cmd)?; +fn dumpcmd(subargs: DumpArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_match(hubris)?; @@ -897,6 +895,9 @@ fn dumpcmd(context: &mut ExecutionContext) -> Result<()> { } } -pub fn init() -> Command { - Command { app: DumpArgs::command(), name: "dump", run: dumpcmd } +pub type Args = DumpArgs; +impl HumilitySubcommand for Args { + fn run(args: Self, context: &mut ExecutionContext) -> Result<()> { + dumpcmd(args, context) + } } diff --git a/cmd/ereport/Cargo.toml b/cmd/ereport/Cargo.toml index 5039d9d03..9cea9069f 100644 --- a/cmd/ereport/Cargo.toml +++ b/cmd/ereport/Cargo.toml @@ -14,6 +14,5 @@ serde_json.workspace = true zerocopy.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-doppel.workspace = true diff --git a/cmd/ereport/src/lib.rs b/cmd/ereport/src/lib.rs index fa145d074..96e70de0e 100644 --- a/cmd/ereport/src/lib.rs +++ b/cmd/ereport/src/lib.rs @@ -10,18 +10,17 @@ use humility::{ core::Core, hubris::{HubrisArchive, HubrisTask}, }; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use anyhow::{Context, Result, anyhow}; use std::collections::VecDeque; use zerocopy::{FromBytes, Immutable, KnownLayout}; -use clap::{CommandFactory, Parser}; +use clap::Parser; #[derive(Parser, Debug)] #[clap(name = "ereport", about = env!("CARGO_PKG_DESCRIPTION"))] -struct EreportArgs { +pub struct EreportArgs { #[clap(subcommand)] cmd: EreportCmd, } @@ -336,8 +335,7 @@ fn pretty_print_value(value: &ciborium::Value, indent: usize, is_key: bool) { } } -fn ereport(context: &mut ExecutionContext) -> Result<()> { - let subargs = EreportArgs::try_parse_from(&context.cli.cmd)?; +fn ereport(subargs: EreportArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_or_dump_booted(hubris)?; @@ -346,6 +344,9 @@ fn ereport(context: &mut ExecutionContext) -> Result<()> { } } -pub fn init() -> Command { - Command { app: EreportArgs::command(), name: "ereport", run: ereport } +pub type Args = EreportArgs; +impl HumilitySubcommand for Args { + fn run(args: Self, context: &mut ExecutionContext) -> Result<()> { + ereport(args, context) + } } diff --git a/cmd/exec/Cargo.toml b/cmd/exec/Cargo.toml index d826660b0..b7d4ad1eb 100644 --- a/cmd/exec/Cargo.toml +++ b/cmd/exec/Cargo.toml @@ -11,5 +11,4 @@ splitty.workspace = true serde_json.workspace = true humility-log.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true diff --git a/cmd/exec/src/lib.rs b/cmd/exec/src/lib.rs index a237a50b9..cf8176f82 100644 --- a/cmd/exec/src/lib.rs +++ b/cmd/exec/src/lib.rs @@ -22,16 +22,15 @@ //! use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use clap::Parser; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_log::msg; use serde_json::Value; use std::collections::BTreeMap; #[derive(Parser, Debug)] #[clap(name = "exec", about = env!("CARGO_PKG_DESCRIPTION"))] -struct ExecArgs { +pub struct ExecArgs { /// list possible commands #[clap(long, short)] list: bool, @@ -71,8 +70,7 @@ fn load_cmds<'a>( Ok(()) } -fn exec(context: &mut ExecutionContext) -> Result<()> { - let subargs = ExecArgs::try_parse_from(&context.cli.cmd)?; +fn exec(subargs: ExecArgs, context: &mut ExecutionContext) -> Result<()> { let env = context.environment.as_ref(); let env = match env { @@ -142,6 +140,9 @@ fn exec(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: ExecArgs::command(), name: "exec", run: exec } +pub type Args = ExecArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + exec(args, context) + } } diff --git a/cmd/extract/Cargo.toml b/cmd/extract/Cargo.toml index 9cf92747e..5fb9c1c93 100644 --- a/cmd/extract/Cargo.toml +++ b/cmd/extract/Cargo.toml @@ -10,5 +10,4 @@ clap.workspace = true zip.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true humility-log.workspace = true diff --git a/cmd/extract/src/lib.rs b/cmd/extract/src/lib.rs index 96ca5a990..7b3bf49ba 100644 --- a/cmd/extract/src/lib.rs +++ b/cmd/extract/src/lib.rs @@ -130,9 +130,8 @@ //! use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use clap::Parser; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_log::msg; use std::fs::File; use std::io::Cursor; @@ -140,7 +139,7 @@ use std::io::{self, Read, Write}; #[derive(Parser, Debug)] #[clap(name = "extract", about = env!("CARGO_PKG_DESCRIPTION"))] -struct ExtractArgs { +pub struct ExtractArgs { /// list contents #[clap(long, short)] list: bool, @@ -153,8 +152,7 @@ struct ExtractArgs { file: Option, } -fn extract(context: &mut ExecutionContext) -> Result<()> { - let subargs = ExtractArgs::try_parse_from(&context.cli.cmd)?; +fn extract(subargs: ExtractArgs, context: &mut ExecutionContext) -> Result<()> { let archive = context.cli.raw_archive()?; if subargs.list { @@ -235,6 +233,9 @@ fn extract(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: ExtractArgs::command(), name: "extract", run: extract } +pub type Args = ExtractArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + extract(args, context) + } } diff --git a/cmd/flash/Cargo.toml b/cmd/flash/Cargo.toml index 5be8ddc1e..1163fb1cf 100644 --- a/cmd/flash/Cargo.toml +++ b/cmd/flash/Cargo.toml @@ -7,7 +7,6 @@ description = "flash archive onto attached device" [dependencies] humility = { workspace = true } humility-cortex = { workspace = true } -humility-cmd = { workspace = true } humility-cli = { workspace = true } humility-probes-core = { workspace = true } humility-auxflash = { workspace = true } diff --git a/cmd/flash/src/lib.rs b/cmd/flash/src/lib.rs index 6e23f982b..4c576e261 100644 --- a/cmd/flash/src/lib.rs +++ b/cmd/flash/src/lib.rs @@ -20,15 +20,14 @@ //! information about auxiliary flash management. use anyhow::{Context, Result, anyhow, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::{core::Core, hubris::*}; use humility_auxflash::AuxFlashHandler; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; #[derive(Parser, Debug)] #[clap(name = "flash", about = env!("CARGO_PKG_DESCRIPTION"))] -struct FlashArgs { +pub struct FlashArgs { /// force re-flashing if archive matches #[clap(long, short = 'F')] force: bool, @@ -188,9 +187,8 @@ fn get_image_state( } } -fn flashcmd(context: &mut ExecutionContext) -> Result<()> { +fn flashcmd(subargs: FlashArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; - let subargs = FlashArgs::try_parse_from(&context.cli.cmd)?; let config = hubris.load_flash_config()?; @@ -344,10 +342,6 @@ fn program_auxflash( } } -pub fn init() -> Command { - Command { app: FlashArgs::command(), name: "flash", run: flashcmd } -} - /// While it may sound like the impetus for an OSHA investigation at the North /// Pole, this function is _actually_ designed to generate small (32-byte) /// chunks describing the data in the PHDRs of an ELF file. Unless the file is @@ -413,3 +407,10 @@ fn generate_ihex_from_elf(data: &[u8]) -> Result { Ok(ihex::create_object_file_representation(&records)?) } + +pub type Args = FlashArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + flashcmd(args, context) + } +} diff --git a/cmd/gimlet/src/lib.rs b/cmd/gimlet/src/lib.rs index 16ace5f58..940ac577e 100644 --- a/cmd/gimlet/src/lib.rs +++ b/cmd/gimlet/src/lib.rs @@ -17,10 +17,10 @@ use std::net::{SocketAddrV6, UdpSocket}; use std::time::Duration; use anyhow::{Context, Result, bail}; -use clap::{ArgGroup, CommandFactory, Parser}; +use clap::{ArgGroup, Parser}; use humility::net::ScopedV6Addr; -use humility_cli::ExecutionContext; -use humility_cmd::{Command, Dumper}; +use humility_cli::{ExecutionContext, HumilitySubcommand}; +use humility_cmd::Dumper; /// This is defined in the gimlet TOML. const HARDCODED_PORT: u16 = 23547; @@ -30,7 +30,7 @@ const HARDCODED_PORT: u16 = 23547; name = "gimlet", about = env!("CARGO_PKG_DESCRIPTION"), group = ArgGroup::new("target").multiple(false) )] -struct Args { +pub struct Args { /// How long to wait for a response from the target, in milliseconds. #[clap( long, short = 'T', default_value_t = 2000, value_name = "ms", @@ -101,7 +101,7 @@ impl Client { } } -fn run(context: &mut ExecutionContext) -> Result<()> { +fn run(subargs: Args, context: &mut ExecutionContext) -> Result<()> { let ip = context .cli .ip @@ -113,7 +113,6 @@ fn run(context: &mut ExecutionContext) -> Result<()> { "the `--ip ` argument is required with `humility gimlet`" ) })?; - let subargs = Args::try_parse_from(&context.cli.cmd)?; let mut client = Client::new(ip, subargs.port, Duration::from_millis(subargs.timeout))?; @@ -132,6 +131,8 @@ fn run(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: Args::command(), name: "gimlet", run } +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + run(args, context) + } } diff --git a/cmd/gpio/Cargo.toml b/cmd/gpio/Cargo.toml index 24a585095..0e4ddd660 100644 --- a/cmd/gpio/Cargo.toml +++ b/cmd/gpio/Cargo.toml @@ -11,5 +11,4 @@ anyhow.workspace = true parse_int.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true humility-hiffy.workspace = true diff --git a/cmd/gpio/src/lib.rs b/cmd/gpio/src/lib.rs index 23c6164e4..69dab3702 100644 --- a/cmd/gpio/src/lib.rs +++ b/cmd/gpio/src/lib.rs @@ -92,20 +92,19 @@ //! ``` //! -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::HiffyContext; use std::str; use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use hif::*; use std::convert::TryInto; #[derive(Parser, Debug)] #[clap(name = "gpio", about = env!("CARGO_PKG_DESCRIPTION"))] -struct GpioArgs { +pub struct GpioArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -149,8 +148,7 @@ struct GpioArgs { pins: Option>, } -fn gpio(context: &mut ExecutionContext) -> Result<()> { - let subargs = GpioArgs::try_parse_from(&context.cli.cmd)?; +fn gpio(subargs: GpioArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; let mut context = HiffyContext::new(hubris, core, subargs.timeout)?; @@ -326,6 +324,9 @@ fn gpio(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: GpioArgs::command(), name: "gpio", run: gpio } +pub type Args = GpioArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + gpio(args, context) + } } diff --git a/cmd/hash/Cargo.toml b/cmd/hash/Cargo.toml index b556d3a5b..bebdcb2dd 100644 --- a/cmd/hash/Cargo.toml +++ b/cmd/hash/Cargo.toml @@ -13,6 +13,5 @@ parse_int.workspace = true indicatif.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-hiffy.workspace = true diff --git a/cmd/hash/src/lib.rs b/cmd/hash/src/lib.rs index f25243401..c99933c0e 100644 --- a/cmd/hash/src/lib.rs +++ b/cmd/hash/src/lib.rs @@ -17,10 +17,9 @@ //! use anyhow::{Context, Result, anyhow, bail}; -use clap::{ArgGroup, CommandFactory, Parser}; +use clap::{ArgGroup, Parser}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::*; use sha2::{Digest, Sha256}; use std::fs::File; @@ -36,7 +35,7 @@ use indicatif::{ProgressBar, ProgressStyle}; group = ArgGroup::new("command").multiple(false), group = ArgGroup::new("data").multiple(false) )] -struct HashArgs { +pub struct HashArgs { /// Initialize the hash block and optionally provide a length. #[clap(long, short)] // not in group "command" to allow -i update init: bool, @@ -92,8 +91,7 @@ struct HashArgs { long: bool, } -fn hash(context: &mut ExecutionContext) -> Result<()> { - let subargs = HashArgs::try_parse_from(&context.cli.cmd)?; +fn hash(subargs: HashArgs, context: &mut ExecutionContext) -> Result<()> { let archive = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(archive)?; @@ -473,6 +471,9 @@ fn print_hash(buf: &[u8]) { } } -pub fn init() -> Command { - Command { app: HashArgs::command(), name: "hash", run: hash } +pub type Args = HashArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + hash(args, context) + } } diff --git a/cmd/hiffy/src/lib.rs b/cmd/hiffy/src/lib.rs index feccc11d1..24788ab58 100644 --- a/cmd/hiffy/src/lib.rs +++ b/cmd/hiffy/src/lib.rs @@ -47,11 +47,11 @@ use ::idol::syntax::send::{Operation, Reply}; use anyhow::{Context, Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::hubris::*; use humility::warn; -use humility_cli::ExecutionContext; -use humility_cmd::{Command, Dumper}; +use humility_cli::{ExecutionContext, HumilitySubcommand}; +use humility_cmd::Dumper; use humility_hiffy::*; use humility_idol as idol; use std::io::IsTerminal; @@ -59,7 +59,7 @@ use std::io::Read; #[derive(Parser, Debug)] #[clap(name = "hiffy", about = env!("CARGO_PKG_DESCRIPTION"))] -struct HiffyArgs { +pub struct HiffyArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -199,8 +199,7 @@ pub fn hiffy_list(hubris: &HubrisArchive, filter: Vec) -> Result<()> { Ok(()) } -fn hiffy(context: &mut ExecutionContext) -> Result<()> { - let subargs = HiffyArgs::try_parse_from(&context.cli.cmd)?; +fn hiffy(subargs: HiffyArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; if subargs.list { @@ -347,6 +346,9 @@ fn hiffy(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: HiffyArgs::command(), name: "hiffy", run: hiffy } +pub type Args = HiffyArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + hiffy(args, context) + } } diff --git a/cmd/host/Cargo.toml b/cmd/host/Cargo.toml index 5f8069ccb..b688bcb2d 100644 --- a/cmd/host/Cargo.toml +++ b/cmd/host/Cargo.toml @@ -10,13 +10,12 @@ description = "Pretty-printing of host state" anyhow.workspace = true chrono.workspace = true clap.workspace = true +turin-post-decoder.workspace = true hif.workspace = true ipcc-data.workspace = true -turin-post-decoder.workspace = true humility.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true humility-doppel.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true diff --git a/cmd/host/src/lib.rs b/cmd/host/src/lib.rs index 1d8802df7..3e91968b7 100644 --- a/cmd/host/src/lib.rs +++ b/cmd/host/src/lib.rs @@ -102,11 +102,10 @@ use anyhow::{Result, anyhow}; use chrono::DateTime; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::{core::Core, hubris::HubrisArchive, reflect, reflect::Load}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_doppel as doppel; use humility_hiffy::HiffyContext; use humility_idol::HubrisIdol; @@ -141,7 +140,7 @@ enum CosmoHostCommand { #[derive(Parser, Debug)] #[clap(name = "host", about = env!("CARGO_PKG_DESCRIPTION"))] -struct HostArgs { +pub struct HostArgs { #[clap(subcommand)] cmd: HostCommand, } @@ -449,8 +448,7 @@ fn host_last_post_code( Ok(()) } -fn host(context: &mut ExecutionContext) -> Result<()> { - let subargs = HostArgs::try_parse_from(&context.cli.cmd)?; +fn host(subargs: HostArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; match subargs.cmd { @@ -479,6 +477,9 @@ fn host(context: &mut ExecutionContext) -> Result<()> { } } -pub fn init() -> Command { - Command { app: HostArgs::command(), name: "host", run: host } +pub type Args = HostArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + host(args, context) + } } diff --git a/cmd/hydrate/Cargo.toml b/cmd/hydrate/Cargo.toml index b2d3b17de..948a4ab8f 100644 --- a/cmd/hydrate/Cargo.toml +++ b/cmd/hydrate/Cargo.toml @@ -8,7 +8,6 @@ description = "Rehydrate a bare memory dump" humility.workspace = true humility-arch-arm.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true humility-log.workspace = true hubpack.workspace = true diff --git a/cmd/hydrate/src/lib.rs b/cmd/hydrate/src/lib.rs index ccf4804b3..2bb1998bf 100644 --- a/cmd/hydrate/src/lib.rs +++ b/cmd/hydrate/src/lib.rs @@ -18,11 +18,10 @@ //! lowest available value); use `--out` to specify a different path name. use anyhow::{Context, Result, bail}; -use clap::{ArgGroup, CommandFactory, Parser}; +use clap::{ArgGroup, Parser}; use humility::hubris::HubrisFlashMap; use humility_arch_arm::ARMRegister; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_log::msg; use std::{collections::BTreeMap, io::Read, path::PathBuf}; @@ -31,7 +30,7 @@ use std::{collections::BTreeMap, io::Read, path::PathBuf}; name = "hydrate", about = env!("CARGO_PKG_DESCRIPTION"), group = ArgGroup::new("target").multiple(false) )] -struct Args { +pub struct Args { /// Path to write the resulting dump #[clap(short, long)] out: Option, @@ -108,8 +107,7 @@ impl humility::core::Core for DryCore { } } -fn run(context: &mut ExecutionContext) -> Result<()> { - let subargs = Args::try_parse_from(&context.cli.cmd)?; +fn run(subargs: Args, context: &mut ExecutionContext) -> Result<()> { let f = std::fs::File::open(&subargs.file)?; let mut z = zip::ZipArchive::new(f)?; @@ -195,6 +193,8 @@ fn run(context: &mut ExecutionContext) -> Result<()> { ) } -pub fn init() -> Command { - Command { app: Args::command(), name: "hydrate", run } +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + run(args, context) + } } diff --git a/cmd/i2c/src/lib.rs b/cmd/i2c/src/lib.rs index 6e008ccb0..b4cbd402a 100644 --- a/cmd/i2c/src/lib.rs +++ b/cmd/i2c/src/lib.rs @@ -91,10 +91,10 @@ //! ``` use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use hif::*; -use humility_cli::ExecutionContext; -use humility_cmd::{Command, Dumper}; +use humility_cli::{ExecutionContext, HumilitySubcommand}; +use humility_cmd::Dumper; use humility_hiffy::*; use humility_log::msg; @@ -423,8 +423,7 @@ fn i2c_done( Ok(()) } -fn i2c(context: &mut ExecutionContext) -> Result<()> { - let subargs = I2cArgs::try_parse_from(&context.cli.cmd)?; +fn i2c(subargs: I2cArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; if !subargs.scan @@ -709,6 +708,9 @@ fn i2c(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: I2cArgs::command(), name: "i2c", run: i2c } +pub type Args = I2cArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + i2c(args, context) + } } diff --git a/cmd/ibc/src/lib.rs b/cmd/ibc/src/lib.rs index 2a88121fd..b4f1c5315 100644 --- a/cmd/ibc/src/lib.rs +++ b/cmd/ibc/src/lib.rs @@ -101,9 +101,9 @@ //! use anyhow::{Result, anyhow, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use colored::Colorize; -use humility_cli::ExecutionContext; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_idol::{self as idol, HubrisIdol}; use zerocopy::{ FromBytes, Immutable, IntoBytes, KnownLayout, @@ -114,12 +114,11 @@ use hif::*; use humility::core::Core; use humility::hubris::*; -use humility_cmd::Command; use humility_hiffy::HiffyContext; #[derive(Parser, Debug)] #[clap(name = "ibc", about = env!("CARGO_PKG_DESCRIPTION"))] -struct IbcArgs { +pub struct IbcArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 15000, value_name = "timeout_ms", @@ -513,8 +512,7 @@ struct IbcEvent { //////////////////////////////////////////////////////////////////////////////// -fn ibc(context: &mut ExecutionContext) -> Result<()> { - let subargs = IbcArgs::try_parse_from(&context.cli.cmd)?; +fn ibc(subargs: IbcArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; let mut worker = IbcHandler::new(hubris, core, subargs.timeout)?; @@ -527,6 +525,9 @@ fn ibc(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: IbcArgs::command(), name: "ibc", run: ibc } +pub type Args = IbcArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + ibc(args, context) + } } diff --git a/cmd/jefe/Cargo.toml b/cmd/jefe/Cargo.toml index 3c598dd5c..9ea82211f 100644 --- a/cmd/jefe/Cargo.toml +++ b/cmd/jefe/Cargo.toml @@ -10,6 +10,5 @@ clap.workspace = true parse_int.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-jefe.workspace = true diff --git a/cmd/jefe/src/lib.rs b/cmd/jefe/src/lib.rs index 503cf5798..31ef5acd5 100644 --- a/cmd/jefe/src/lib.rs +++ b/cmd/jefe/src/lib.rs @@ -95,16 +95,15 @@ //! normal, or `--start`/`-s` to run it once but catch the next fault. use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_jefe::{JefeRequest, send_request}; use std::num::NonZeroU32; #[derive(Parser, Debug)] #[clap(name = "jefe", about = env!("CARGO_PKG_DESCRIPTION"))] -struct JefeArgs { +pub struct JefeArgs { /// sets timeout #[clap( long, short, default_value_t = 5000, value_name = "timeout_ms", @@ -131,8 +130,7 @@ struct JefeArgs { task: String, } -fn jefe(context: &mut ExecutionContext) -> Result<()> { - let subargs = JefeArgs::try_parse_from(&context.cli.cmd)?; +fn jefe(subargs: JefeArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; @@ -170,6 +168,9 @@ fn jefe(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: JefeArgs::command(), name: "jefe", run: jefe } +pub type Args = JefeArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + jefe(args, context) + } } diff --git a/cmd/lpc55gpio/src/lib.rs b/cmd/lpc55gpio/src/lib.rs index ec05a3503..ea6f0e4c3 100644 --- a/cmd/lpc55gpio/src/lib.rs +++ b/cmd/lpc55gpio/src/lib.rs @@ -102,20 +102,19 @@ //! ``` //! -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::*; use std::str; use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use hif::*; use std::convert::TryInto; #[derive(Parser, Debug)] #[clap(name = "lpc55gpio", about = "GPIO pin manipulation (lpc55 variant)")] -struct GpioArgs { +pub struct GpioArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -163,8 +162,7 @@ struct GpioArgs { pins: Option>, } -fn gpio(context: &mut ExecutionContext) -> Result<()> { - let subargs = GpioArgs::try_parse_from(&context.cli.cmd)?; +fn gpio(subargs: GpioArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; let mut context = HiffyContext::new(hubris, core, subargs.timeout)?; @@ -310,6 +308,9 @@ fn gpio(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: GpioArgs::command(), name: "lpc55gpio", run: gpio } +pub type Args = GpioArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + gpio(args, context) + } } diff --git a/cmd/lsusb/Cargo.toml b/cmd/lsusb/Cargo.toml index 6117765df..b7c3e4957 100644 --- a/cmd/lsusb/Cargo.toml +++ b/cmd/lsusb/Cargo.toml @@ -6,7 +6,6 @@ description = "List all USB devices visible to Humility" [dependencies] humility = { workspace = true } -humility-cmd = { workspace = true } humility-cli = { workspace = true } clap = { workspace = true } anyhow = { workspace = true } diff --git a/cmd/lsusb/src/lib.rs b/cmd/lsusb/src/lib.rs index 4a52c7283..321061144 100644 --- a/cmd/lsusb/src/lib.rs +++ b/cmd/lsusb/src/lib.rs @@ -8,20 +8,18 @@ //! on the system, to help you choose probes and/or diagnose permissions issues. use anyhow::{Context, Result, anyhow}; -use clap::{CommandFactory, Parser}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use clap::Parser; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use std::collections::HashMap; use std::time::Duration; #[derive(Parser, Debug)] #[clap(name = "lsusb", about = env!("CARGO_PKG_DESCRIPTION"))] -struct Args { +pub struct Args { // None as yet } -fn lsusb(context: &mut ExecutionContext) -> Result<()> { - let _subargs = Args::try_parse_from(&context.cli.cmd)?; +fn lsusb(_args: Args, context: &mut ExecutionContext) -> Result<()> { let mut targets = if let Some(ref env) = context.cli.environment { humility_cli::env::Environment::read(env) .with_context(|| { @@ -140,6 +138,8 @@ fn list1( Ok((format!("{vid:04x}:{pid:04x}:{serial}"), format!("{man}\t{prod}"))) } -pub fn init() -> Command { - Command { app: Args::command(), name: "lsusb", run: lsusb } +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + lsusb(args, context) + } } diff --git a/cmd/manifest/Cargo.toml b/cmd/manifest/Cargo.toml index 49b272c33..0b7039e4d 100644 --- a/cmd/manifest/Cargo.toml +++ b/cmd/manifest/Cargo.toml @@ -6,7 +6,6 @@ description = "print archive manifest" [dependencies] humility = { workspace = true } -humility-cmd = { workspace = true } humility-cli = { workspace = true } clap = { workspace = true } anyhow = { workspace = true } diff --git a/cmd/manifest/src/lib.rs b/cmd/manifest/src/lib.rs index 4178ab759..b8891f4cd 100644 --- a/cmd/manifest/src/lib.rs +++ b/cmd/manifest/src/lib.rs @@ -42,27 +42,27 @@ //! `humility manifest` can operate on either an archive or on a dump. use anyhow::Result; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use std::collections::HashSet; #[derive(Parser, Debug)] #[clap(name = "manifest", about = env!("CARGO_PKG_DESCRIPTION"))] -struct ManifestArgs { +pub struct ManifestArgs { /// generate JSON output #[clap(short, long)] json: bool, } #[allow(clippy::print_literal)] -fn manifestcmd(context: &mut ExecutionContext) -> Result<()> { +fn manifestcmd( + subargs: ManifestArgs, + context: &mut ExecutionContext, +) -> Result<()> { let hubris = context.cli.archive()?; let manifest = &hubris.manifest; - let subargs = ManifestArgs::try_parse_from(&context.cli.cmd)?; - if subargs.json { println!("{}", serde_json::to_string(manifest)?); return Ok(()); @@ -261,6 +261,9 @@ fn manifestcmd(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: ManifestArgs::command(), name: "manifest", run: manifestcmd } +pub type Args = ManifestArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + manifestcmd(args, context) + } } diff --git a/cmd/map/Cargo.toml b/cmd/map/Cargo.toml index de4ea59af..dacbe78fa 100644 --- a/cmd/map/Cargo.toml +++ b/cmd/map/Cargo.toml @@ -6,7 +6,6 @@ description = "print memory map, with association of regions to tasks" [dependencies] humility = { workspace = true } -humility-cmd = { workspace = true } humility-cli = { workspace = true } clap = { workspace = true } anyhow = { workspace = true } diff --git a/cmd/map/src/lib.rs b/cmd/map/src/lib.rs index 3ef6ae8fd..dc77fb7f7 100644 --- a/cmd/map/src/lib.rs +++ b/cmd/map/src/lib.rs @@ -62,15 +62,14 @@ //! we can see from the `map` output has been sized to only 256 bytes.) use anyhow::Result; -use clap::{CommandFactory, Parser}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use clap::Parser; +use humility_cli::{ExecutionContext, HumilitySubcommand}; #[derive(Parser, Debug)] #[clap(name = "map", about = env!("CARGO_PKG_DESCRIPTION"))] -struct MapArgs {} +pub struct MapArgs {} -fn mapcmd(context: &mut ExecutionContext) -> Result<()> { +fn mapcmd(_args: MapArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; // Use an archive core to easily read from flash @@ -135,6 +134,9 @@ fn mapcmd(context: &mut ExecutionContext) -> Result<()> { } /// This is some init right here -pub fn init() -> Command { - Command { app: MapArgs::command(), name: "map", run: mapcmd } +pub type Args = MapArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + mapcmd(args, context) + } } diff --git a/cmd/monorail/Cargo.toml b/cmd/monorail/Cargo.toml index e78d24651..8f62eaad0 100644 --- a/cmd/monorail/Cargo.toml +++ b/cmd/monorail/Cargo.toml @@ -18,7 +18,6 @@ parse_int.workspace = true regex.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true diff --git a/cmd/monorail/src/lib.rs b/cmd/monorail/src/lib.rs index 8280eb9c8..1af42866e 100644 --- a/cmd/monorail/src/lib.rs +++ b/cmd/monorail/src/lib.rs @@ -171,20 +171,20 @@ use std::convert::TryInto; use humility::core::Core; use humility::hubris::*; use humility::reflect::*; -use humility_cli::ExecutionContext; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::{HiffyContext, HiffyError}; use humility_idol::{HubrisIdol, IdolArgument}; use anyhow::{Result, anyhow}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use colored::Colorize; use vsc7448_info::parse::{PhyRegister, TargetRegister}; use vsc7448_types::Field; #[derive(Parser, Debug)] #[clap(name = "monorail", about = env!("CARGO_PKG_DESCRIPTION"))] -struct MonorailArgs { +pub struct MonorailArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -968,9 +968,10 @@ fn monorail_counters( Ok(()) } -fn monorail(context: &mut ExecutionContext) -> Result<()> { - let subargs = MonorailArgs::try_parse_from(&context.cli.cmd)?; - +fn monorail( + subargs: MonorailArgs, + context: &mut ExecutionContext, +) -> Result<()> { // Early exit for subcommands which don't require an archive or Core match &subargs.cmd { Command::Info { reg, value } => { @@ -1081,10 +1082,9 @@ fn monorail(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> humility_cmd::Command { - humility_cmd::Command { - app: MonorailArgs::command(), - name: "monorail", - run: monorail, +pub type Args = MonorailArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + monorail(args, context) } } diff --git a/cmd/mwocp/Cargo.toml b/cmd/mwocp/Cargo.toml index 4cb2fa7f7..31d4157df 100644 --- a/cmd/mwocp/Cargo.toml +++ b/cmd/mwocp/Cargo.toml @@ -17,7 +17,6 @@ pmbus.workspace = true zerocopy.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true humility-hiffy.workspace = true humility-i2c.workspace = true humility-idol.workspace = true diff --git a/cmd/mwocp/src/lib.rs b/cmd/mwocp/src/lib.rs index d46c835b2..435fc0b74 100644 --- a/cmd/mwocp/src/lib.rs +++ b/cmd/mwocp/src/lib.rs @@ -34,13 +34,12 @@ use humility::hubris::*; use humility::msg; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::*; use humility_i2c::I2cArgs; use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use hif::*; use indicatif::{HumanBytes, HumanDuration}; use indicatif::{ProgressBar, ProgressStyle}; @@ -53,7 +52,7 @@ use std::time::Instant; #[clap(name = "mwocp", about = env!("CARGO_PKG_DESCRIPTION"), group = clap::ArgGroup::new("subcommand").multiple(false) )] -struct MwocpArgs { +pub struct MwocpArgs { /// sets timeout #[clap( long, short, default_value_t = 5000, value_name = "timeout_ms", @@ -116,8 +115,7 @@ const MWOCP68_BLOCK_DELAY_MS: u8 = 100; const MWOCP68_CHECKSUM_DELAY: u64 = 2; const MWOCP68_REBOOT_DELAY: u64 = 5; -fn mwocp(context: &mut ExecutionContext) -> Result<()> { - let subargs = MwocpArgs::try_parse_from(&context.cli.cmd)?; +fn mwocp(subargs: MwocpArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; @@ -576,6 +574,9 @@ fn mwocp(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: MwocpArgs::command(), name: "mwocp", run: mwocp } +pub type Args = MwocpArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + mwocp(args, context) + } } diff --git a/cmd/net/Cargo.toml b/cmd/net/Cargo.toml index 47a04aee5..8e0bc27bc 100644 --- a/cmd/net/Cargo.toml +++ b/cmd/net/Cargo.toml @@ -15,7 +15,6 @@ parse_int.workspace = true colored.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true diff --git a/cmd/net/src/lib.rs b/cmd/net/src/lib.rs index 84c58ffec..624ca5c6c 100644 --- a/cmd/net/src/lib.rs +++ b/cmd/net/src/lib.rs @@ -40,14 +40,13 @@ use std::collections::BTreeMap; use anyhow::Result; -use clap::{CommandFactory, Parser}; +use clap::Parser; use colored::Colorize; use humility::core::Core; use humility::hubris::HubrisArchive; use humility::reflect::*; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::HiffyContext; use humility_idol::HubrisIdol; @@ -61,7 +60,7 @@ enum NetCommand { Status, /// Print the counters /// - /// This is a destructive operation that clears counter values, resetting + /// This is a depub structive operation that clears counter values, resetting /// them to zero. /// /// If no flags are provided, both the table and diagram are shown. @@ -77,7 +76,7 @@ enum NetCommand { #[derive(Parser, Debug)] #[clap(name = "net", about = env!("CARGO_PKG_DESCRIPTION"))] -struct NetArgs { +pub struct NetArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -524,9 +523,7 @@ fn net_counters_diagram(s: &Struct) -> Result<()> { Ok(()) } -fn net(context: &mut ExecutionContext) -> Result<()> { - let subargs = NetArgs::try_parse_from(&context.cli.cmd)?; - +fn net(subargs: NetArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; let hiffy_context = HiffyContext::new(hubris, core, subargs.timeout)?; @@ -542,6 +539,9 @@ fn net(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: NetArgs::command(), name: "net", run: net } +pub type Args = NetArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + net(args, context) + } } diff --git a/cmd/pmbus/Cargo.toml b/cmd/pmbus/Cargo.toml index ac6d5d429..35e529d2e 100644 --- a/cmd/pmbus/Cargo.toml +++ b/cmd/pmbus/Cargo.toml @@ -15,7 +15,6 @@ parse_int.workspace = true humility.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true humility-hiffy.workspace = true humility-i2c.workspace = true humility-idol.workspace = true diff --git a/cmd/pmbus/src/lib.rs b/cmd/pmbus/src/lib.rs index 7145b1401..8dad544b2 100644 --- a/cmd/pmbus/src/lib.rs +++ b/cmd/pmbus/src/lib.rs @@ -190,14 +190,13 @@ use colored::Colorize; use humility::hubris::*; use humility::{core::Core, warn}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::*; use humility_i2c::I2cArgs; use humility_idol::{HubrisIdol, IdolArgument, IdolOperation}; use anyhow::{Result, anyhow, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use hif::*; use indexmap::IndexMap; use pmbus::commands::*; @@ -207,7 +206,7 @@ use std::fmt::Write; #[derive(Parser, Debug)] #[clap(name = "pmbus", about = env!("CARGO_PKG_DESCRIPTION"))] -struct PmbusArgs { +pub struct PmbusArgs { /// sets timeout #[clap( long, short, default_value_t = 5000, value_name = "timeout_ms", @@ -1902,8 +1901,7 @@ impl PmbusWorker for IdolWorker<'_> { } #[allow(clippy::print_literal)] -fn pmbus(context: &mut ExecutionContext) -> Result<()> { - let subargs = PmbusArgs::try_parse_from(&context.cli.cmd)?; +fn pmbus(subargs: PmbusArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; if subargs.list { @@ -2242,6 +2240,9 @@ fn pmbus_main( Ok(()) } -pub fn init() -> Command { - Command { app: PmbusArgs::command(), name: "pmbus", run: pmbus } +pub type Args = PmbusArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + pmbus(args, context) + } } diff --git a/cmd/power/Cargo.toml b/cmd/power/Cargo.toml index 612251608..416df1000 100644 --- a/cmd/power/Cargo.toml +++ b/cmd/power/Cargo.toml @@ -14,7 +14,6 @@ idol = { workspace = true } log = { workspace = true } humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true diff --git a/cmd/power/src/lib.rs b/cmd/power/src/lib.rs index 95d34a3cc..c6af33bb0 100644 --- a/cmd/power/src/lib.rs +++ b/cmd/power/src/lib.rs @@ -16,19 +16,18 @@ //! use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use hif::*; use humility::core::Core; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::*; use humility_idol::{self as idol, HubrisIdol}; use std::collections::{BTreeMap, HashSet}; #[derive(Parser, Debug)] #[clap(name = "power", about = env!("CARGO_PKG_DESCRIPTION"))] -struct PowerArgs { +pub struct PowerArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -115,8 +114,7 @@ fn phase_currents( Ok(()) } -fn power(context: &mut ExecutionContext) -> Result<()> { - let subargs = PowerArgs::try_parse_from(&context.cli.cmd)?; +fn power(subargs: PowerArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; @@ -307,6 +305,9 @@ fn power(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: PowerArgs::command(), name: "power", run: power } +pub type Args = PowerArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + power(args, context) + } } diff --git a/cmd/powershelf/Cargo.toml b/cmd/powershelf/Cargo.toml index fe0e998de..1e1daa5e0 100644 --- a/cmd/powershelf/Cargo.toml +++ b/cmd/powershelf/Cargo.toml @@ -6,7 +6,6 @@ description = "inspect powershelf over the management network" [dependencies] humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true diff --git a/cmd/powershelf/src/lib.rs b/cmd/powershelf/src/lib.rs index 821fe05fc..6cc514a46 100644 --- a/cmd/powershelf/src/lib.rs +++ b/cmd/powershelf/src/lib.rs @@ -14,18 +14,17 @@ //! indices 0 through 5). use anyhow::{Context, Result, anyhow}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use hif::*; use humility::hubris::HubrisArchive; use humility::hubris::HubrisEnum; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::*; use humility_idol::{self as idol, HubrisIdol}; #[derive(Parser, Debug)] #[clap(name = "powershelf", about = env!("CARGO_PKG_DESCRIPTION"))] -struct PowershelfArgs { +pub struct PowershelfArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -129,8 +128,10 @@ fn interpret_raw_variant(variant: &str, payload: &[u8]) { } } -fn powershelf_run(context: &mut ExecutionContext) -> Result<()> { - let subargs = PowershelfArgs::try_parse_from(&context.cli.cmd)?; +fn powershelf_run( + subargs: PowershelfArgs, + context: &mut ExecutionContext, +) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; @@ -217,10 +218,9 @@ fn powershelf_run(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { - app: PowershelfArgs::command(), - name: "powershelf", - run: powershelf_run, +pub type Args = PowershelfArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + powershelf_run(args, context) } } diff --git a/cmd/probe/Cargo.toml b/cmd/probe/Cargo.toml index f1ceb92d7..655b960f2 100644 --- a/cmd/probe/Cargo.toml +++ b/cmd/probe/Cargo.toml @@ -12,5 +12,4 @@ num-traits.workspace = true humility.workspace = true humility-arch-arm.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true humility-cortex.workspace = true diff --git a/cmd/probe/src/lib.rs b/cmd/probe/src/lib.rs index 089fdfd6e..415503c9b 100644 --- a/cmd/probe/src/lib.rs +++ b/cmd/probe/src/lib.rs @@ -87,25 +87,23 @@ //! ``` use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::hubris::HubrisValidate; use humility_arch_arm::ARMRegister; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_cortex::debug::*; use humility_cortex::scs::*; #[derive(Parser, Debug)] #[clap(name = "probe", about = env!("CARGO_PKG_DESCRIPTION"))] -struct ProbeArgs { +pub struct ProbeArgs { /// display environment variable for this probe #[clap(long, short)] environment: bool, } #[rustfmt::skip::macros(format)] -fn probecmd(context: &mut ExecutionContext) -> Result<()> { - let subargs = ProbeArgs::try_parse_from(&context.cli.cmd)?; +fn probecmd(subargs: ProbeArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = context.cli.try_archive()?; let core = &mut *context.cli.attach_probe(hubris.as_ref())?; @@ -411,6 +409,9 @@ fn probecmd(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: ProbeArgs::command(), name: "probe", run: probecmd } +pub type Args = ProbeArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + probecmd(args, context) + } } diff --git a/cmd/qspi/src/lib.rs b/cmd/qspi/src/lib.rs index c1dceace1..ec5cb3dd1 100644 --- a/cmd/qspi/src/lib.rs +++ b/cmd/qspi/src/lib.rs @@ -83,8 +83,8 @@ //! as well as bulk erase. use humility::core::Core; -use humility_cli::ExecutionContext; -use humility_cmd::{Command, Dumper}; +use humility_cli::{ExecutionContext, HumilitySubcommand}; +use humility_cmd::Dumper; use humility_hiffy::*; use humility_idol::{HubrisIdol, IdolArgument}; use sha2::{Digest, Sha256}; @@ -96,7 +96,7 @@ use std::mem; use std::time::Instant; use anyhow::{Result, anyhow, bail}; -use clap::{ArgGroup, CommandFactory, Parser}; +use clap::{ArgGroup, Parser}; use hif::*; use indicatif::{HumanBytes, HumanDuration}; @@ -107,7 +107,7 @@ use indicatif::{ProgressBar, ProgressStyle}; name = "qspi", about = env!("CARGO_PKG_DESCRIPTION"), group = ArgGroup::new("command").multiple(false) )] -struct QspiArgs { +pub struct QspiArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 30000, value_name = "timeout_ms", @@ -481,8 +481,7 @@ fn write( } } -fn qspi(context: &mut ExecutionContext) -> Result<()> { - let subargs = QspiArgs::try_parse_from(&context.cli.cmd)?; +fn qspi(subargs: QspiArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; @@ -1182,6 +1181,9 @@ impl fmt::Display for DeviceIdData { } } -pub fn init() -> Command { - Command { app: QspiArgs::command(), name: "qspi", run: qspi } +pub type Args = QspiArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + qspi(args, context) + } } diff --git a/cmd/readmem/src/lib.rs b/cmd/readmem/src/lib.rs index 0de3e903c..948b5d462 100644 --- a/cmd/readmem/src/lib.rs +++ b/cmd/readmem/src/lib.rs @@ -116,10 +116,10 @@ //! use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::{Command, Dumper}; +use humility_cli::{ExecutionContext, HumilitySubcommand}; +use humility_cmd::Dumper; use std::convert::TryInto; use std::io::Write; use std::path::PathBuf; @@ -141,7 +141,7 @@ fn parse_size(src: &str) -> Result { #[derive(Parser, Debug)] #[clap(name = "readmem", about = env!("CARGO_PKG_DESCRIPTION"))] -struct ReadmemArgs { +pub struct ReadmemArgs { /// print out as halfwords instead of as bytes #[clap(long, short = 'H', conflicts_with_all = &["word", "symbol", "file"])] halfword: bool, @@ -166,8 +166,7 @@ struct ReadmemArgs { length: Option, } -fn readmem(context: &mut ExecutionContext) -> Result<()> { - let subargs = ReadmemArgs::try_parse_from(&context.cli.cmd)?; +fn readmem(subargs: ReadmemArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = context.cli.try_archive()?; let core = &mut *context.cli.attach_live_or_dump(hubris.as_ref(), None)?; @@ -268,6 +267,9 @@ fn readmem(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: ReadmemArgs::command(), name: "readmem", run: readmem } +pub type Args = ReadmemArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + readmem(args, context) + } } diff --git a/cmd/readvar/Cargo.toml b/cmd/readvar/Cargo.toml index 328c26433..3a51dc3d3 100644 --- a/cmd/readvar/Cargo.toml +++ b/cmd/readvar/Cargo.toml @@ -9,5 +9,4 @@ clap.workspace = true anyhow.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true diff --git a/cmd/readvar/src/lib.rs b/cmd/readvar/src/lib.rs index ec8050f09..5fdfe3892 100644 --- a/cmd/readvar/src/lib.rs +++ b/cmd/readvar/src/lib.rs @@ -37,15 +37,14 @@ //! use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::core::{Core, ProbeError}; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; #[derive(Parser, Debug)] #[clap(name = "readvar", about = env!("CARGO_PKG_DESCRIPTION"))] -struct ReadvarArgs { +pub struct ReadvarArgs { /// values in decimal instead of hex #[clap(long, short)] decimal: bool, @@ -99,8 +98,7 @@ fn readvar_dump( Ok(()) } -fn readvar(context: &mut ExecutionContext) -> Result<()> { - let subargs = ReadvarArgs::try_parse_from(&context.cli.cmd)?; +fn readvar(subargs: ReadvarArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; if subargs.list { @@ -179,6 +177,9 @@ fn readvar(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: ReadvarArgs::command(), name: "readvar", run: readvar } +pub type Args = ReadvarArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + readvar(args, context) + } } diff --git a/cmd/rebootleby/Cargo.toml b/cmd/rebootleby/Cargo.toml index d36c0452f..5fe3c670d 100644 --- a/cmd/rebootleby/Cargo.toml +++ b/cmd/rebootleby/Cargo.toml @@ -8,7 +8,6 @@ description = "Do something kind of like embootleby to recover a device with bad humility = { workspace = true } humility-arch-arm = { workspace = true } humility-cortex = { workspace = true } -humility-cmd = { workspace = true } humility-cli = { workspace = true } clap = { workspace = true } anyhow = { workspace = true } diff --git a/cmd/rebootleby/src/lib.rs b/cmd/rebootleby/src/lib.rs index b1b252213..08831123c 100644 --- a/cmd/rebootleby/src/lib.rs +++ b/cmd/rebootleby/src/lib.rs @@ -11,11 +11,10 @@ //! !!! Using this can be dangerous and should be undertaken with caution use anyhow::{Context, Result, anyhow, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::core::Core; use humility_arch_arm::ARMRegister; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use std::io::Read; use std::ops::RangeInclusive; use std::path::PathBuf; @@ -24,7 +23,7 @@ use zip::ZipArchive; #[derive(Parser, Debug)] #[clap(about = env!("CARGO_PKG_DESCRIPTION"))] -struct Rebootleby { +pub struct Rebootleby { /// Path to a Bootleby Bundle file. path: PathBuf, /// Flag to ensure you _really_ mean to run this command @@ -32,9 +31,10 @@ struct Rebootleby { yes_really: bool, } -fn rebootleby(context: &mut ExecutionContext) -> Result<()> { - let subargs = Rebootleby::try_parse_from(&context.cli.cmd)?; - +fn rebootleby( + subargs: Rebootleby, + context: &mut ExecutionContext, +) -> Result<()> { // Load bundle let bundle_reader = std::fs::File::open(&subargs.path) .with_context(|| format!("loading {}", subargs.path.display()))?; @@ -138,8 +138,11 @@ fn rebootleby(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: Rebootleby::command(), name: "rebootleby", run: rebootleby } +pub type Args = Rebootleby; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + rebootleby(args, context) + } } // The undocumented registers. These look remarkably similar to the diff --git a/cmd/registers/Cargo.toml b/cmd/registers/Cargo.toml index addc7953c..ef20ec58e 100644 --- a/cmd/registers/Cargo.toml +++ b/cmd/registers/Cargo.toml @@ -12,6 +12,5 @@ num-traits.workspace = true humility.workspace = true humility-arch-arm.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true humility-cortex.workspace = true humility-stack.workspace = true diff --git a/cmd/registers/src/lib.rs b/cmd/registers/src/lib.rs index 7136086e4..d02fb74f0 100644 --- a/cmd/registers/src/lib.rs +++ b/cmd/registers/src/lib.rs @@ -130,18 +130,17 @@ //! use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::hubris::*; use humility_arch_arm::{ARMRegister, ARMRegisterField}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_cortex::debug::*; use num_traits::FromPrimitive; use std::collections::BTreeMap; #[derive(Parser, Debug)] #[clap(name = "registers", about = env!("CARGO_PKG_DESCRIPTION"))] -struct RegistersArgs { +pub struct RegistersArgs { /// show stack backtrace #[clap(long, short)] stack: bool, @@ -232,8 +231,10 @@ fn print_reg(reg: ARMRegister, val: u32, fields: &[ARMRegisterField]) { println!(); } -fn registers(context: &mut ExecutionContext) -> Result<()> { - let subargs = RegistersArgs::try_parse_from(&context.cli.cmd)?; +fn registers( + subargs: RegistersArgs, + context: &mut ExecutionContext, +) -> Result<()> { let hubris = &context.cli.try_archive()?; let core = &mut *context.cli.attach_live_or_dump(hubris.as_ref(), None)?; let mut regs = BTreeMap::new(); @@ -362,6 +363,9 @@ fn registers(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: RegistersArgs::command(), name: "registers", run: registers } +pub type Args = RegistersArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + registers(args, context) + } } diff --git a/cmd/rencm/src/lib.rs b/cmd/rencm/src/lib.rs index c824ef747..de05637d5 100644 --- a/cmd/rencm/src/lib.rs +++ b/cmd/rencm/src/lib.rs @@ -10,15 +10,15 @@ use humility::core::Core; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::{Command, Dumper}; +use humility_cli::{ExecutionContext, HumilitySubcommand}; +use humility_cmd::Dumper; use humility_hiffy::*; use humility_i2c::I2cArgs; use itertools::Itertools; use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use hif::*; use idt8a3xxxx::*; use std::collections::BTreeMap; @@ -30,7 +30,7 @@ use serde_xml_rs::from_str; #[derive(Parser, Debug)] #[clap(name = "rencm", about = env!("CARGO_PKG_DESCRIPTION"))] -struct RencmArgs { +pub struct RencmArgs { /// sets timeout #[clap( long, short, default_value_t = 5000, value_name = "timeout_ms", @@ -791,8 +791,7 @@ fn rencm_ingest(subargs: &RencmArgs, modules: &[Module]) -> Result<()> { Ok(()) } -fn rencm(context: &mut ExecutionContext) -> Result<()> { - let subargs = RencmArgs::try_parse_from(&context.cli.cmd)?; +fn rencm(subargs: RencmArgs, context: &mut ExecutionContext) -> Result<()> { let modules = modules(); if subargs.ingest.is_some() { @@ -804,6 +803,9 @@ fn rencm(context: &mut ExecutionContext) -> Result<()> { rencm_attached(hubris, core, &subargs, modules) } -pub fn init() -> Command { - Command { app: RencmArgs::command(), name: "rencm", run: rencm } +pub type Args = RencmArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + rencm(args, context) + } } diff --git a/cmd/rendmp/Cargo.toml b/cmd/rendmp/Cargo.toml index 81dbda71e..d795b6760 100644 --- a/cmd/rendmp/Cargo.toml +++ b/cmd/rendmp/Cargo.toml @@ -19,7 +19,6 @@ strum_macros.workspace = true zerocopy.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true humility-hiffy.workspace = true humility-i2c.workspace = true humility-idol.workspace = true diff --git a/cmd/rendmp/src/lib.rs b/cmd/rendmp/src/lib.rs index 16b4b2d31..ece199965 100644 --- a/cmd/rendmp/src/lib.rs +++ b/cmd/rendmp/src/lib.rs @@ -145,14 +145,13 @@ use humility::hubris::*; use humility::reflect::{Base, Value}; use humility::warn; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::*; use humility_i2c::I2cArgs; use humility_idol::{HubrisIdol, IdolOperation}; use anyhow::{Context, Result, anyhow, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use colored::Colorize; use hif::*; use indicatif::{HumanBytes, HumanDuration}; @@ -176,7 +175,7 @@ mod blackbox; #[clap(name = "rendmp", about = env!("CARGO_PKG_DESCRIPTION"), group = clap::ArgGroup::new("subcommand").multiple(false) )] -struct RendmpArgs { +pub struct RendmpArgs { /// sets timeout #[clap( long, short, default_value_t = 5000, value_name = "timeout_ms", @@ -2294,8 +2293,7 @@ fn restore_default_config<'a>( Ok(()) } -fn rendmp(context: &mut ExecutionContext) -> Result<()> { - let subargs = RendmpArgs::try_parse_from(&context.cli.cmd)?; +fn rendmp(subargs: RendmpArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; @@ -2883,6 +2881,9 @@ fn rendmp(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: RendmpArgs::command(), name: "rendmp", run: rendmp } +pub type Args = RendmpArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + rendmp(args, context) + } } diff --git a/cmd/reset/Cargo.toml b/cmd/reset/Cargo.toml index 19f3ea096..be4f678fb 100644 --- a/cmd/reset/Cargo.toml +++ b/cmd/reset/Cargo.toml @@ -6,7 +6,6 @@ description = "Reset the chip using external pins" [dependencies] humility = { workspace = true } -humility-cmd = { workspace = true } humility-cli = { workspace = true } humility-probes-core = { workspace = true } clap = { workspace = true } diff --git a/cmd/reset/src/lib.rs b/cmd/reset/src/lib.rs index 6484b59c4..a80c12234 100644 --- a/cmd/reset/src/lib.rs +++ b/cmd/reset/src/lib.rs @@ -8,13 +8,12 @@ //! or using software reset with the appropriate flag use anyhow::Result; -use clap::{CommandFactory, Parser}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use clap::Parser; +use humility_cli::{ExecutionContext, HumilitySubcommand}; #[derive(Parser, Debug)] #[clap(name = "reset", about = env!("CARGO_PKG_DESCRIPTION"))] -struct ResetArgs { +pub struct ResetArgs { /// Use a software reset instead of pin reset #[clap(long, conflicts_with_all = &["halt"])] soft_reset: bool, @@ -26,8 +25,7 @@ struct ResetArgs { use_token: Option, } -fn reset(context: &mut ExecutionContext) -> Result<()> { - let subargs = ResetArgs::try_parse_from(&context.cli.cmd)?; +fn reset(subargs: ResetArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = context.cli.try_archive()?; let probe = match &context.cli.probe { @@ -111,6 +109,9 @@ fn reset(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: ResetArgs::command(), name: "reset", run: reset } +pub type Args = ResetArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + reset(args, context) + } } diff --git a/cmd/ringbuf/Cargo.toml b/cmd/ringbuf/Cargo.toml index 435b48608..2934d67d0 100644 --- a/cmd/ringbuf/Cargo.toml +++ b/cmd/ringbuf/Cargo.toml @@ -9,6 +9,5 @@ clap.workspace = true anyhow.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-doppel.workspace = true diff --git a/cmd/ringbuf/src/lib.rs b/cmd/ringbuf/src/lib.rs index 212056762..f18a025f7 100644 --- a/cmd/ringbuf/src/lib.rs +++ b/cmd/ringbuf/src/lib.rs @@ -63,17 +63,16 @@ //! documentation](https://github.com/oxidecomputer/hubris/blob/master/lib/ringbuf/src/lib.rs) for more details. use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::core::Core; use humility::hubris::*; use humility::reflect::{self, Format, Load, Value}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_doppel::{CountedRingbuf, CounterVariant, Ringbuf, StaticCell}; #[derive(Parser, Debug)] #[clap(name = "ringbuf", about = env!("CARGO_PKG_DESCRIPTION"))] -struct RingbufArgs { +pub struct RingbufArgs { /// list variables #[clap(long, short)] list: bool, @@ -232,8 +231,7 @@ fn taskname<'a>( // this allow is meant for the header println! in the body but you cannot apply // an attribute to a macro invoction, so we have to put it here instead. #[allow(clippy::print_literal)] -fn ringbuf(context: &mut ExecutionContext) -> Result<()> { - let subargs = RingbufArgs::try_parse_from(&context.cli.cmd)?; +fn ringbuf(subargs: RingbufArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let mut ringbufs = vec![]; @@ -315,6 +313,9 @@ fn ringbuf(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: RingbufArgs::command(), name: "ringbuf", run: ringbuf } +pub type Args = RingbufArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + ringbuf(args, context) + } } diff --git a/cmd/sbrmi/Cargo.toml b/cmd/sbrmi/Cargo.toml index 6747bc4c1..6d37b525e 100644 --- a/cmd/sbrmi/Cargo.toml +++ b/cmd/sbrmi/Cargo.toml @@ -15,7 +15,6 @@ termimad.workspace = true zerocopy.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true diff --git a/cmd/sbrmi/src/lib.rs b/cmd/sbrmi/src/lib.rs index 7f4669653..b9e44945a 100644 --- a/cmd/sbrmi/src/lib.rs +++ b/cmd/sbrmi/src/lib.rs @@ -90,13 +90,12 @@ //! using the `--mca` option and specifyin a desired thread. use anyhow::Result; -use clap::{ArgGroup, CommandFactory, Parser}; +use clap::{ArgGroup, Parser}; use colored::Colorize; use hif::*; use humility::core::Core; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::*; use humility_idol::{self as idol, HubrisIdol}; use raw_cpuid::{CpuId, CpuIdResult}; @@ -109,7 +108,7 @@ use std::rc::Rc; name = "sbrmi", about = env!("CARGO_PKG_DESCRIPTION"), group = ArgGroup::new("command").multiple(false).required(false) )] -struct SbrmiArgs { +pub struct SbrmiArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -502,8 +501,7 @@ fn mca( Ok(()) } -fn sbrmi(context: &mut ExecutionContext) -> Result<()> { - let subargs = SbrmiArgs::try_parse_from(&context.cli.cmd)?; +fn sbrmi(subargs: SbrmiArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; let mut context = HiffyContext::new(hubris, core, subargs.timeout)?; @@ -588,6 +586,9 @@ fn sbrmi(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: SbrmiArgs::command(), name: "sbrmi", run: sbrmi } +pub type Args = SbrmiArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + sbrmi(args, context) + } } diff --git a/cmd/sensors/Cargo.toml b/cmd/sensors/Cargo.toml index 9c7e5b4e9..1bc568096 100644 --- a/cmd/sensors/Cargo.toml +++ b/cmd/sensors/Cargo.toml @@ -13,7 +13,6 @@ indexmap.workspace = true itertools.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-doppel.workspace = true humility-hiffy.workspace = true diff --git a/cmd/sensors/src/lib.rs b/cmd/sensors/src/lib.rs index 8438ece37..17f8b809f 100644 --- a/cmd/sensors/src/lib.rs +++ b/cmd/sensors/src/lib.rs @@ -25,13 +25,12 @@ //! counts are also displayed. use anyhow::{Result, anyhow, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use hif::*; use humility::core::Core; use humility::hubris::*; use humility::reflect::{self, Load}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_doppel as doppel; use humility_hiffy::*; use humility_idol::{self as idol, HubrisIdol}; @@ -42,7 +41,7 @@ use std::time::{Duration, Instant}; #[derive(Parser, Debug)] #[clap(name = "sensors", about = env!("CARGO_PKG_DESCRIPTION"))] -struct SensorsArgs { +pub struct SensorsArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -531,8 +530,7 @@ fn print( Ok(()) } -fn sensors(context: &mut ExecutionContext) -> Result<()> { - let subargs = SensorsArgs::try_parse_from(&context.cli.cmd)?; +fn sensors(subargs: SensorsArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let types = if let Some(ref types) = subargs.types { @@ -647,6 +645,9 @@ fn sensors(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: SensorsArgs::command(), name: "sensors", run: sensors } +pub type Args = SensorsArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + sensors(args, context) + } } diff --git a/cmd/spctrl/src/lib.rs b/cmd/spctrl/src/lib.rs index 3525410b2..4c9221a93 100644 --- a/cmd/spctrl/src/lib.rs +++ b/cmd/spctrl/src/lib.rs @@ -44,14 +44,14 @@ //! 0x00000030 | f739ba6f 20067a60 310c4e08 e42eca28 | o.9.`z. .N.1(... //! ``` -use humility_cli::ExecutionContext; -use humility_cmd::{Command, Dumper}; +use humility_cli::{ExecutionContext, HumilitySubcommand}; +use humility_cmd::Dumper; use humility_hiffy::*; use std::str; use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use hif::*; #[derive(Parser, Debug)] @@ -72,7 +72,7 @@ enum SpCtrlCmd { #[derive(Parser, Debug)] #[clap(name = "spctrl", about = env!("CARGO_PKG_DESCRIPTION"))] -struct SpCtrlArgs { +pub struct SpCtrlArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -88,8 +88,7 @@ struct SpCtrlArgs { word: bool, } -fn spctrl(context: &mut ExecutionContext) -> Result<()> { - let subargs = SpCtrlArgs::try_parse_from(&context.cli.cmd)?; +fn spctrl(subargs: SpCtrlArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; let mut context = HiffyContext::new(hubris, core, subargs.timeout)?; @@ -150,6 +149,9 @@ fn spctrl(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: SpCtrlArgs::command(), name: "spctrl", run: spctrl } +pub type Args = SpCtrlArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + spctrl(args, context) + } } diff --git a/cmd/spd/Cargo.toml b/cmd/spd/Cargo.toml index 6bcb4bc0d..023d30b99 100644 --- a/cmd/spd/Cargo.toml +++ b/cmd/spd/Cargo.toml @@ -13,7 +13,6 @@ jep106.workspace = true parse_int.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true humility-hiffy.workspace = true humility-i2c.workspace = true humility-log.workspace = true diff --git a/cmd/spd/src/lib.rs b/cmd/spd/src/lib.rs index 707fac517..a79cdf5fd 100644 --- a/cmd/spd/src/lib.rs +++ b/cmd/spd/src/lib.rs @@ -107,8 +107,7 @@ //! use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::*; use humility_i2c::I2cArgs; use humility_log::msg; @@ -118,12 +117,12 @@ use std::io::Write; use std::str; use anyhow::{Result, anyhow, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use hif::*; #[derive(Parser, Debug)] #[clap(name = "spd", about = env!("CARGO_PKG_DESCRIPTION"))] -struct SpdArgs { +pub struct SpdArgs { /// sets timeout #[clap( long, short, default_value_t = 5000, value_name = "timeout_ms", @@ -330,8 +329,7 @@ fn set_page( ops.push(Op::DropN(4)); } -fn spd(context: &mut ExecutionContext) -> Result<()> { - let subargs = SpdArgs::try_parse_from(&context.cli.cmd)?; +fn spd(subargs: SpdArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_or_dump_booted(hubris)?; @@ -518,6 +516,9 @@ fn dump_ddr4_over_i2c( Ok(()) } -pub fn init() -> Command { - Command { app: SpdArgs::command(), name: "spd", run: spd } +pub type Args = SpdArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + spd(args, context) + } } diff --git a/cmd/spi/src/lib.rs b/cmd/spi/src/lib.rs index 34ee8afe9..51dd28918 100644 --- a/cmd/spi/src/lib.rs +++ b/cmd/spi/src/lib.rs @@ -33,20 +33,20 @@ //! use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::{Command, Dumper}; +use humility_cli::{ExecutionContext, HumilitySubcommand}; +use humility_cmd::Dumper; use humility_hiffy::*; use std::convert::TryInto; use std::str; use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use hif::*; #[derive(Parser, Debug)] #[clap(name = "spi", about = env!("CARGO_PKG_DESCRIPTION"))] -struct SpiArgs { +pub struct SpiArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -170,8 +170,7 @@ pub fn spi_task( Ok(task) } -fn spi(context: &mut ExecutionContext) -> Result<()> { - let subargs = SpiArgs::try_parse_from(&context.cli.cmd)?; +fn spi(subargs: SpiArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; @@ -311,6 +310,9 @@ fn spi(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: SpiArgs::command(), name: "spi", run: spi } +pub type Args = SpiArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + spi(args, context) + } } diff --git a/cmd/stackmargin/src/lib.rs b/cmd/stackmargin/src/lib.rs index e4a346a1c..26a9a3174 100644 --- a/cmd/stackmargin/src/lib.rs +++ b/cmd/stackmargin/src/lib.rs @@ -28,22 +28,23 @@ //! use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use std::{collections::HashSet, convert::TryInto}; #[derive(Parser, Debug)] #[clap(name = "stackmargin", about = env!("CARGO_PKG_DESCRIPTION"))] -struct StackmarginArgs { +pub struct StackmarginArgs { /// Tasks to check (leave empty to check all tasks) tasks: Vec, } #[rustfmt::skip::macros(println, bail)] -fn stackmargin(context: &mut ExecutionContext) -> Result<()> { - let subargs = StackmarginArgs::try_parse_from(&context.cli.cmd)?; +fn stackmargin( + subargs: StackmarginArgs, + context: &mut ExecutionContext, +) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_or_dump_booted(hubris)?; @@ -161,10 +162,9 @@ fn stackmargin(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { - app: StackmarginArgs::command(), - name: "stackmargin", - run: stackmargin, +pub type Args = StackmarginArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + stackmargin(args, context) } } diff --git a/cmd/stmsecure/Cargo.toml b/cmd/stmsecure/Cargo.toml index 14a11d9a0..d553537ad 100644 --- a/cmd/stmsecure/Cargo.toml +++ b/cmd/stmsecure/Cargo.toml @@ -12,4 +12,3 @@ parse_int.workspace = true humility.workspace = true humility-arch-arm.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true diff --git a/cmd/stmsecure/src/lib.rs b/cmd/stmsecure/src/lib.rs index d09cd072f..6560e09af 100644 --- a/cmd/stmsecure/src/lib.rs +++ b/cmd/stmsecure/src/lib.rs @@ -28,11 +28,10 @@ //! ``` use anyhow::{Result, anyhow}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::core::Core; use humility_arch_arm::ARMRegister; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; const FLASH_OPT_KEY1: u32 = 0x0819_2A3B; const FLASH_OPT_KEY2: u32 = 0x4C5D_6E7F; @@ -52,7 +51,13 @@ const FLASH_SCAR_PRG1: u32 = 0x5200_2034; #[derive(Parser, Debug)] #[clap(name = "stmsecure", about = env!("CARGO_PKG_DESCRIPTION"))] -enum StmSecureArgs { +pub struct StmSecureArgs { + #[clap(subcommand)] + cmd: StmSecureCmd, +} + +#[derive(clap::Subcommand, Debug)] +pub enum StmSecureCmd { /// Show status about secure region settings Status, /// Enable Read Out Protection (RDP) i.e. can't read flash from debugger @@ -221,7 +226,7 @@ fn stmsecure_setsecureregion( // We have to use the delightful ROM API in order to write this register core.halt()?; - // Set up the structure at 0x2000_0000 + // Set up the pub structure at 0x2000_0000 // typedef struct // { // uint32_t sizeInBytes; /**< pass 0 for an empty secure area */ @@ -294,24 +299,29 @@ fn stmsecure_swapbanks(core: &mut dyn Core) -> Result<()> { } #[rustfmt::skip::macros(format)] -fn stmsecure(context: &mut ExecutionContext) -> Result<()> { - let subargs = StmSecureArgs::try_parse_from(&context.cli.cmd)?; +fn stmsecure( + subargs: StmSecureArgs, + context: &mut ExecutionContext, +) -> Result<()> { let core = &mut *context.cli.attach_probe(None)?; - match subargs { - StmSecureArgs::Status => stmsecure_status(core), - StmSecureArgs::SetSecureBit => stmsecure_lockbit_set(core), - StmSecureArgs::UnsetSecureBit => stmsecure_lockbit_unset(core), - StmSecureArgs::SetSecureRegion { address, size, doit } => { + match subargs.cmd { + StmSecureCmd::Status => stmsecure_status(core), + StmSecureCmd::SetSecureBit => stmsecure_lockbit_set(core), + StmSecureCmd::UnsetSecureBit => stmsecure_lockbit_unset(core), + StmSecureCmd::SetSecureRegion { address, size, doit } => { stmsecure_setsecureregion(core, address, size, doit) } - StmSecureArgs::UnsetSecureRegion => stmsecure_unsetsecureregion(core), - StmSecureArgs::SetRDP => stmsecure_rdpset(core), - StmSecureArgs::UnsetRDP => stmsecure_rdpunset(core), - StmSecureArgs::SwapBanks => stmsecure_swapbanks(core), + StmSecureCmd::UnsetSecureRegion => stmsecure_unsetsecureregion(core), + StmSecureCmd::SetRDP => stmsecure_rdpset(core), + StmSecureCmd::UnsetRDP => stmsecure_rdpunset(core), + StmSecureCmd::SwapBanks => stmsecure_swapbanks(core), } } -pub fn init() -> Command { - Command { app: StmSecureArgs::command(), name: "stmsecure", run: stmsecure } +pub type Args = StmSecureArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + stmsecure(args, context) + } } diff --git a/cmd/tasks/Cargo.toml b/cmd/tasks/Cargo.toml index a23ca5096..864e0784e 100644 --- a/cmd/tasks/Cargo.toml +++ b/cmd/tasks/Cargo.toml @@ -13,7 +13,6 @@ parse_int.workspace = true humility.workspace = true humility-arch-arm.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-doppel.workspace = true humility-stack.workspace = true diff --git a/cmd/tasks/src/lib.rs b/cmd/tasks/src/lib.rs index fc9db75d0..93ab4b586 100644 --- a/cmd/tasks/src/lib.rs +++ b/cmd/tasks/src/lib.rs @@ -112,13 +112,12 @@ //! use anyhow::{Context, Result, anyhow, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use humility::core::Core; use humility::hubris::*; use humility::reflect::{self, Format, Load}; use humility_arch_arm::ARMRegister; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_doppel::{self as doppel, Task, TaskDesc, TaskId, TaskState}; use num_traits::FromPrimitive; use std::collections::{BTreeMap, HashMap}; @@ -126,7 +125,7 @@ use std::io::Write; #[derive(Parser, Debug)] #[clap(name = "tasks", about = env!("CARGO_PKG_DESCRIPTION"))] -struct TasksArgs { +pub struct TasksArgs { /// show registers #[clap(long, short)] registers: bool, @@ -183,8 +182,7 @@ fn print_regs( Ok(()) } -fn tasks(context: &mut ExecutionContext) -> Result<()> { - let subargs = TasksArgs::try_parse_from(&context.cli.cmd)?; +fn tasks(subargs: TasksArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_or_dump_booted(hubris)?; @@ -928,6 +926,9 @@ fn explain_recv( Ok(()) } -pub fn init() -> Command { - Command { app: TasksArgs::command(), name: "tasks", run: tasks } +pub type Args = TasksArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + tasks(args, context) + } } diff --git a/cmd/test/Cargo.toml b/cmd/test/Cargo.toml index 77149dda9..ca977a3ab 100644 --- a/cmd/test/Cargo.toml +++ b/cmd/test/Cargo.toml @@ -14,6 +14,5 @@ hif.workspace = true humility-hiffy.workspace = true humility.workspace = true humility-cortex.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true cmd-tasks.workspace = true diff --git a/cmd/test/src/lib.rs b/cmd/test/src/lib.rs index bf461d6f4..bcf798cab 100644 --- a/cmd/test/src/lib.rs +++ b/cmd/test/src/lib.rs @@ -91,12 +91,11 @@ //! use anyhow::{Context, Result, bail}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use colored::Colorize; use hif::*; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::*; use std::fmt; use std::fs::OpenOptions; @@ -104,7 +103,7 @@ use std::io::{BufWriter, Write}; #[derive(Parser, Debug)] #[clap(name = "test", about = env!("CARGO_PKG_DESCRIPTION"))] -struct TestArgs { +pub struct TestArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 3000, value_name = "timeout_ms", @@ -161,8 +160,7 @@ impl fmt::Display for TestResult { } } -fn test(context: &mut ExecutionContext) -> Result<()> { - let subargs = TestArgs::try_parse_from(&context.cli.cmd)?; +fn test(subargs: TestArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; @@ -285,6 +283,9 @@ fn test(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: TestArgs::command(), name: "test", run: test } +pub type Args = TestArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + test(args, context) + } } diff --git a/cmd/tofino-eeprom/Cargo.toml b/cmd/tofino-eeprom/Cargo.toml index 147e56162..c71d91d0d 100644 --- a/cmd/tofino-eeprom/Cargo.toml +++ b/cmd/tofino-eeprom/Cargo.toml @@ -11,7 +11,6 @@ indicatif.workspace = true parse_int.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true diff --git a/cmd/tofino-eeprom/src/lib.rs b/cmd/tofino-eeprom/src/lib.rs index 45ca55856..4f14d040b 100644 --- a/cmd/tofino-eeprom/src/lib.rs +++ b/cmd/tofino-eeprom/src/lib.rs @@ -7,13 +7,12 @@ //! Tools to interact with the Tofino EEPROM use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; -use humility_cli::ExecutionContext; +use clap::Parser; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use indicatif::{ProgressBar, ProgressStyle}; use humility::core::Core; use humility::hubris::*; -use humility_cmd::Command; use humility_hiffy::HiffyContext; use humility_idol::{HubrisIdol, IdolArgument}; @@ -25,7 +24,7 @@ const EEPROM_SIZE_BYTES: usize = 65536; #[derive(Parser, Debug)] #[clap(name = "tofino-eeprom", about = env!("CARGO_PKG_DESCRIPTION"))] -struct EepromArgs { +pub struct EepromArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 15000, value_name = "timeout_ms", @@ -139,8 +138,7 @@ impl<'a> EepromHandler<'a> { //////////////////////////////////////////////////////////////////////////////// -fn eeprom(context: &mut ExecutionContext) -> Result<()> { - let subargs = EepromArgs::try_parse_from(&context.cli.cmd)?; +fn eeprom(subargs: EepromArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; let mut worker = EepromHandler::new(hubris, core, subargs.timeout)?; @@ -158,6 +156,9 @@ fn eeprom(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: EepromArgs::command(), name: "tofino-eeprom", run: eeprom } +pub type Args = EepromArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + eeprom(args, context) + } } diff --git a/cmd/validate/Cargo.toml b/cmd/validate/Cargo.toml index 1893fe535..4daaef862 100644 --- a/cmd/validate/Cargo.toml +++ b/cmd/validate/Cargo.toml @@ -13,7 +13,6 @@ parse_int.workspace = true idol.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true diff --git a/cmd/validate/src/lib.rs b/cmd/validate/src/lib.rs index 5aeefc3df..b30c451ec 100644 --- a/cmd/validate/src/lib.rs +++ b/cmd/validate/src/lib.rs @@ -43,19 +43,18 @@ //! use anyhow::{Result, anyhow}; -use clap::{CommandFactory, Parser}; +use clap::Parser; use colored::Colorize; use hif::*; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use humility_cli::{ExecutionContext, HumilitySubcommand}; use humility_hiffy::{HiffyContext, IpcError}; use humility_i2c::I2cArgs; use humility_idol::{self as idol, HubrisIdol}; #[derive(Parser, Debug)] #[clap(name = "validate", about = env!("CARGO_PKG_DESCRIPTION"))] -struct ValidateArgs { +pub struct ValidateArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -131,8 +130,10 @@ fn list(hubris: &HubrisArchive, hargs: &Option) -> Result<()> { Ok(()) } -fn validate(context: &mut ExecutionContext) -> Result<()> { - let subargs = ValidateArgs::try_parse_from(&context.cli.cmd)?; +fn validate( + subargs: ValidateArgs, + context: &mut ExecutionContext, +) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; @@ -272,6 +273,9 @@ fn validate(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: ValidateArgs::command(), name: "validate", run: validate } +pub type Args = ValidateArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + validate(args, context) + } } diff --git a/cmd/vpd/src/lib.rs b/cmd/vpd/src/lib.rs index e61572141..7e1ed424e 100644 --- a/cmd/vpd/src/lib.rs +++ b/cmd/vpd/src/lib.rs @@ -103,12 +103,12 @@ //! will be locked and the command will return with a *non-zero* exit status. use anyhow::{Context, Result, bail}; -use clap::{ArgGroup, CommandFactory, Parser}; +use clap::{ArgGroup, Parser}; use hif::*; use humility::core::Core; use humility::hubris::*; -use humility_cli::ExecutionContext; -use humility_cmd::{Command, Dumper}; +use humility_cli::{ExecutionContext, HumilitySubcommand}; +use humility_cmd::Dumper; use humility_hiffy::*; use humility_idol::{self as idol, HubrisIdol}; use indicatif::{ProgressBar, ProgressStyle}; @@ -120,7 +120,7 @@ use std::io::{Read, Seek, SeekFrom, Write}; name = "vpd", about = env!("CARGO_PKG_DESCRIPTION"), group = ArgGroup::new("command").multiple(false), )] -struct VpdArgs { +pub struct VpdArgs { /// sets timeout #[clap( long, short = 'T', default_value_t = 5000, value_name = "timeout_ms", @@ -706,8 +706,7 @@ fn vpd_lock_all( Ok(()) } -fn vpd(context: &mut ExecutionContext) -> Result<()> { - let subargs = VpdArgs::try_parse_from(&context.cli.cmd)?; +fn vpd(subargs: VpdArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; let core = &mut *context.cli.attach_live_booted(hubris)?; @@ -728,6 +727,9 @@ fn vpd(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: VpdArgs::command(), name: "vpd", run: vpd } +pub type Args = VpdArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + vpd(args, context) + } } diff --git a/cmd/writeword/Cargo.toml b/cmd/writeword/Cargo.toml index e89f7f569..59ebbf44e 100644 --- a/cmd/writeword/Cargo.toml +++ b/cmd/writeword/Cargo.toml @@ -7,7 +7,6 @@ description = "writes one or more memory words" [dependencies] humility = { workspace = true } humility-cli = { workspace = true } -humility-cmd = { workspace = true } clap = { workspace = true } anyhow = { workspace = true } parse_int = { workspace = true } diff --git a/cmd/writeword/src/lib.rs b/cmd/writeword/src/lib.rs index a031fe945..db8dc4ffa 100644 --- a/cmd/writeword/src/lib.rs +++ b/cmd/writeword/src/lib.rs @@ -48,13 +48,12 @@ //! use anyhow::{Result, bail}; -use clap::{CommandFactory, Parser}; -use humility_cli::ExecutionContext; -use humility_cmd::Command; +use clap::Parser; +use humility_cli::{ExecutionContext, HumilitySubcommand}; #[derive(Parser, Debug)] #[clap(name = "writeword", about = env!("CARGO_PKG_DESCRIPTION"))] -struct WritewordArgs { +pub struct WritewordArgs { /// address to write to #[clap(value_parser = parse_int::parse::,)] address: u32, @@ -64,8 +63,10 @@ struct WritewordArgs { value: Vec, } -fn writeword(context: &mut ExecutionContext) -> Result<()> { - let subargs = WritewordArgs::try_parse_from(&context.cli.cmd)?; +fn writeword( + subargs: WritewordArgs, + context: &mut ExecutionContext, +) -> Result<()> { let hubris = context.cli.try_archive()?; let core = &mut *context.cli.attach_probe(hubris.as_ref())?; if subargs.address & 0b11 != 0 { @@ -81,6 +82,9 @@ fn writeword(context: &mut ExecutionContext) -> Result<()> { Ok(()) } -pub fn init() -> Command { - Command { app: WritewordArgs::command(), name: "writeword", run: writeword } +pub type Args = WritewordArgs; +impl HumilitySubcommand for Args { + fn run(args: Args, context: &mut ExecutionContext) -> Result<()> { + writeword(args, context) + } } diff --git a/humility-bin/Cargo.toml b/humility-bin/Cargo.toml index 485929ecc..191ee98af 100644 --- a/humility-bin/Cargo.toml +++ b/humility-bin/Cargo.toml @@ -22,8 +22,9 @@ version = "0.12.17" license = "MPL-2.0" [build-dependencies] -cargo_metadata = { workspace = true } anyhow = { workspace = true } +cargo_metadata = { workspace = true } +heck = { workspace = true } # Any dependency marked with option is to allow compiling without libusb [dependencies] @@ -118,4 +119,3 @@ probes = ["humility-cli/probes", "cmd-reset", "cmd-lsusb", "cmd-flash", "cmd-deb [[bin]] name = "humility" path = "src/main.rs" - diff --git a/humility-bin/build.rs b/humility-bin/build.rs index aa4b7d62f..6d12f2f56 100644 --- a/humility-bin/build.rs +++ b/humility-bin/build.rs @@ -3,6 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use anyhow::Result; +use heck::*; use std::collections::BTreeSet; use std::env; use std::fs::File; @@ -26,47 +27,78 @@ fn main() -> Result<()> { write!( output, r##" - -// -// Our generated command description. -// -struct CommandDescription {{ - init: fn() -> Command, - docmsg: &'static str, -}} - -fn dcmds() -> Vec {{ - vec![ +#[derive(::clap::Parser, Debug)] +pub enum Subcommand {{ "## )?; + // + let banned = if std::env::var_os("CARGO_FEATURE_PROBES").is_none() { + // These are everything that can potentially pull in libusb + ["probe-rs", "humility-probes-core", "rusb"].into_iter().collect() + } else { + BTreeSet::new() + }; for id in &metadata.workspace_members { let package = metadata.packages.iter().find(|p| &p.id == id).unwrap().clone(); - if let Some(cmd) = package.name.strip_prefix("humility-cmd-") { - if std::env::var_os("CARGO_FEATURE_PROBES").is_none() && - // These are everything that can potentially pull in libusb - package.dependencies.iter().any(|d| d.name == "probe-rs" || d.name == "humility-probes-core" || d.name == "rusb") - { - continue; - } - cmds.insert(cmd.to_string().replace('-', "_")); + if let Some(cmd) = package.name.strip_prefix("humility-cmd-") + && !package.dependencies.iter().any(|d| banned.contains(&*d.name)) + { + cmds.insert(cmd.to_string()); } } for cmd in cmds.iter() { writeln!( output, - r##" CommandDescription {{ - init: cmd_{}::init, - docmsg: "For additional documentation, run \"humility doc {}\"." - }},"##, - cmd, cmd + " {}(cmd_{}::Args),", + cmd.to_upper_camel_case(), + cmd.to_snake_case() )?; } - write!(output, " ]\n}}")?; + writeln!( + output, + "}} + +pub fn dispatch(c: Subcommand, ctx: &mut ::humility_cli::ExecutionContext) -> anyhow::Result<()> {{ + use ::humility_cli::HumilitySubcommand; + match c {{" + )?; + for cmd in cmds.iter() { + writeln!( + output, + " Subcommand::{}(args) => cmd_{}::Args::run(args, ctx),", + cmd.to_upper_camel_case(), + cmd.to_snake_case(), + )?; + } + writeln!( + output, + " }} +}} + +pub fn name(c: &Subcommand) -> String {{ + use ::clap::{{CommandFactory}}; + match c {{ + " + )?; + + for cmd in cmds.iter() { + writeln!( + output, + " Subcommand::{}(_) => cmd_{}::Args::command().get_name().to_owned(),", + cmd.to_upper_camel_case(), + cmd.to_snake_case(), + )?; + } + writeln!( + output, + " }} +}}" + )?; Ok(()) } diff --git a/humility-bin/src/cmd.rs b/humility-bin/src/cmd.rs index c2d8d8d76..c48cf0ea0 100644 --- a/humility-bin/src/cmd.rs +++ b/humility-bin/src/cmd.rs @@ -2,49 +2,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use anyhow::{Context, Result}; -use clap::Command as ClapCommand; -use humility_cli::ExecutionContext; -use humility_cmd::Command; -use std::collections::HashMap; - -// -// Our build.rs creates cmds.rs, which looks at our workspace to assemble -// the commands, and creates a function (`dcmds`) that we call to get -// a vector of them. -// +// Our `build.rs` creates `cmds.rs`, which looks at our workspace to assemble +// the commands, and creates an `enum Subcommand` with all subcommands include!(concat!(env!("OUT_DIR"), "/cmds.rs")); - -pub fn init( - command: ClapCommand, -) -> (HashMap<&'static str, Command>, ClapCommand) { - let mut cmds = HashMap::new(); - let mut rval = command; - - let dcmds = dcmds(); - - for dcmd in dcmds { - let cmd = (dcmd.init)(); - let app = cmd.app.clone(); - let name = cmd.name; - - cmds.insert(name, cmd); - - rval = rval.subcommand(app.after_help(dcmd.docmsg)); - } - - (cmds, rval) -} - -pub fn subcommand( - context: &mut ExecutionContext, - commands: &HashMap<&'static str, Command>, -) -> Result<()> { - let cmd = context.cli.cmd[0].as_str(); - - let command = commands - .get(cmd) - .with_context(|| format!("command {} not found", cmd))?; - - (command.run)(context) -} diff --git a/humility-bin/src/main.rs b/humility-bin/src/main.rs index f122ced2c..45be823a6 100644 --- a/humility-bin/src/main.rs +++ b/humility-bin/src/main.rs @@ -2,45 +2,70 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use std::collections::HashMap; -use std::ffi::OsString; - -use clap::ArgMatches; -use humility_cli::Cli; -use humility_cmd::Command; - -use anyhow::Result; -use clap::CommandFactory; -use clap::FromArgMatches; -use clap::Parser; - +use clap::{ArgGroup, CommandFactory, FromArgMatches, Parser}; mod cmd; +use humility_cli::{Cli, ExecutionContext}; + +/// Main CLI entry point +/// +/// The distinction between [`Cli`] and [`OuterCli`] is necessary to break a +/// dependency loop: the `Cli` is stored in the [`ExecutionContext`]; commands +/// need to take the `ExecutionContext`; and the `OuterCli` needs to depend on +/// commands. +#[derive(Parser, Debug)] +#[clap( + name = "humility", max_term_width = 80, + group = ArgGroup::new("hubris").multiple(false), + disable_version_flag = true, +)] +struct OuterCli { + #[clap(flatten)] + cli: Cli, + + #[clap(subcommand)] + cmd: Option, +} -fn main() -> Result<()> { - let (commands, m, args) = match parse_args(std::env::args_os()) { - Some(s) => s, - None => std::process::exit(1), +fn main() -> std::process::ExitCode { + let m = OuterCli::command().get_matches(); + let outer_cli = match OuterCli::from_arg_matches(&m) { + Ok(c) => c, + Err(e) => { + eprint!("{e:#}"); + return std::process::ExitCode::FAILURE; + } }; - - if let Some(s) = version(&args) { - println!("{}", s); - std::process::exit(0); + let OuterCli { cli, cmd } = outer_cli; + if let Some(s) = version(&cli) { + eprintln!("{s}"); + return std::process::ExitCode::SUCCESS; }; - let mut context = humility_cli::ExecutionContext::new(args.clone(), &m)?; + let log_level = if cli.verbose { "trace" } else { "warn" }; + let mut context = match ExecutionContext::new(cli, &m) { + Ok(ctx) => ctx, + Err(e) => { + eprintln!("failed to build execution context: {e:#}"); + return std::process::ExitCode::FAILURE; + } + }; - let log_level = if args.verbose { "trace" } else { "warn" }; + let Some(cmd) = cmd else { + eprintln!("humility failed: subcommand expected (--help to list)"); + return std::process::ExitCode::FAILURE; + }; + let name = cmd::name(&cmd); let env = env_logger::Env::default().filter_or("RUST_LOG", log_level); env_logger::init_from_env(env); - if let Err(err) = cmd::subcommand(&mut context, &commands) { - eprintln!("humility {} failed: {:?}", args.cmd[0], err); - std::process::exit(1); + if let Err(err) = cmd::dispatch(cmd, &mut context) { + eprintln!("humility {name} failed: {:?}", err); + std::process::ExitCode::FAILURE + } else { + std::process::ExitCode::SUCCESS } - - Ok(()) } #[cfg(feature = "probes")] @@ -62,42 +87,7 @@ pub(crate) fn version(cli: &Cli) -> Option { } } -pub(crate) fn parse_args( - input: I, -) -> Option<(HashMap<&'static str, Command>, ArgMatches, Cli)> -where - I: IntoIterator, - T: Into + Clone, -{ - // This isn't hugely efficient, but we actually parse our arguments - // twice: the first is with our subcommands grafted into our - // arguments to get us a unified help and error message in the event - // of any parsing value or request for a help message; if that works, - // we parse our arguments again but relying on the - // external_subcommand to directive to allow our subcommand to do any - // parsing on its own. - let (commands, command) = cmd::init(Cli::command()); - - let input: Vec<_> = input.into_iter().collect(); - let input2 = input.clone(); - - let m = match command.try_get_matches_from(input) { - Ok(m) => m, - Err(e) => { - e.print().unwrap(); - return None; - } - }; - - let _args = Cli::from_arg_matches(&m); - - // If we're here, we know that our arguments pass muster from the Clap - // perspective. - Some((commands, m, Cli::parse_from(input2))) -} - #[test] fn validate_clap() { - let (_, clap) = cmd::init(Cli::command()); - clap.clone().debug_assert(); + OuterCli::command().debug_assert() } diff --git a/humility-cli/src/lib.rs b/humility-cli/src/lib.rs index 5fea7801f..ab3f29470 100644 --- a/humility-cli/src/lib.rs +++ b/humility-cli/src/lib.rs @@ -5,7 +5,7 @@ pub mod env; use anyhow::{Context, Result, anyhow, bail}; -use clap::{ArgGroup, ArgMatches, Parser, parser::ValueSource}; +use clap::{ArgMatches, Parser, parser::ValueSource}; use env::Environment; use humility::{ core::Core, @@ -15,11 +15,6 @@ use humility::{ use std::time::Duration; #[derive(Parser, Debug, Clone)] -#[clap( - name = "humility", max_term_width = 80, - group = ArgGroup::new("hubris").multiple(false), - disable_version_flag = true, -)] pub struct Cli { /// verbose messages #[clap(long, short)] @@ -114,10 +109,6 @@ pub struct Cli { conflicts_with = "hubris" )] pub list_targets: bool, - - /// Subcommand to execute - #[clap(trailing_var_arg = true)] - pub cmd: Vec, } impl Cli { @@ -336,6 +327,11 @@ impl Cli { } } +/// Trait representing a Humility subcommand +pub trait HumilitySubcommand: Parser { + fn run(args: Self, context: &mut ExecutionContext) -> Result<()>; +} + pub struct ExecutionContext { pub environment: Option, pub cli: Cli, @@ -477,11 +473,6 @@ impl ExecutionContext { _ => None, }; - if cli.cmd.is_empty() { - eprintln!("humility failed: subcommand expected (--help to list)"); - std::process::exit(1); - } - // // Check to see if we have both a dump and an archive. Because these // conflict with one another but because we allow both of them to be diff --git a/humility-cmd/Cargo.toml b/humility-cmd/Cargo.toml index 53a0c6b8d..eeb30f08e 100644 --- a/humility-cmd/Cargo.toml +++ b/humility-cmd/Cargo.toml @@ -2,10 +2,3 @@ name = "humility-cmd" version = "0.1.0" edition.workspace = true - -[dependencies] -anyhow.workspace = true -clap.workspace = true - -humility.workspace = true -humility-cli.workspace = true diff --git a/humility-cmd/src/lib.rs b/humility-cmd/src/lib.rs index 83e1a9223..3e8a4d516 100644 --- a/humility-cmd/src/lib.rs +++ b/humility-cmd/src/lib.rs @@ -2,21 +2,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use anyhow::Result; -use clap::Command as ClapCommand; - -pub struct Command { - pub app: ClapCommand, - pub name: &'static str, - pub run: fn(&mut humility_cli::ExecutionContext) -> Result<()>, -} - -impl Command { - pub fn short_description(&self) -> String { - self.app.get_about().unwrap().to_string() - } -} - pub struct Dumper { /// Word size, in bytes pub size: usize, From 20270a39fbbee5a9667864e6e1b6a0406c141847 Mon Sep 17 00:00:00 2001 From: Matt Keeter Date: Wed, 13 May 2026 14:35:45 -0700 Subject: [PATCH 2/3] Rename humility-cmd -> humility-hexdump --- Cargo.lock | 34 +++++++++---------- Cargo.toml | 4 +-- cmd/gimlet/Cargo.toml | 2 +- cmd/gimlet/src/lib.rs | 2 +- cmd/hiffy/Cargo.toml | 2 +- cmd/hiffy/src/lib.rs | 2 +- cmd/i2c/Cargo.toml | 2 +- cmd/i2c/src/lib.rs | 2 +- cmd/ibc/Cargo.toml | 4 +-- cmd/lpc55gpio/Cargo.toml | 2 +- cmd/qspi/Cargo.toml | 2 +- cmd/qspi/src/lib.rs | 2 +- cmd/readmem/Cargo.toml | 2 +- cmd/readmem/src/lib.rs | 2 +- cmd/rencm/Cargo.toml | 2 +- cmd/rencm/src/lib.rs | 2 +- cmd/spctrl/Cargo.toml | 2 +- cmd/spctrl/src/lib.rs | 2 +- cmd/spi/Cargo.toml | 2 +- cmd/spi/src/lib.rs | 2 +- cmd/stackmargin/Cargo.toml | 2 +- cmd/vpd/Cargo.toml | 2 +- cmd/vpd/src/lib.rs | 2 +- humility-bin/Cargo.toml | 2 +- {humility-cmd => humility-hexdump}/Cargo.toml | 2 +- {humility-cmd => humility-hexdump}/src/lib.rs | 0 26 files changed, 43 insertions(+), 43 deletions(-) rename {humility-cmd => humility-hexdump}/Cargo.toml (67%) rename {humility-cmd => humility-hexdump}/src/lib.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index b65aa0219..a211d72eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1639,7 +1639,6 @@ dependencies = [ "heck", "hif", "humility-cli", - "humility-cmd", "humility-cmd-auxflash", "humility-cmd-console-proxy", "humility-cmd-counters", @@ -1697,6 +1696,7 @@ dependencies = [ "humility-cmd-writeword", "humility-core", "humility-cortex", + "humility-hexdump", "indexmap 2.14.0", "indicatif", "jep106 0.3.0", @@ -1729,10 +1729,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "humility-cmd" -version = "0.1.0" - [[package]] name = "humility-cmd-auxflash" version = "0.1.0" @@ -1942,8 +1938,8 @@ dependencies = [ "gimlet-inspector-protocol", "hubpack", "humility-cli", - "humility-cmd", "humility-core", + "humility-hexdump", "indexmap 2.14.0", "parse_int", "serde", @@ -1985,8 +1981,8 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", "humility-core", + "humility-hexdump", "humility-hiffy", "humility-idol", "idol", @@ -2041,7 +2037,7 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", + "humility-hexdump", "humility-hiffy", "humility-i2c", "humility-log", @@ -2058,8 +2054,8 @@ dependencies = [ "colored", "hif", "humility-cli", - "humility-cmd", "humility-core", + "humility-hexdump", "humility-hiffy", "humility-idol", "idol", @@ -2088,7 +2084,7 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", + "humility-hexdump", "humility-hiffy", "parse_int", ] @@ -2257,8 +2253,8 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", "humility-core", + "humility-hexdump", "humility-hiffy", "humility-idol", "indicatif", @@ -2274,8 +2270,8 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-core", + "humility-hexdump", "humility-log", "parse-size", "parse_int", @@ -2332,8 +2328,8 @@ dependencies = [ "csv", "hif", "humility-cli", - "humility-cmd", "humility-core", + "humility-hexdump", "humility-hiffy", "humility-i2c", "idt8a3xxxx", @@ -2433,7 +2429,7 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", + "humility-hexdump", "humility-hiffy", "parse_int", ] @@ -2464,8 +2460,8 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", "humility-core", + "humility-hexdump", "humility-hiffy", "parse_int", ] @@ -2477,8 +2473,8 @@ dependencies = [ "anyhow", "clap", "humility-cli", - "humility-cmd", "humility-core", + "humility-hexdump", ] [[package]] @@ -2564,8 +2560,8 @@ dependencies = [ "clap", "hif", "humility-cli", - "humility-cmd", "humility-core", + "humility-hexdump", "humility-hiffy", "humility-idol", "idol", @@ -2679,6 +2675,10 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "humility-hexdump" +version = "0.1.0" + [[package]] name = "humility-hiffy" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index b82bac501..3ea6b7608 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,11 +8,11 @@ members = [ "humility-arch-cortex", "humility-auxflash", "humility-bin", - "humility-cmd", "humility-cli", "humility-core", "humility-doppel", "humility-dump-agent", + "humility-hexdump", "humility-hiffy", "humility-i2c", "humility-idol", @@ -114,10 +114,10 @@ humility = { path = "./humility-core", package = "humility-core" } humility-arch-arm = { path = "./humility-arch-arm" } humility-auxflash = { path = "./humility-auxflash" } humility-cortex = { path = "./humility-arch-cortex" } -humility-cmd = { path = "./humility-cmd" } humility-cli = { path = "./humility-cli", default-features = false } humility-dump-agent = { path = "./humility-dump-agent" } humility-doppel = { path = "./humility-doppel" } +humility-hexdump = { path = "./humility-hexdump" } humility-hiffy = { path = "./humility-hiffy" } humility-i2c = { path = "./humility-i2c" } humility-idol = { path = "./humility-idol" } diff --git a/cmd/gimlet/Cargo.toml b/cmd/gimlet/Cargo.toml index 9bf93c8bc..cc948232c 100644 --- a/cmd/gimlet/Cargo.toml +++ b/cmd/gimlet/Cargo.toml @@ -6,8 +6,8 @@ description = "Gimlet-specific diagnostic commands" [dependencies] humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true +humility-hexdump.workspace = true hubpack.workspace = true gimlet-inspector-protocol.workspace = true diff --git a/cmd/gimlet/src/lib.rs b/cmd/gimlet/src/lib.rs index 940ac577e..db7aa1fae 100644 --- a/cmd/gimlet/src/lib.rs +++ b/cmd/gimlet/src/lib.rs @@ -20,7 +20,7 @@ use anyhow::{Context, Result, bail}; use clap::{ArgGroup, Parser}; use humility::net::ScopedV6Addr; use humility_cli::{ExecutionContext, HumilitySubcommand}; -use humility_cmd::Dumper; +use humility_hexdump::Dumper; /// This is defined in the gimlet TOML. const HARDCODED_PORT: u16 = 23547; diff --git a/cmd/hiffy/Cargo.toml b/cmd/hiffy/Cargo.toml index 0533a12c0..60f873805 100644 --- a/cmd/hiffy/Cargo.toml +++ b/cmd/hiffy/Cargo.toml @@ -14,7 +14,7 @@ hif.workspace = true idol.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true +humility-hexdump.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true diff --git a/cmd/hiffy/src/lib.rs b/cmd/hiffy/src/lib.rs index 24788ab58..d8748c179 100644 --- a/cmd/hiffy/src/lib.rs +++ b/cmd/hiffy/src/lib.rs @@ -51,7 +51,7 @@ use clap::Parser; use humility::hubris::*; use humility::warn; use humility_cli::{ExecutionContext, HumilitySubcommand}; -use humility_cmd::Dumper; +use humility_hexdump::Dumper; use humility_hiffy::*; use humility_idol as idol; use std::io::IsTerminal; diff --git a/cmd/i2c/Cargo.toml b/cmd/i2c/Cargo.toml index 5d2716a71..52c4af448 100644 --- a/cmd/i2c/Cargo.toml +++ b/cmd/i2c/Cargo.toml @@ -13,7 +13,7 @@ indicatif.workspace = true hif.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true +humility-hexdump.workspace = true humility-hiffy.workspace = true humility-i2c.workspace = true humility-log.workspace = true diff --git a/cmd/i2c/src/lib.rs b/cmd/i2c/src/lib.rs index b4cbd402a..462c221c3 100644 --- a/cmd/i2c/src/lib.rs +++ b/cmd/i2c/src/lib.rs @@ -94,7 +94,7 @@ use anyhow::{Result, bail}; use clap::Parser; use hif::*; use humility_cli::{ExecutionContext, HumilitySubcommand}; -use humility_cmd::Dumper; +use humility_hexdump::Dumper; use humility_hiffy::*; use humility_log::msg; diff --git a/cmd/ibc/Cargo.toml b/cmd/ibc/Cargo.toml index 95231a519..485c84d60 100644 --- a/cmd/ibc/Cargo.toml +++ b/cmd/ibc/Cargo.toml @@ -12,10 +12,10 @@ parse_int.workspace = true zerocopy.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true -humility-idol.workspace = true +humility-hexdump.workspace = true humility-hiffy.workspace = true +humility-idol.workspace = true hif.workspace = true idol.workspace = true diff --git a/cmd/lpc55gpio/Cargo.toml b/cmd/lpc55gpio/Cargo.toml index 94238ca59..80b7007b1 100644 --- a/cmd/lpc55gpio/Cargo.toml +++ b/cmd/lpc55gpio/Cargo.toml @@ -11,5 +11,5 @@ anyhow.workspace = true parse_int.workspace = true humility-cli.workspace = true -humility-cmd.workspace = true +humility-hexdump.workspace = true humility-hiffy.workspace = true diff --git a/cmd/qspi/Cargo.toml b/cmd/qspi/Cargo.toml index d13c31fe5..a55201c72 100644 --- a/cmd/qspi/Cargo.toml +++ b/cmd/qspi/Cargo.toml @@ -14,7 +14,7 @@ log.workspace = true sha2.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true +humility-hexdump.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true diff --git a/cmd/qspi/src/lib.rs b/cmd/qspi/src/lib.rs index ec5cb3dd1..feb35fab1 100644 --- a/cmd/qspi/src/lib.rs +++ b/cmd/qspi/src/lib.rs @@ -84,7 +84,7 @@ use humility::core::Core; use humility_cli::{ExecutionContext, HumilitySubcommand}; -use humility_cmd::Dumper; +use humility_hexdump::Dumper; use humility_hiffy::*; use humility_idol::{HubrisIdol, IdolArgument}; use sha2::{Digest, Sha256}; diff --git a/cmd/readmem/Cargo.toml b/cmd/readmem/Cargo.toml index dfb1962d2..76db57373 100644 --- a/cmd/readmem/Cargo.toml +++ b/cmd/readmem/Cargo.toml @@ -6,8 +6,8 @@ description = "read and display memory region" [dependencies] humility = { workspace = true } -humility-cmd = { workspace = true } humility-cli = { workspace = true } +humility-hexdump = { workspace = true } humility-log = { workspace = true } clap = { workspace = true } anyhow = { workspace = true } diff --git a/cmd/readmem/src/lib.rs b/cmd/readmem/src/lib.rs index 948b5d462..d65b23721 100644 --- a/cmd/readmem/src/lib.rs +++ b/cmd/readmem/src/lib.rs @@ -119,7 +119,7 @@ use anyhow::{Result, bail}; use clap::Parser; use humility::hubris::*; use humility_cli::{ExecutionContext, HumilitySubcommand}; -use humility_cmd::Dumper; +use humility_hexdump::Dumper; use std::convert::TryInto; use std::io::Write; use std::path::PathBuf; diff --git a/cmd/rencm/Cargo.toml b/cmd/rencm/Cargo.toml index 1de586534..f99f09c9d 100644 --- a/cmd/rencm/Cargo.toml +++ b/cmd/rencm/Cargo.toml @@ -16,7 +16,7 @@ serde.workspace = true csv.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true +humility-hexdump.workspace = true humility-hiffy.workspace = true humility-i2c.workspace = true diff --git a/cmd/rencm/src/lib.rs b/cmd/rencm/src/lib.rs index de05637d5..d187aca42 100644 --- a/cmd/rencm/src/lib.rs +++ b/cmd/rencm/src/lib.rs @@ -11,7 +11,7 @@ use humility::core::Core; use humility::hubris::*; use humility_cli::{ExecutionContext, HumilitySubcommand}; -use humility_cmd::Dumper; +use humility_hexdump::Dumper; use humility_hiffy::*; use humility_i2c::I2cArgs; diff --git a/cmd/spctrl/Cargo.toml b/cmd/spctrl/Cargo.toml index 010ec9933..b2098e6ab 100644 --- a/cmd/spctrl/Cargo.toml +++ b/cmd/spctrl/Cargo.toml @@ -10,6 +10,6 @@ clap.workspace = true anyhow.workspace = true parse_int.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true +humility-hexdump.workspace = true humility-hiffy.workspace = true diff --git a/cmd/spctrl/src/lib.rs b/cmd/spctrl/src/lib.rs index 4c9221a93..ee64133ad 100644 --- a/cmd/spctrl/src/lib.rs +++ b/cmd/spctrl/src/lib.rs @@ -45,7 +45,7 @@ //! ``` use humility_cli::{ExecutionContext, HumilitySubcommand}; -use humility_cmd::Dumper; +use humility_hexdump::Dumper; use humility_hiffy::*; use std::str; diff --git a/cmd/spi/Cargo.toml b/cmd/spi/Cargo.toml index 91c06f875..8d553d93b 100644 --- a/cmd/spi/Cargo.toml +++ b/cmd/spi/Cargo.toml @@ -11,6 +11,6 @@ anyhow.workspace = true parse_int.workspace = true humility.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true +humility-hexdump.workspace = true humility-hiffy.workspace = true diff --git a/cmd/spi/src/lib.rs b/cmd/spi/src/lib.rs index 51dd28918..891fbe72e 100644 --- a/cmd/spi/src/lib.rs +++ b/cmd/spi/src/lib.rs @@ -34,7 +34,7 @@ use humility::hubris::*; use humility_cli::{ExecutionContext, HumilitySubcommand}; -use humility_cmd::Dumper; +use humility_hexdump::Dumper; use humility_hiffy::*; use std::convert::TryInto; diff --git a/cmd/stackmargin/Cargo.toml b/cmd/stackmargin/Cargo.toml index c0495b6cf..b5334228d 100644 --- a/cmd/stackmargin/Cargo.toml +++ b/cmd/stackmargin/Cargo.toml @@ -6,7 +6,7 @@ description = "calculate and print stack margins by task" [dependencies] humility = { workspace = true } -humility-cmd = { workspace = true } humility-cli = { workspace = true } +humility-hexdump = { workspace = true } clap = { workspace = true } anyhow = { workspace = true } diff --git a/cmd/vpd/Cargo.toml b/cmd/vpd/Cargo.toml index 463dff275..0c48d723a 100644 --- a/cmd/vpd/Cargo.toml +++ b/cmd/vpd/Cargo.toml @@ -18,8 +18,8 @@ indicatif.workspace = true serde.workspace = true ron.workspace = true -humility-cmd.workspace = true humility-cli.workspace = true +humility-hexdump.workspace = true humility-hiffy.workspace = true humility-idol.workspace = true humility.workspace = true diff --git a/cmd/vpd/src/lib.rs b/cmd/vpd/src/lib.rs index 7e1ed424e..145049905 100644 --- a/cmd/vpd/src/lib.rs +++ b/cmd/vpd/src/lib.rs @@ -108,7 +108,7 @@ use hif::*; use humility::core::Core; use humility::hubris::*; use humility_cli::{ExecutionContext, HumilitySubcommand}; -use humility_cmd::Dumper; +use humility_hexdump::Dumper; use humility_hiffy::*; use humility_idol::{self as idol, HubrisIdol}; use indicatif::{ProgressBar, ProgressStyle}; diff --git a/humility-bin/Cargo.toml b/humility-bin/Cargo.toml index 191ee98af..a8b4fc3de 100644 --- a/humility-bin/Cargo.toml +++ b/humility-bin/Cargo.toml @@ -33,8 +33,8 @@ hif = { workspace = true } spd = { workspace = true } humility = { workspace = true } humility-cortex = { workspace = true } -humility-cmd = { workspace = true } humility-cli = { workspace = true, default-features = false } +humility-hexdump = { workspace = true } cmd-auxflash = { workspace = true } cmd-console-proxy = { workspace = true } cmd-counters = { workspace = true } diff --git a/humility-cmd/Cargo.toml b/humility-hexdump/Cargo.toml similarity index 67% rename from humility-cmd/Cargo.toml rename to humility-hexdump/Cargo.toml index eeb30f08e..1229ec99a 100644 --- a/humility-cmd/Cargo.toml +++ b/humility-hexdump/Cargo.toml @@ -1,4 +1,4 @@ [package] -name = "humility-cmd" +name = "humility-hexdump" version = "0.1.0" edition.workspace = true diff --git a/humility-cmd/src/lib.rs b/humility-hexdump/src/lib.rs similarity index 100% rename from humility-cmd/src/lib.rs rename to humility-hexdump/src/lib.rs From 1cefecdb9cc1de446a3ec29cec1a930dc3a0923e Mon Sep 17 00:00:00 2001 From: Matt Keeter Date: Wed, 13 May 2026 14:42:00 -0700 Subject: [PATCH 3/3] Update README --- DEVELOPING.mkdn | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/DEVELOPING.mkdn b/DEVELOPING.mkdn index cdb27bbbc..de08cfc6e 100644 --- a/DEVELOPING.mkdn +++ b/DEVELOPING.mkdn @@ -36,11 +36,7 @@ So you've decided to add a subcommand to Humility. Here's what you need to do. make sure any new name starts with `humility-cmd-` (e.g. `humility-cmd-yourcommand`). -2. Review the settings in the `init` routine you cribbed from to make sure they - reflect your subcommand. In particular, the name must appear a second time in - the `name:` field. - -3. Cite your new subcommand from the root `Cargo.toml`. This needs to happen in +2. Cite your new subcommand from the root `Cargo.toml`. This needs to happen in three places using two different names: in the `workspace.members` element using the relative path (e.g. `cmd/yourcommand`); in the `workspace.dependencies` section using the name of your package with the @@ -48,10 +44,10 @@ So you've decided to add a subcommand to Humility. Here's what you need to do. `dependencies` table with a line reading `cmd-yourcommand = {workspace = true}`. -4. Regenerate the README file by running `cargo xtask readme`. The `xtask` bit +3. Regenerate the README file by running `cargo xtask readme`. The `xtask` bit there is very important. -5. If you're adding a new command, you almost certainly want to bump Humility's +4. If you're adding a new command, you almost certainly want to bump Humility's patch version. This makes it easier to tell whether users have the command. Doing this requires an extra step compared to a normal Rust package; see the previous section in this file.