use std::path::PathBuf;
use anyhow::Result;
use clap::Args;
use tldr_core::{scan_secrets, SecretsReport, Severity};
use crate::commands::daemon_router::{params_with_path, try_daemon_route};
use crate::output::{format_secrets_text, OutputFormat, OutputWriter};
#[derive(Debug, Args)]
pub struct SecretsArgs {
#[arg(default_value = ".")]
pub path: PathBuf,
#[arg(long, short = 'e', default_value = "4.5")]
pub entropy_threshold: f64,
#[arg(long)]
pub include_test: bool,
#[arg(long, short = 's')]
pub min_severity: Option<SeverityArg>,
}
#[derive(Debug, Clone, Copy, clap::ValueEnum)]
pub enum SeverityArg {
Low,
Medium,
High,
Critical,
}
impl From<SeverityArg> for Severity {
fn from(arg: SeverityArg) -> Self {
match arg {
SeverityArg::Low => Severity::Low,
SeverityArg::Medium => Severity::Medium,
SeverityArg::High => Severity::High,
SeverityArg::Critical => Severity::Critical,
}
}
}
impl SecretsArgs {
pub fn run(&self, format: OutputFormat, quiet: bool) -> Result<()> {
let writer = OutputWriter::new(format, quiet);
if let Some(report) = try_daemon_route::<SecretsReport>(
&self.path,
"secrets",
params_with_path(Some(&self.path)),
) {
if writer.is_text() {
let text = format_secrets_text(&report);
writer.write_text(&text)?;
return Ok(());
} else {
writer.write(&report)?;
return Ok(());
}
}
writer.progress(&format!(
"Scanning for secrets in {}...",
self.path.display()
));
let report = scan_secrets(
&self.path,
self.entropy_threshold,
self.include_test,
self.min_severity.map(|s| s.into()),
)?;
if writer.is_text() {
let text = format_secrets_text(&report);
writer.write_text(&text)?;
} else {
writer.write(&report)?;
}
Ok(())
}
}