use std::path::PathBuf;
use clap::{Parser, Subcommand, ValueEnum};
#[derive(Parser, Debug)]
#[command(
name = "bitvex",
version,
about = "CRA compliance tool: generates OpenVEX reports from Yocto build artifacts"
)]
pub struct Args {
#[command(subcommand)]
pub command: Option<Command>,
#[arg(long, value_name = "PATH")]
pub sbom: Option<PathBuf>,
#[arg(long = "kernel-config", value_name = "PATH")]
pub kernel_config: Vec<PathBuf>,
#[arg(long = "uboot-config", value_name = "PATH")]
pub uboot_config: Option<PathBuf>,
#[arg(long = "device-tree", value_name = "PATH")]
pub device_tree: Option<PathBuf>,
#[arg(
long,
short,
value_name = "PATH",
default_value = "bitvex-report.vex.json"
)]
pub output: PathBuf,
#[arg(long, value_enum, default_value = "openvex")]
pub format: OutputFormat,
#[arg(long, default_value = "BitVex <bitvex@automated>")]
pub author: String,
#[arg(long, value_name = "PATH")]
pub rules: Option<PathBuf>,
#[arg(long)]
pub offline: bool,
#[arg(long)]
pub download_db: bool,
#[arg(long = "db-path", value_name = "PATH")]
pub db_path: Option<PathBuf>,
#[arg(long)]
pub profile: Option<DownloadProfile>,
#[arg(long)]
pub epss: bool,
#[arg(long)]
pub epss_offline: bool,
#[arg(long)]
pub download_epss_db: bool,
#[arg(long = "epss-db-path", value_name = "PATH")]
pub epss_db_path: Option<PathBuf>,
#[arg(long, value_name = "FLOAT", default_value = "0.0")]
pub epss_threshold: f64,
#[arg(long)]
pub fail_on_any: bool,
#[arg(long)]
pub fail_on_high: bool,
#[arg(long)]
pub fail_on_critical: bool,
#[arg(long, short)]
pub yes: bool,
#[arg(long, short)]
pub verbose: bool,
}
#[derive(Subcommand, Debug)]
pub enum Command {
Diff {
#[arg(long)]
old: PathBuf,
#[arg(long)]
new: PathBuf,
#[arg(long, short)]
output: Option<PathBuf>,
},
Delta {
#[arg(long)]
old: PathBuf,
#[arg(long)]
new: PathBuf,
#[arg(long, short)]
output: Option<PathBuf>,
},
DownloadDb {
#[arg(long = "db-path", value_name = "PATH")]
db_path: Option<PathBuf>,
#[arg(long, value_delimiter = ',')]
ecosystems: Option<Vec<String>>,
#[arg(long)]
profile: Option<DownloadProfile>,
#[arg(long, short)]
yes: bool,
},
DownloadEpssDb {
#[arg(long = "db-path", value_name = "PATH")]
db_path: Option<PathBuf>,
#[arg(long, short)]
yes: bool,
},
Watch {
#[arg(long, short, value_name = "PATH", default_value = "bitvex-watch.toml")]
config: PathBuf,
},
Status {
#[arg(long)]
project: Option<String>,
#[arg(long = "db-path", value_name = "PATH")]
db_path: Option<PathBuf>,
},
}
#[derive(Debug, Clone, ValueEnum)]
pub enum DownloadProfile {
Small,
Medium,
Big,
Complete,
}
#[derive(Debug, Clone, ValueEnum)]
pub enum OutputFormat {
Openvex,
Sarif,
}
impl DownloadProfile {
pub fn ecosystems(&self) -> &[&str] {
match self {
DownloadProfile::Small => &["Linux"],
DownloadProfile::Medium => &["Linux", "Alpine", "crates.io"],
DownloadProfile::Big => &["Linux", "Alpine", "Debian", "PyPI", "crates.io"],
DownloadProfile::Complete => &[
"Alpine",
"Debian",
"Ubuntu",
"Linux",
"crates.io",
"Go",
"npm",
"PyPI",
"Maven",
"NuGet",
],
}
}
pub fn name(&self) -> &str {
match self {
DownloadProfile::Small => "small",
DownloadProfile::Medium => "medium",
DownloadProfile::Big => "big",
DownloadProfile::Complete => "complete",
}
}
}