use std::fmt::Write as _;
use clap::CommandFactory;
use crate::cli::Cli;
pub(crate) fn render() -> String {
let root = Cli::command();
let mut out = String::new();
out.push_str("# CLI Command Reference\n\n");
out.push_str(
"Generated from `Cli::command()` (clap's command-tree introspection) — \
every `tm <command>` and its nested subcommands, verbatim. Source: \
`crates/trusty-mpm/src/bin/tm/cli/mod.rs` (top-level `Command` enum) \
plus one action enum per group under `cli/actions/*.rs`. Regenerate \
with `tm generate capabilities`.\n\n",
);
let mut commands: Vec<&clap::Command> = root.get_subcommands().collect();
commands.sort_by_key(|c| c.get_name().to_string());
let _ = writeln!(out, "{} top-level commands.\n", commands.len());
for cmd in commands {
render_command(cmd, 0, &mut out);
}
out
}
fn render_command(cmd: &clap::Command, depth: usize, out: &mut String) {
let indent = " ".repeat(depth);
let name = cmd.get_name();
let about = cmd.get_about().map(|s| s.to_string()).unwrap_or_default();
if about.is_empty() {
let _ = writeln!(out, "{indent}- `{name}`");
} else {
let _ = writeln!(out, "{indent}- `{name}` — {about}");
}
let mut subs: Vec<&clap::Command> = cmd.get_subcommands().collect();
subs.sort_by_key(|c| c.get_name().to_string());
for sub in subs {
render_command(sub, depth + 1, out);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cli_tree_render_contains_known_command() {
let rendered = render();
assert!(rendered.contains("`doctor`"), "{rendered}");
assert!(rendered.contains("`session`"), "{rendered}");
assert!(rendered.contains("`generate`"), "{rendered}");
assert!(rendered.contains("`capabilities`"), "{rendered}");
}
#[test]
fn cli_tree_render_is_deterministic() {
assert_eq!(render(), render());
}
#[test]
fn cli_tree_render_lists_top_level_command_count() {
let root = Cli::command();
let expected = root.get_subcommands().count();
let rendered = render();
assert!(
rendered.contains(&format!("{expected} top-level commands.")),
"{rendered}"
);
}
}