diff --git a/src/analyzers/commit_pattern.py b/src/analyzers/commit_pattern.py index 7d1d891..22e625a 100644 --- a/src/analyzers/commit_pattern.py +++ b/src/analyzers/commit_pattern.py @@ -1,79 +1,63 @@ from collections import defaultdict -from datetime import datetime -from typing import Dict, List +from dataclasses import dataclass +from typing import Dict, List, Optional from src.analyzers.git_repository import GitRepository -from src.models import Author, CommitAnalysis +from src.models.data_structures import CommitAnalysis +@dataclass class CommitPatternAnalyzer: - """Analyze commit patterns and statistics.""" + """Analyzes commit patterns.""" - def __init__( - self, - repo: GitRepository, - days: int = 30, - ) -> None: - """Initialize CommitPatternAnalyzer.""" - self.repo = repo - self.days = days + repo: GitRepository + days: int - def analyze(self) -> CommitAnalysis: + def analyze(self) -> Optional[CommitAnalysis]: """Analyze commit patterns.""" - commits = self.repo.get_commits(since_days=self.days) + commits = self.repo.get_commits() if not commits: - return CommitAnalysis() + return None - authors = defaultdict(lambda: {"count": 0, "lines_added": 0, "lines_deleted": 0}) + commits_by_hour: Dict[str, int] = defaultdict(int) + commits_by_day: Dict[str, int] = defaultdict(int) + commits_by_week: Dict[str, int] = defaultdict(int) - commits_by_hour = defaultdict(int) - commits_by_day = defaultdict(int) - commits_by_week = defaultdict(int) - commits_by_month = defaultdict(int) + author_commits: Dict[str, List[str]] = defaultdict(list) for commit in commits: - hour = commit.author_datetime.strftime("%H:00") - day = commit.author_datetime.strftime("%A") - week = commit.author_datetime.strftime("%Y-W%W") - month = commit.author_datetime.strftime("%Y-%m") + hour_key = commit.timestamp.strftime("%H:00") + day_key = commit.timestamp.strftime("%A") + week_key = commit.timestamp.strftime("%Y-W%U") - commits_by_hour[hour] += 1 - commits_by_day[day] += 1 - commits_by_week[week] += 1 - commits_by_month[month] += 1 + commits_by_hour[hour_key] += 1 + commits_by_day[day_key] += 1 + commits_by_week[week_key] += 1 - author_key = f"{commit.author_name} <{commit.author_email}>" - authors[author_key]["count"] += 1 - authors[author_key]["lines_added"] += commit.additions - authors[author_key]["lines_deleted"] += commit.deletions + author_commits[commit.author_email].append(commit.sha) - top_authors = [ - Author( - name=name.split(" <")[0], - email=name.split("<")[1].rstrip(">") if "<" in name else "", - commit_count=data["count"], - lines_added=data["lines_added"], - lines_deleted=data["lines_deleted"], - ) - for name, data in sorted( - authors.items(), - key=lambda x: x[1]["count"], - reverse=True, - )[:10] - ] + authors = [] + for email, commit_shas in author_commits.items(): + author = self.repo.get_authors() + for a in author: + if a.email == email: + a.commit_count = len(commit_shas) + authors.append(a) + break - unique_authors = len(authors) - total_commits = len(commits) - average_commits_per_day = total_commits / max(self.days, 1) + authors.sort(key=lambda a: a.commit_count, reverse=True) + top_authors = authors[:10] + + total_days = max(1, self.days) + avg_commits_per_day = len(commits) / total_days return CommitAnalysis( - total_commits=total_commits, - unique_authors=unique_authors, + total_commits=len(commits), + unique_authors=len(authors), commits_by_hour=dict(commits_by_hour), commits_by_day=dict(commits_by_day), commits_by_week=dict(commits_by_week), - commits_by_month=dict(commits_by_month), top_authors=top_authors, - average_commits_per_day=average_commits_per_day, + average_commits_per_day=avg_commits_per_day, )