use clap::{Parser, Subcommand, ValueEnum};
use repopilot::baseline::gate::FailOn;
use repopilot::findings::types::Severity;
use repopilot::output::OutputFormat;
use std::path::PathBuf;
#[derive(Parser)]
#[command(name = "repopilot")]
#[command(version)]
#[command(
about = "Local-first CLI for repository audit, architecture risk detection, baseline tracking, and CI-friendly code review.",
long_about = None
)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
pub enum Commands {
Baseline {
#[command(subcommand)]
command: BaselineCommands,
},
Compare {
before: std::path::PathBuf,
after: std::path::PathBuf,
#[arg(long, value_enum, default_value = "console")]
format: CompareOutputFormatArg,
#[arg(short, long)]
output: Option<std::path::PathBuf>,
},
Scan {
path: PathBuf,
#[arg(long, value_enum)]
format: Option<OutputFormatArg>,
#[arg(short, long)]
output: Option<PathBuf>,
#[arg(long)]
config: Option<PathBuf>,
#[arg(long)]
baseline: Option<PathBuf>,
#[arg(long, value_enum)]
fail_on: Option<FailOnArg>,
#[arg(long)]
max_file_loc: Option<usize>,
#[arg(long)]
max_directory_modules: Option<usize>,
#[arg(long)]
max_directory_depth: Option<usize>,
},
Init {
#[arg(long)]
force: bool,
#[arg(long, default_value = "repopilot.toml")]
path: PathBuf,
},
}
#[derive(Subcommand)]
pub enum BaselineCommands {
Create {
path: PathBuf,
#[arg(short, long)]
output: Option<PathBuf>,
#[arg(long)]
force: bool,
},
}
#[derive(Clone, Copy, Debug, ValueEnum)]
pub enum OutputFormatArg {
Console,
Html,
Json,
Markdown,
}
#[derive(Clone, Copy, Debug, ValueEnum)]
pub enum CompareOutputFormatArg {
Console,
Json,
Markdown,
}
#[derive(Clone, Copy, Debug, ValueEnum)]
pub enum FailOnArg {
NewLow,
NewMedium,
NewHigh,
NewCritical,
Low,
Medium,
High,
Critical,
}
impl From<OutputFormatArg> for OutputFormat {
fn from(format: OutputFormatArg) -> Self {
match format {
OutputFormatArg::Console => OutputFormat::Console,
OutputFormatArg::Html => OutputFormat::Html,
OutputFormatArg::Json => OutputFormat::Json,
OutputFormatArg::Markdown => OutputFormat::Markdown,
}
}
}
impl From<FailOnArg> for FailOn {
fn from(value: FailOnArg) -> Self {
match value {
FailOnArg::NewLow => FailOn::New(Severity::Low),
FailOnArg::NewMedium => FailOn::New(Severity::Medium),
FailOnArg::NewHigh => FailOn::New(Severity::High),
FailOnArg::NewCritical => FailOn::New(Severity::Critical),
FailOnArg::Low => FailOn::Any(Severity::Low),
FailOnArg::Medium => FailOn::Any(Severity::Medium),
FailOnArg::High => FailOn::Any(Severity::High),
FailOnArg::Critical => FailOn::Any(Severity::Critical),
}
}
}