include!("comprehensive_serve.rs");
include!("comprehensive_types.rs");
include!("comprehensive_runners.rs");
include!("comprehensive_formatting.rs");
#[allow(clippy::too_many_arguments)]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub async fn handle_analyze_comprehensive(
project_path: PathBuf,
format: ComprehensiveOutputFormat,
include_duplicates: bool,
include_dead_code: bool,
include_defects: bool,
include_complexity: bool,
include_tdg: bool,
_confidence_threshold: f32,
_min_lines: usize,
include: Option<String>,
exclude: Option<String>,
output: Option<PathBuf>,
_perf: bool,
executive_summary: bool,
_top_files: usize,
) -> Result<()> {
use std::time::Instant;
eprintln!("🔍 Running comprehensive analysis...");
let start = Instant::now();
let mut report = ComprehensiveReport::default();
let config = ComprehensiveAnalysisConfig::new(
include_complexity,
include_tdg,
include_dead_code,
include_defects,
include_duplicates,
&include,
&exclude,
_confidence_threshold,
_min_lines,
);
run_comprehensive_analyses(&mut report, &project_path, &config).await?;
let elapsed = start.elapsed();
eprintln!("✅ Comprehensive analysis completed in {elapsed:?}");
write_comprehensive_output(&report, format, executive_summary, output).await?;
Ok(())
}
#[derive(Debug, Clone)]
struct ComprehensiveAnalysisConfig {
include_complexity: bool,
include_tdg: bool,
include_dead_code: bool,
include_defects: bool,
include_duplicates: bool,
include_patterns: Option<String>,
exclude_patterns: Option<String>,
confidence_threshold: f32,
min_lines: usize,
}
impl ComprehensiveAnalysisConfig {
#[allow(clippy::too_many_arguments)]
fn new(
include_complexity: bool,
include_tdg: bool,
include_dead_code: bool,
include_defects: bool,
include_duplicates: bool,
include: &Option<String>,
exclude: &Option<String>,
confidence_threshold: f32,
min_lines: usize,
) -> Self {
Self {
include_complexity,
include_tdg,
include_dead_code,
include_defects,
include_duplicates,
include_patterns: include.clone(),
exclude_patterns: exclude.clone(),
confidence_threshold,
min_lines,
}
}
}
async fn run_comprehensive_analyses(
report: &mut ComprehensiveReport,
project_path: &Path,
config: &ComprehensiveAnalysisConfig,
) -> Result<()> {
run_comprehensive_analyses_with_config(report, project_path, config).await
}
async fn run_comprehensive_analyses_with_config(
report: &mut ComprehensiveReport,
project_path: &Path,
config: &ComprehensiveAnalysisConfig,
) -> Result<()> {
eprintln!("🔍 Analyzing technical debt...");
report.satd = Some(
run_satd_analysis(
project_path,
&config.include_patterns,
&config.exclude_patterns,
)
.await?,
);
run_optional_analyses(report, project_path, config).await?;
Ok(())
}
async fn run_optional_analyses(
report: &mut ComprehensiveReport,
project_path: &Path,
config: &ComprehensiveAnalysisConfig,
) -> Result<()> {
run_complexity_if_requested(report, project_path, config).await?;
run_tdg_if_requested(report, project_path, config).await?;
run_dead_code_if_requested(report, project_path, config).await?;
run_defects_if_requested(report, project_path, config).await?;
run_duplicates_if_requested(report, project_path, config).await?;
Ok(())
}
async fn run_complexity_if_requested(
report: &mut ComprehensiveReport,
project_path: &Path,
config: &ComprehensiveAnalysisConfig,
) -> Result<()> {
if config.include_complexity {
eprintln!("📊 Analyzing complexity...");
report.complexity = Some(
run_complexity_analysis(
project_path,
&config.include_patterns,
&config.exclude_patterns,
)
.await?,
);
}
Ok(())
}
async fn run_tdg_if_requested(
report: &mut ComprehensiveReport,
project_path: &Path,
config: &ComprehensiveAnalysisConfig,
) -> Result<()> {
if config.include_tdg {
eprintln!("📈 Analyzing technical debt gradient...");
report.tdg = Some(create_tdg_report(project_path).await?);
}
Ok(())
}
async fn run_dead_code_if_requested(
report: &mut ComprehensiveReport,
project_path: &Path,
config: &ComprehensiveAnalysisConfig,
) -> Result<()> {
if config.include_dead_code {
eprintln!("💀 Analyzing dead code...");
report.dead_code = Some(
run_dead_code_analysis(
project_path,
&config.include_patterns,
&config.exclude_patterns,
)
.await?,
);
}
Ok(())
}
async fn run_defects_if_requested(
report: &mut ComprehensiveReport,
project_path: &Path,
config: &ComprehensiveAnalysisConfig,
) -> Result<()> {
if config.include_defects {
eprintln!("🐛 Predicting defects...");
report.defects = Some(
run_defect_prediction(project_path, config.confidence_threshold, config.min_lines)
.await?,
);
}
Ok(())
}
async fn run_duplicates_if_requested(
report: &mut ComprehensiveReport,
project_path: &Path,
config: &ComprehensiveAnalysisConfig,
) -> Result<()> {
if config.include_duplicates {
eprintln!("👥 Detecting duplicates...");
report.duplicates = Some(
run_duplicate_detection(
project_path,
&config.include_patterns,
&config.exclude_patterns,
)
.await?,
);
}
Ok(())
}
async fn write_comprehensive_output(
report: &ComprehensiveReport,
format: ComprehensiveOutputFormat,
executive_summary: bool,
output: Option<PathBuf>,
) -> Result<()> {
let content = format_comprehensive_report(report, format, executive_summary)?;
if let Some(output_path) = output {
tokio::fs::write(&output_path, &content).await?;
eprintln!("📄 Report written to: {}", output_path.display());
} else {
println!("{content}");
}
Ok(())
}