1use std::path::PathBuf;
2
3use clap::error::ErrorKind;
4use clap::{Parser, ValueEnum};
5
6use crate::graph::RiskTier;
7
8#[derive(Debug, Clone, Parser)]
9#[command(name = "blast-radius")]
10#[command(
11 version,
12 about = "Estimate the transitive blast radius of frontend code changes"
13)]
14pub struct Cli {
15 #[command(subcommand)]
16 pub command: Command,
17
18 #[arg(long, global = true, default_value = ".")]
19 pub repo_root: PathBuf,
20
21 #[arg(long, global = true, value_enum, default_value_t = OutputFormat::Tree)]
22 pub format: OutputFormat,
23
24 #[arg(long, global = true)]
25 pub output: Option<PathBuf>,
26
27 #[arg(long, short = 'v', global = true, default_value_t = false)]
29 pub verbose: bool,
30
31 #[arg(long, global = true, default_value_t = false)]
33 pub explain_unresolved: bool,
34
35 #[arg(long, global = true)]
38 pub fail_threshold: Option<usize>,
39
40 #[arg(long, global = true, value_enum)]
42 pub fail_on_risk: Option<RiskTier>,
43}
44
45#[derive(Debug, Clone, Parser)]
46pub enum Command {
47 Export { file: PathBuf, export_name: String },
49 File { file: PathBuf },
51 Files {
54 #[arg(required = true, num_args = 1..)]
55 files: Vec<PathBuf>,
56 },
57}
58
59#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
60pub enum OutputFormat {
61 Tree,
62 Json,
63 Mermaid,
64 Dot,
65}
66
67impl Cli {
68 pub fn parse_args() -> Self {
72 match Self::try_parse() {
73 Ok(cli) => cli,
74 Err(error) => {
75 let code = match error.kind() {
76 ErrorKind::DisplayHelp | ErrorKind::DisplayVersion => 0,
77 _ => 64,
78 };
79 let _ = error.print();
80 std::process::exit(code);
81 }
82 }
83 }
84}