From 4c39d7839cb3763a7e0aeb0a623b7e353bbe7071 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Wed, 4 Feb 2026 15:45:43 +0000 Subject: [PATCH] Initial upload: GitPulse - Developer Productivity Analyzer CLI tool --- src/export/csv.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/export/csv.rs diff --git a/src/export/csv.rs b/src/export/csv.rs new file mode 100644 index 0000000..92bbfad --- /dev/null +++ b/src/export/csv.rs @@ -0,0 +1,59 @@ +use crate::models::AnalysisResult; +use anyhow::{Context, Result}; +use csv::{Writer, WriterBuilder}; +use std::fs::File; +use std::path::PathBuf; + +pub fn export_csv(result: &AnalysisResult, path: &PathBuf) -> Result<()> { + let mut wtr = WriterBuilder::new() + .delimiter(b',') + .has_headers(true) + .from_path(path) + .context("Failed to create CSV writer")?; + + wtr.write_record(&[ + "Name", "Email", "Commits", "Lines Added", "Lines Removed", "Net Change", + ])?; + + for author in &result.contributors.top_contributors { + wtr.write_record(&[ + &author.name, + &author.email, + &author.commits.to_string(), + &author.lines_added.to_string(), + &author.lines_removed.to_string(), + &author.net_change.to_string(), + ])?; + } + + wtr.flush()?; + Ok(()) +} + +pub fn export_contributors_detailed(result: &AnalysisResult, path: &PathBuf) -> Result<()> { + let mut wtr = Writer::from_path(path)?; + + wtr.write_record(&[ + "Name", "Email", "Commits", "Lines Added", "Lines Removed", + "Net Change", "Files Changed", "First Commit", "Last Commit", + "Avg Commits/Day" + ])?; + + for author in &result.contributors.top_contributors { + wtr.write_record(&[ + &author.name, + &author.email, + &author.commits.to_string(), + &author.lines_added.to_string(), + &author.lines_removed.to_string(), + &author.net_change.to_string(), + &author.files_changed.to_string(), + &author.first_commit, + &author.last_commit, + &format!("{:.2}", author.average_commits_per_day), + ])?; + } + + wtr.flush()?; + Ok(()) +}