Initial upload: git-insights-cli with CI/CD workflow
Some checks failed
CI / test (push) Has been cancelled
CI / build (push) Has been cancelled
CI / release (push) Has been cancelled

This commit is contained in:
2026-01-30 20:35:23 +00:00
parent d20c16aa5a
commit 466d6794d0

67
src/analyzers/velocity.py Normal file
View File

@@ -0,0 +1,67 @@
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,
)