68 lines
2.3 KiB
Python
68 lines
2.3 KiB
Python
from dataclasses import dataclass
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
from src.analyzers.git_repository import GitRepository
|
|
from src.models.data_structures import VelocityAnalysis, Author
|
|
|
|
|
|
@dataclass
|
|
class VelocityAnalyzer:
|
|
"""Analyzes team velocity."""
|
|
|
|
repo: GitRepository
|
|
days: int
|
|
|
|
def analyze(self) -> Optional[VelocityAnalysis]:
|
|
"""Analyze team velocity."""
|
|
commits = self.repo.get_commits()
|
|
|
|
if not commits:
|
|
return None
|
|
|
|
authors = self.repo.get_authors()
|
|
authors.sort(key=lambda a: a.commit_count, reverse=True)
|
|
top_contributors = authors[:10]
|
|
|
|
commits_per_day = len(commits) / max(1, self.days)
|
|
commits_per_week = commits_per_day * 7
|
|
commits_per_month = commits_per_day * 30
|
|
|
|
commits_by_day: Dict[str, int] = {}
|
|
commits_by_hour: Dict[str, int] = {}
|
|
|
|
for commit in commits:
|
|
day_key = commit.timestamp.strftime("%A")
|
|
hour_key = commit.timestamp.strftime("%H:00")
|
|
|
|
commits_by_day[day_key] = commits_by_day.get(day_key, 0) + 1
|
|
commits_by_hour[hour_key] = commits_by_hour.get(hour_key, 0) + 1
|
|
|
|
most_active_day = max(commits_by_day, key=commits_by_day.get) if commits_by_day else "N/A"
|
|
most_active_hour = max(commits_by_hour, key=commits_by_hour.get) if commits_by_hour else "N/A"
|
|
|
|
if len(commits) >= 2:
|
|
recent_commits = commits[:10]
|
|
older_commits = commits[10:20]
|
|
|
|
recent_avg = sum(1 for _ in recent_commits) / max(1, len(recent_commits))
|
|
older_avg = sum(1 for _ in older_commits) / max(1, len(older_commits))
|
|
|
|
if recent_avg > older_avg * 1.1:
|
|
velocity_trend = "increasing"
|
|
elif recent_avg < older_avg * 0.9:
|
|
velocity_trend = "decreasing"
|
|
else:
|
|
velocity_trend = "stable"
|
|
else:
|
|
velocity_trend = "stable"
|
|
|
|
return VelocityAnalysis(
|
|
commits_per_day=commits_per_day,
|
|
commits_per_week=commits_per_week,
|
|
commits_per_month=commits_per_month,
|
|
velocity_trend=velocity_trend,
|
|
top_contributors=top_contributors,
|
|
most_active_day=most_active_day,
|
|
most_active_hour=most_active_hour,
|
|
)
|