the_code_graph_cli/commands/
stats.rs1use domain::error::Result;
2use domain::model::{CloneConfig, FlowConfig, RiskConfig};
3use domain::use_cases::clones::CloneUseCase;
4use domain::use_cases::flow::FlowUseCase;
5use domain::use_cases::query::QueryUseCase;
6use domain::use_cases::risk::RiskUseCase;
7
8use crate::adapters::fs::RealFileSystem;
9use crate::commands::helpers::open_graph;
10use crate::output::{print, OutputFormat};
11
12pub fn run_stats(output_format: OutputFormat) -> Result<()> {
13 let (store, root) = open_graph()?;
14 let uc = QueryUseCase::new(store.clone(), store.clone());
15 let mut stats = uc.stats()?;
16
17 let risk_store = store.clone();
19 let clone_store = store.clone();
20 let flow_uc = FlowUseCase::new(store);
21 let flow_config = FlowConfig::default();
22 let analysis = flow_uc.analyze(&flow_config)?;
23 stats.entry_point_count = Some(analysis.stats.total_entry_points);
24
25 if stats.symbols <= 5000 {
27 let avg = if analysis.criticality.is_empty() {
28 0.0
29 } else {
30 analysis
31 .criticality
32 .iter()
33 .map(|c| c.betweenness)
34 .sum::<f64>()
35 / analysis.criticality.len() as f64
36 };
37 stats.avg_criticality = Some(avg);
38 }
39
40 if stats.symbols <= 10_000 {
42 let clone_fs = RealFileSystem;
43 let clone_uc = CloneUseCase::new(clone_store, clone_fs, root);
44 let clone_config = CloneConfig::default();
45 if let Ok(clone_analysis) = clone_uc.analyze(&clone_config) {
46 stats.clone_clusters = Some(clone_analysis.clusters.len());
47 stats.duplication_pct = Some(clone_analysis.duplication_pct);
48 stats.most_duplicated = clone_analysis.most_duplicated;
49 }
50 }
51
52 if stats.symbols <= 5000 {
54 let risk_uc = RiskUseCase::new(risk_store);
55 let risk_config = RiskConfig::default();
56 if let Ok(risk_analysis) = risk_uc.analyze(&risk_config) {
57 stats.avg_risk = Some(risk_analysis.stats.avg_risk);
58 stats.p90_risk = Some(risk_analysis.stats.p90_risk);
59 }
60 }
61
62 print(&stats, output_format);
63 Ok(())
64}