forge-guard 0.1.0

Pre-deployment smart contract auditing framework for Foundry
Documentation
//! `forge scan` — scan dependencies for vulnerabilities.

use crate::dependencies::DependencyScanner;

use super::ScanArgs;
use anyhow::Result;
use colored::*;

/// Scan dependencies for known vulnerabilities.
pub fn run(args: &ScanArgs) -> Result<()> {
    eprintln!("{}", "🔎 Forge Guard — Dependency Scanner".bold());
    eprintln!("   Depth:       {}", args.depth);
    eprintln!(
        "   Fail fast:   {}",
        if args.fail_fast { "yes" } else { "no" }
    );

    let mut scanner = DependencyScanner::new(args.depth);

    // Update vulnerability database if requested
    if args.update {
        eprintln!("\n📥 Updating vulnerability database...");
        scanner.update_database()?;
    }

    // Scan dependencies
    eprintln!("\n🔍 Scanning dependencies...");
    let vulnerabilities = scanner.scan()?;

    // Report results
    if vulnerabilities.is_empty() {
        println!("\n{} No vulnerabilities found!", "".green().bold());
    } else {
        println!(
            "\n{} {} vulnerabilities found:",
            "⚠️".yellow().bold(),
            vulnerabilities.len()
        );

        for vuln in &vulnerabilities {
            let severity_color = match vuln.severity.to_lowercase().as_str() {
                "critical" | "high" => "red",
                "medium" => "yellow",
                _ => "blue",
            };

            println!(
                "\n  [{}] {}",
                vuln.severity.color(severity_color).bold(),
                vuln.name.bold()
            );
            println!("       Package:  {}", vuln.package);
            println!("       Version:  {}", vuln.version);
            println!("       Detail:   {}", vuln.description);
            println!("       Fix:      {}", vuln.recommended_fix);

            if args.fail_fast && vuln.severity.to_lowercase() == "critical" {
                anyhow::bail!("Critical vulnerability found: {}", vuln.name);
            }
        }
    }

    // Output JSON if requested
    if args.shared.json {
        println!("{}", serde_json::to_string_pretty(&vulnerabilities)?);
    }

    Ok(())
}