|
1 | 1 | use clap::Parser; |
| 2 | +use git_reports::analysis::{analyze_repo, clone_or_update}; |
| 3 | +use git_reports::config::load_config; |
| 4 | +use serde_json; |
2 | 5 |
|
3 | 6 | #[derive(Parser, Debug)] |
4 | 7 | #[command(name = "git-reports")] |
5 | 8 | #[command(about = "Automated Git analytics engine for work summaries", long_about = None)] |
6 | 9 | struct Args { |
7 | | - /// Path to the Git repository |
8 | | - #[arg(short, long, default_value = ".")] |
9 | | - repo: String, |
| 10 | + /// Ruta al archivo de configuración (config.toml) |
| 11 | + #[arg(short, long, default_value = "config.toml")] |
| 12 | + config: String, |
10 | 13 |
|
11 | | - /// Output file path (JSON) |
| 14 | + /// Archivo de salida JSON (por defecto imprime a stdout) |
12 | 15 | #[arg(short, long)] |
13 | 16 | output: Option<String>, |
14 | 17 |
|
15 | | - /// Time period: week, month, all |
| 18 | + /// Periodo de análisis: week, month, all |
16 | 19 | #[arg(short, long, default_value = "week")] |
17 | 20 | period: String, |
18 | 21 | } |
19 | 22 |
|
20 | 23 | fn main() { |
21 | 24 | let args = Args::parse(); |
22 | | - println!("Git Reports - Analyzing repository: {}", args.repo); |
23 | | - println!("Period: {}", args.period); |
24 | | - |
25 | | - // TODO: Implement Git analysis |
26 | | - println!("Analysis complete!"); |
| 25 | + |
| 26 | + // Cargar configuración |
| 27 | + let config = match load_config(&args.config) { |
| 28 | + Ok(c) => c, |
| 29 | + Err(e) => { |
| 30 | + eprintln!("Error: {}", e); |
| 31 | + std::process::exit(1); |
| 32 | + } |
| 33 | + }; |
| 34 | + |
| 35 | + eprintln!( |
| 36 | + "Git Reports — {} perfil(es) encontrado(s), periodo: {}", |
| 37 | + config.profile.len(), |
| 38 | + args.period |
| 39 | + ); |
| 40 | + |
| 41 | + let mut all_reports: Vec<serde_json::Value> = Vec::new(); |
| 42 | + |
| 43 | + for profile in &config.profile { |
| 44 | + eprintln!("\n[perfil: {}] email: {}", profile.name, profile.email); |
| 45 | + |
| 46 | + let mut profile_reports: Vec<serde_json::Value> = Vec::new(); |
| 47 | + |
| 48 | + for entry in &profile.repo { |
| 49 | + let label = format!("{}/{}/{}", entry.provider, entry.owner, entry.name); |
| 50 | + eprintln!(" Procesando {}", label); |
| 51 | + |
| 52 | + // Clonar o actualizar el repo en caché |
| 53 | + let repo = match clone_or_update(entry, profile) { |
| 54 | + Ok(r) => r, |
| 55 | + Err(e) => { |
| 56 | + eprintln!(" ✗ Error: {}", e); |
| 57 | + continue; |
| 58 | + } |
| 59 | + }; |
| 60 | + |
| 61 | + // Analizar commits filtrados por email y periodo |
| 62 | + let report = match analyze_repo(&repo, &args.period, &profile.email, &label) { |
| 63 | + Ok(r) => r, |
| 64 | + Err(e) => { |
| 65 | + eprintln!(" ✗ Error al analizar: {}", e); |
| 66 | + continue; |
| 67 | + } |
| 68 | + }; |
| 69 | + |
| 70 | + eprintln!( |
| 71 | + " ✓ {} commit(s) encontrado(s) para {}", |
| 72 | + report.total_commits, profile.email |
| 73 | + ); |
| 74 | + |
| 75 | + profile_reports.push(serde_json::to_value(&report).unwrap()); |
| 76 | + } |
| 77 | + |
| 78 | + all_reports.push(serde_json::json!({ |
| 79 | + "profile": profile.name, |
| 80 | + "email": profile.email, |
| 81 | + "repos": profile_reports, |
| 82 | + })); |
| 83 | + } |
| 84 | + |
| 85 | + // Serializar resultado final |
| 86 | + let json = serde_json::to_string_pretty(&all_reports).unwrap_or_else(|e| { |
| 87 | + eprintln!("Error al serializar JSON: {}", e); |
| 88 | + std::process::exit(1); |
| 89 | + }); |
| 90 | + |
| 91 | + match &args.output { |
| 92 | + Some(path) => { |
| 93 | + std::fs::write(path, &json).unwrap_or_else(|e| { |
| 94 | + eprintln!("Error al escribir '{}': {}", path, e); |
| 95 | + std::process::exit(1); |
| 96 | + }); |
| 97 | + eprintln!("\nReporte guardado en: {}", path); |
| 98 | + } |
| 99 | + None => println!("{}", json), |
| 100 | + } |
27 | 101 | } |
| 102 | + |
0 commit comments