mod audit;
use self::audit::AuditCommand;
use crate::config::AuditConfig;
use abscissa_core::{config::Override, Command, Configurable, FrameworkError, Runnable};
use clap::Parser;
use std::{ops::Deref, path::PathBuf};
pub const CONFIG_FILE: &str = "audit.toml";
#[derive(Command, Debug, Parser, Runnable)]
#[command(bin_name = "cargo")]
pub enum CargoAuditSubCommand {
#[command(about = "Audit Cargo.lock files for vulnerable crates")]
Audit(AuditCommand),
}
#[derive(Command, Debug, Parser)]
#[command(author, version, about)]
pub struct CargoAuditCommand {
#[command(subcommand)]
cmd: CargoAuditSubCommand,
#[arg(short = 'v', long, help = "Increase verbosity")]
pub verbose: bool,
}
impl Runnable for CargoAuditCommand {
fn run(&self) {
self.cmd.run()
}
}
impl Configurable<AuditConfig> for CargoAuditCommand {
fn config_path(&self) -> Option<PathBuf> {
let project_config_filename = PathBuf::from("./.cargo").join(CONFIG_FILE);
if project_config_filename.exists() {
return Some(project_config_filename);
}
let home_config_filename = home::cargo_home()
.ok()
.map(|cargo_home| cargo_home.join(CONFIG_FILE))?;
if home_config_filename.exists() {
Some(home_config_filename)
} else {
None
}
}
fn process_config(&self, config: AuditConfig) -> Result<AuditConfig, FrameworkError> {
match &self.cmd {
CargoAuditSubCommand::Audit(cmd) => cmd.override_config(config),
}
}
}
impl Deref for CargoAuditCommand {
type Target = AuditCommand;
fn deref(&self) -> &AuditCommand {
match &self.cmd {
CargoAuditSubCommand::Audit(cmd) => cmd,
}
}
}