use std::path::PathBuf;
use clap::{Args, Parser, Subcommand, ValueEnum};
#[derive(Parser)]
#[command(
name = "secretrace",
author = "Secretrace Contributors",
version,
about = "Detect hardcoded secrets in Rust codebases",
long_about = "A research-grade static analysis tool for detecting hardcoded secrets \
in Rust code with intelligent false-positive filtering."
)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
#[arg(short, long, global = true)]
pub verbose: bool,
#[arg(short, long, global = true)]
pub quiet: bool,
#[arg(short, long, global = true)]
pub config: Option<PathBuf>,
}
#[derive(Subcommand)]
pub enum Commands {
Scan(ScanArgs),
Init(InitArgs),
Explain(ExplainArgs),
Debug(DebugArgs),
}
#[derive(Args)]
pub struct ScanArgs {
#[arg(default_value = ".")]
pub path: PathBuf,
#[arg(short, long, default_value = "70")]
pub threshold: i32,
#[arg(short, long, value_enum, default_value = "text")]
pub format: OutputFormatArg,
#[arg(short, long)]
pub output: Option<PathBuf>,
#[arg(long)]
pub include_tests: bool,
#[arg(long)]
pub include_examples: bool,
#[arg(long)]
pub ignore: Vec<String>,
#[arg(long)]
pub only: Vec<String>,
#[arg(long, default_value = "0")]
pub max_files: usize,
#[arg(short = 'j', long)]
pub jobs: Option<usize>,
#[arg(long)]
pub fail_on_findings: bool,
#[arg(long)]
pub show_scores: bool,
#[arg(long)]
pub scan_history: bool,
#[arg(long, default_value = "0")]
pub max_commits: usize,
#[arg(long)]
pub since: Option<String>,
#[arg(long)]
pub until: Option<String>,
#[arg(long)]
pub branch: Option<String>,
#[arg(long)]
pub exclude_deleted: bool,
#[arg(long)]
pub only_deleted: bool,
}
#[derive(Args)]
pub struct InitArgs {
#[arg(short, long, default_value = ".vsec.toml")]
pub output: PathBuf,
#[arg(short, long)]
pub force: bool,
#[arg(long)]
pub minimal: bool,
}
#[derive(Args)]
pub struct ExplainArgs {
pub finding_id: String,
#[arg(short, long)]
pub results: Option<PathBuf>,
}
#[derive(Args)]
pub struct DebugArgs {
pub path: PathBuf,
#[arg(long)]
pub show_all: bool,
#[arg(long)]
pub show_ast: bool,
}
#[derive(Clone, Copy, ValueEnum)]
pub enum OutputFormatArg {
Text,
Json,
Sarif,
Markdown,
Github,
}
impl From<OutputFormatArg> for crate::output::OutputFormat {
fn from(arg: OutputFormatArg) -> Self {
match arg {
OutputFormatArg::Text => Self::Text,
OutputFormatArg::Json => Self::Json,
OutputFormatArg::Sarif => Self::Sarif,
OutputFormatArg::Markdown => Self::Markdown,
OutputFormatArg::Github => Self::Github,
}
}
}