Skip to main content

atproto_devtool/
cli.rs

1//! Root clap parser and dispatch entry point.
2
3use clap::Parser;
4use miette::Result;
5use std::process::ExitCode;
6use tracing_subscriber::{EnvFilter, fmt};
7
8use crate::commands::Command;
9use crate::common::diagnostics::install_miette_handler;
10
11/// Top-level `atproto-devtool` CLI.
12#[derive(Debug, Parser)]
13#[command(
14    name = "atproto-devtool",
15    version,
16    about = "Diagnostics and conformance tooling for atproto services.",
17    long_about = None,
18)]
19pub struct Cli {
20    /// Enable verbose (DEBUG-level) logging to stderr.
21    #[arg(long, global = true)]
22    verbose: bool,
23
24    /// Disable ANSI color in rendered diagnostics.
25    #[arg(long, global = true)]
26    no_color: bool,
27
28    #[command(subcommand)]
29    command: Command,
30}
31
32/// Parse `std::env::args()`, install global handlers, and dispatch.
33///
34/// Returns `Result<ExitCode, miette::Report>` to propagate exit codes through
35/// the dispatch chain. The main handler renders errors with exit code 1.
36pub async fn run() -> Result<ExitCode> {
37    let cli = Cli::parse();
38
39    install_miette_handler(cli.no_color)?;
40    install_tracing(cli.verbose);
41
42    cli.command.run(cli.no_color).await
43}
44
45fn install_tracing(verbose: bool) {
46    let default_filter = if verbose { "debug" } else { "warn" };
47    let filter =
48        EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(default_filter));
49
50    let _ = fmt()
51        .with_env_filter(filter)
52        .with_writer(std::io::stderr)
53        .try_init();
54}