Initial upload: GitPulse - Developer Productivity Analyzer CLI tool
Some checks failed
CI / test (push) Has been cancelled
CI / release (push) Has been cancelled

This commit is contained in:
2026-02-04 15:45:34 +00:00
parent 615365d7e2
commit 36fb1b9a2d

198
src/models/mod.rs Normal file
View File

@@ -0,0 +1,198 @@
pub mod commit;
pub mod author;
pub mod file;
pub mod time_series;
pub use commit::CommitData;
pub use author::AuthorStats;
pub use file::FileStats;
pub use time_series::{TimeSeriesData, TimeBucket};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RepositoryInfo {
pub path: String,
pub branch: Option<String>,
pub remote_url: Option<String>,
pub total_commits: usize,
pub total_authors: usize,
pub repository_age_days: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommitFrequency {
pub total_commits: usize,
pub commits_per_day: f64,
pub commits_per_week: f64,
pub commits_per_month: f64,
pub busiest_day: String,
pub busiest_day_count: usize,
pub quietest_day: String,
pub quietest_day_count: usize,
pub day_distribution: HashMap<String, usize>,
pub hour_distribution: HashMap<u32, usize>,
}
impl Default for CommitFrequency {
fn default() -> Self {
Self {
total_commits: 0,
commits_per_day: 0.0,
commits_per_week: 0.0,
commits_per_month: 0.0,
busiest_day: String::new(),
busiest_day_count: 0,
quietest_day: String::new(),
quietest_day_count: 0,
day_distribution: HashMap::new(),
hour_distribution: HashMap::new(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CodeChurn {
pub total_lines_added: usize,
pub total_lines_removed: usize,
pub net_change: i64,
pub average_commit_size: f64,
pub largest_commit: Option<CommitChange>,
pub top_churn_files: Vec<FileChange>,
pub additions_by_day: HashMap<String, usize>,
pub removals_by_day: HashMap<String, usize>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommitChange {
pub oid: String,
pub message: String,
pub author: String,
pub timestamp: String,
pub lines_added: usize,
pub lines_removed: usize,
pub net_change: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileChange {
pub path: String,
pub lines_added: usize,
pub lines_removed: usize,
pub net_change: i64,
pub commit_count: usize,
}
impl Default for CodeChurn {
fn default() -> Self {
Self {
total_lines_added: 0,
total_lines_removed: 0,
net_change: 0,
average_commit_size: 0.0,
largest_commit: None,
top_churn_files: Vec::new(),
additions_by_day: HashMap::new(),
removals_by_day: HashMap::new(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContributorStats {
pub total_contributors: usize,
pub top_contributors: Vec<AuthorStats>,
pub contributions_by_author: HashMap<String, usize>,
}
impl Default for ContributorStats {
fn default() -> Self {
Self {
total_contributors: 0,
top_contributors: Vec::new(),
contributions_by_author: HashMap::new(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefactoringActivity {
pub total_renames: usize,
pub total_copies: usize,
pub refactoring_score: f64,
pub renamed_files: Vec<RenameInfo>,
pub refactoring_hotspots: Vec<RefactoringHotspot>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RenameInfo {
pub old_path: String,
pub new_path: String,
pub commit_oid: String,
pub commit_message: String,
pub similarity: f64,
pub timestamp: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefactoringHotspot {
pub file_path: String,
pub rename_count: usize,
pub last_rename: String,
}
impl Default for RefactoringActivity {
fn default() -> Self {
Self {
total_renames: 0,
total_copies: 0,
refactoring_score: 0.0,
renamed_files: Vec::new(),
refactoring_hotspots: Vec::new(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnalysisResult {
pub repository: RepositoryInfo,
pub time_range: TimeRange,
pub commit_frequency: CommitFrequency,
pub code_churn: CodeChurn,
pub contributors: ContributorStats,
pub refactoring: RefactoringActivity,
pub time_series: Vec<TimeSeriesData>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TimeRange {
pub start: String,
pub end: String,
pub days: u32,
}
impl Default for AnalysisResult {
fn default() -> Self {
Self {
repository: RepositoryInfo {
path: String::new(),
branch: None,
remote_url: None,
total_commits: 0,
total_authors: 0,
repository_age_days: 0,
},
time_range: TimeRange {
start: String::new(),
end: String::new(),
days: 0,
},
commit_frequency: CommitFrequency::default(),
code_churn: CodeChurn::default(),
contributors: ContributorStats::default(),
refactoring: RefactoringActivity::default(),
time_series: Vec::new(),
}
}
}