morph-cli 0.1.0

AST-based codebase migration and codemod tool for JavaScript and TypeScript projects.
Documentation
use std::path::Path;
use std::time::Instant;
use anyhow::Result;
use crate::core::detection::scanner::Scanner;
use crate::core::pipeline::executor::PipelineExecutor;
use crate::core::registry::RecipeRegistry;
use crate::utils::terminal;

pub fn execute(path: &Path, project_root: &Path) -> Result<()> {
    println!("{}", terminal::label("Morph Benchmark ⚡"));
    println!("Measuring performance on: {}\n", path.display());

    // 1. Benchmark Scan
    let scan_start = Instant::now();
    let mut scanner = Scanner::new(path.to_path_buf());
    let scan_result = scanner.scan();
    let scan_duration = scan_start.elapsed();
    
    println!("{} Scan completed in {:?}", terminal::success_prefix(), scan_duration);
    println!("  Files discovered: {}", scan_result.total_files);
    
    // 2. Benchmark Transform (Dry-run of detected recipes)
    if scan_result.detection.migration_opportunities.is_empty() {
        println!("\n{} No migration opportunities detected. Skipping transform benchmark.", terminal::info_prefix());
    } else {
        println!("\n{} Benchmarking detected migration pipelines...", terminal::info_prefix());
        
        let registry = RecipeRegistry::new();
        let opp = &scan_result.detection.migration_opportunities[0];
        println!("  Using opportunity: {} ({} recipes)", opp.name, opp.recipes.len());
        
        let mut executor = PipelineExecutor::new(project_root.to_path_buf());
        for recipe_name in &opp.recipes {
            executor = executor.add_recipe(recipe_name);
        }
        
        let transform_start = Instant::now();
        let summary = executor.execute(
            path,
            crate::core::recipe::TransformMode::DryRun,
            false, // review
            false, // autofix
            &registry,
            false, // verbose
        )?;
        let transform_duration = transform_start.elapsed();
        
        println!("\n{} Transform benchmark summary:", terminal::label("Results"));
        println!("  Pipeline duration: {:?}", transform_duration);
        println!("  Total modified:    {}", summary.total_changed_files);
        println!("  Total skipped:     {}", summary.total_skipped_files);
        
        println!("\nPer-stage breakdown:");
        for (stage, duration_ms) in summary.timings {
            println!("  - {}: {}ms", stage, duration_ms);
        }
    }

    println!("\n{} Benchmark completed!", terminal::success_prefix());
    Ok(())
}