fix: add analyzer modules
Some checks failed
CI / test (push) Has been cancelled
CI / build (push) Has been cancelled

This commit is contained in:
2026-02-01 08:19:57 +00:00
parent 0ceab37f63
commit ba2c01a8db

View File

@@ -1,67 +1,50 @@
from collections import defaultdict from collections import defaultdict
from typing import Dict, List from dataclasses import dataclass
from typing import Dict, Optional
from src.analyzers.git_repository import GitRepository from src.analyzers.git_repository import GitRepository
from src.models import CodeChurnAnalysis, FileChange from src.models.data_structures import CodeChurnAnalysis
@dataclass
class CodeChurnAnalyzer: class CodeChurnAnalyzer:
"""Analyze code churn and changes.""" """Analyzes code churn."""
def __init__( repo: GitRepository
self, days: int
repo: GitRepository,
days: int = 30,
churn_threshold: int = 500,
) -> None:
"""Initialize CodeChurnAnalyzer."""
self.repo = repo
self.days = days
self.churn_threshold = churn_threshold
def analyze(self) -> CodeChurnAnalysis: def analyze(self) -> Optional[CodeChurnAnalysis]:
"""Analyze code churn.""" """Analyze code churn."""
commits = self.repo.get_commits(since_days=self.days) commits = self.repo.get_commits()
if not commits: if not commits:
return CodeChurnAnalysis() return None
total_lines_added = sum(c.additions for c in commits) total_lines_added = sum(c.lines_added for c in commits)
total_lines_deleted = sum(c.deletions for c in commits) total_lines_deleted = sum(c.lines_deleted for c in commits)
net_change = total_lines_added - total_lines_deleted net_change = total_lines_added - total_lines_deleted
churn_by_file = defaultdict(int) churn_by_file: Dict[str, Dict[str, int]] = defaultdict(lambda: {"added": 0, "deleted": 0})
churn_by_author = defaultdict(int) churn_by_author: Dict[str, Dict[str, int]] = defaultdict(lambda: {"added": 0, "deleted": 0})
high_churn_files = []
high_churn_commits = [] high_churn_commits = []
churn_threshold = 500
for commit in commits: for commit in commits:
churn_by_author[commit.author_name] += commit.lines_changed_count
for filepath in commit.files_changed: for filepath in commit.files_changed:
file_churn = commit.lines_changed_count churn_by_file[filepath]["added"] += commit.lines_added
churn_by_file[filepath] += file_churn churn_by_file[filepath]["deleted"] += commit.lines_deleted
if file_churn >= self.churn_threshold: churn_by_author[commit.author]["added"] += commit.lines_added
high_churn_files.append( churn_by_author[commit.author]["deleted"] += commit.lines_deleted
FileChange(
filepath=filepath,
lines_added=commit.additions,
lines_deleted=commit.deletions,
)
)
if commit.lines_changed_count >= self.churn_threshold: if commit.lines_added + commit.lines_deleted > churn_threshold:
high_churn_commits.append(commit) high_churn_commits.append(commit)
high_churn_files.sort( high_churn_commits.sort(key=lambda c: c.lines_added + c.lines_deleted, reverse=True)
key=lambda x: x.lines_added + x.lines_deleted,
reverse=True,
)
high_churn_files = high_churn_files[:20]
total_churn = sum(c.lines_changed_count for c in commits) total_changes = sum(c.lines_added + c.lines_deleted for c in commits)
average_churn_per_commit = total_churn / max(len(commits), 1) avg_churn_per_commit = total_changes / max(1, len(commits))
return CodeChurnAnalysis( return CodeChurnAnalysis(
total_lines_added=total_lines_added, total_lines_added=total_lines_added,
@@ -69,7 +52,6 @@ class CodeChurnAnalyzer:
net_change=net_change, net_change=net_change,
churn_by_file=dict(churn_by_file), churn_by_file=dict(churn_by_file),
churn_by_author=dict(churn_by_author), churn_by_author=dict(churn_by_author),
high_churn_files=high_churn_files[:10], high_churn_commits=high_churn_commits[:50],
high_churn_commits=high_churn_commits[:10], average_churn_per_commit=avg_churn_per_commit,
average_churn_per_commit=average_churn_per_commit,
) )