ruchy 4.2.0

A systems scripting language that transpiles to idiomatic Rust with extreme quality engineering
Documentation
//! Ruchy coverage reporting tool
//!
//! This binary runs test coverage analysis and generates reports

use clap::{Arg, Command};
use ruchy::quality::{CoverageCollector, CoverageTool, HtmlReportGenerator, QualityGates};
use std::process;
use tracing::{error, info};

#[tokio::main]
async fn main() {
    let matches = Command::new("ruchy-coverage")
        .version("0.3.2")
        .author("Ruchy Contributors")
        .about("Ruchy test coverage reporting tool")
        .arg(
            Arg::new("tool")
                .long("tool")
                .help("Coverage tool to use")
                .value_name("TOOL")
                .value_parser(["tarpaulin", "grcov", "llvm"])
                .default_value("tarpaulin"),
        )
        .arg(
            Arg::new("output")
                .long("output")
                .short('o')
                .help("Output directory for reports")
                .value_name("DIR")
                .default_value("target/coverage"),
        )
        .arg(
            Arg::new("quality-gates")
                .long("quality-gates")
                .help("Run quality gates check")
                .action(clap::ArgAction::SetTrue),
        )
        .get_matches();

    let tool_name = matches
        .get_one::<String>("tool")
        .map_or("tarpaulin", String::as_str);
    let output_dir = matches
        .get_one::<String>("output")
        .map_or("target/coverage", String::as_str);
    let run_quality_gates = matches.get_flag("quality-gates");

    let coverage_tool = match tool_name {
        "tarpaulin" => CoverageTool::Tarpaulin,
        "grcov" => CoverageTool::Grcov,
        "llvm" => CoverageTool::Llvm,
        _ => {
            error!("Unknown coverage tool: {}", tool_name);
            process::exit(1);
        }
    };

    info!("Running coverage analysis with {}", tool_name);

    // Collect coverage
    let collector = CoverageCollector::new(coverage_tool);

    if !collector.is_available() {
        error!("Coverage tool '{}' is not available", tool_name);
        error!("Please install the tool first:");
        match tool_name {
            "tarpaulin" => error!("  cargo install cargo-tarpaulin"),
            "grcov" => error!("  cargo install grcov"),
            "llvm" => error!("  Install LLVM tools for your platform"),
            _ => {}
        }
        process::exit(1);
    }

    let coverage_report = match collector.collect() {
        Ok(report) => report,
        Err(err) => {
            error!("Failed to collect coverage: {}", err);
            process::exit(1);
        }
    };

    // Generate HTML report
    let html_generator = HtmlReportGenerator::new(output_dir);
    if let Err(err) = html_generator.generate(&coverage_report) {
        error!("Failed to generate HTML report: {}", err);
        process::exit(1);
    }

    // Print summary
    info!("Coverage Analysis Complete!");
    info!("==========================");
    info!(
        "  Lines: {:.1}% ({}/{})",
        coverage_report.line_coverage_percentage(),
        coverage_report.covered_lines,
        coverage_report.total_lines
    );
    info!(
        "  Functions: {:.1}% ({}/{})",
        coverage_report.function_coverage_percentage(),
        coverage_report.covered_functions,
        coverage_report.total_functions
    );
    info!("  HTML Report: {output_dir}/coverage.html");

    // Run quality gates if requested
    if run_quality_gates {
        info!("\nRunning Quality Gates...");
        let mut quality_gates = QualityGates::new();

        match quality_gates.collect_metrics() {
            Ok(_) => match quality_gates.check() {
                Ok(_) => info!("✅ All quality gates passed!"),
                Err(report) => {
                    error!("❌ Quality gate failures: {report:?}");
                    process::exit(1);
                }
            },
            Err(err) => {
                error!("Failed to collect quality metrics: {}", err);
                process::exit(1);
            }
        }
    }
}