Add models, analyzers, and formatters
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-02-01 07:57:57 +00:00
parent 21e16bff72
commit 89da5c37d2

View File

@@ -1,6 +1,6 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import datetime from datetime import datetime
from typing import List, Optional from typing import Any, Dict, List, Optional
from dataclasses_json import dataclass_json from dataclasses_json import dataclass_json
@@ -8,7 +8,7 @@ from dataclasses_json import dataclass_json
@dataclass_json @dataclass_json
@dataclass @dataclass
class Author: class Author:
"""Represents a git author.""" """Author information."""
name: str name: str
email: str email: str
commit_count: int = 0 commit_count: int = 0
@@ -19,77 +19,134 @@ class Author:
@dataclass_json @dataclass_json
@dataclass @dataclass
class Commit: class Commit:
"""Represents a git commit.""" """Git commit information."""
sha: str sha: str
message: str message: str
author: str author_name: str
author_email: str author_email: str
timestamp: datetime committed_datetime: datetime
lines_added: int = 0 author_datetime: datetime
lines_deleted: int = 0 additions: int = 0
deletions: int = 0
files_changed: List[str] = field(default_factory=list) files_changed: List[str] = field(default_factory=list)
parents: List[str] = field(default_factory=list)
is_merge: bool = False is_merge: bool = False
is_revert: bool = False is_revert: bool = False
@property
def lines_changed_count(self) -> int:
"""Get total lines changed."""
return self.additions + self.deletions
@dataclass_json @dataclass_json
@dataclass @dataclass
class FileChange: class FileChange:
"""Represents changes to a file in a commit.""" """File change information."""
filepath: str filepath: str
lines_added: int lines_added: int = 0
lines_deleted: int lines_deleted: int = 0
change_type: str change_type: str = "M"
@dataclass_json @dataclass_json
@dataclass @dataclass
class CommitAnalysis: class CommitAnalysis:
"""Analysis of commit patterns.""" """Commit pattern analysis results."""
total_commits: int total_commits: int = 0
unique_authors: int unique_authors: int = 0
commits_by_hour: dict commits_by_hour: Dict[str, int] = field(default_factory=dict)
commits_by_day: dict commits_by_day: Dict[str, int] = field(default_factory=dict)
commits_by_week: dict commits_by_week: Dict[str, int] = field(default_factory=dict)
top_authors: List[Author] commits_by_month: Dict[str, int] = field(default_factory=dict)
average_commits_per_day: float top_authors: List[Author] = field(default_factory=list)
average_commits_per_day: float = 0.0
def to_dict(self) -> Dict[str, Any]:
"""Convert to dictionary."""
return {
"total_commits": self.total_commits,
"unique_authors": self.unique_authors,
"commits_by_hour": self.commits_by_hour,
"commits_by_day": self.commits_by_day,
"commits_by_week": self.commits_by_week,
"commits_by_month": self.commits_by_month,
"top_authors": [a.to_dict() for a in self.top_authors],
"average_commits_per_day": self.average_commits_per_day,
}
@dataclass_json @dataclass_json
@dataclass @dataclass
class CodeChurnAnalysis: class CodeChurnAnalysis:
"""Analysis of code churn.""" """Code churn analysis results."""
total_lines_added: int total_lines_added: int = 0
total_lines_deleted: int total_lines_deleted: int = 0
net_change: int net_change: int = 0
churn_by_file: dict churn_by_file: Dict[str, int] = field(default_factory=dict)
churn_by_author: dict churn_by_author: Dict[str, int] = field(default_factory=dict)
high_churn_commits: List[Commit] high_churn_files: List[FileChange] = field(default_factory=list)
average_churn_per_commit: float high_churn_commits: List[Commit] = field(default_factory=list)
average_churn_per_commit: float = 0.0
def to_dict(self) -> Dict[str, Any]:
"""Convert to dictionary."""
return {
"total_lines_added": self.total_lines_added,
"total_lines_deleted": self.total_lines_deleted,
"net_change": self.net_change,
"churn_by_file": self.churn_by_file,
"churn_by_author": self.churn_by_author,
"high_churn_files": [f.to_dict() for f in self.high_churn_files],
"high_churn_commits": [c.to_dict() for c in self.high_churn_commits],
"average_churn_per_commit": self.average_churn_per_commit,
}
@dataclass_json @dataclass_json
@dataclass @dataclass
class RiskyCommitAnalysis: class RiskyCommitAnalysis:
"""Analysis of risky commits.""" """Risky commit detection results."""
total_risky_commits: int large_commits: List[Commit] = field(default_factory=list)
large_change_commits: List[Commit] merge_commits: List[Commit] = field(default_factory=list)
merge_commits: List[Commit] revert_commits: List[Commit] = field(default_factory=list)
revert_commits: List[Commit] total_risky: int = 0
risk_score: float
def to_dict(self) -> Dict[str, Any]:
"""Convert to dictionary."""
return {
"large_commits": [c.to_dict() for c in self.large_commits],
"merge_commits": [c.to_dict() for c in self.merge_commits],
"revert_commits": [c.to_dict() for c in self.revert_commits],
"total_risky": self.total_risky,
}
@dataclass_json @dataclass_json
@dataclass @dataclass
class VelocityAnalysis: class VelocityAnalysis:
"""Analysis of team velocity.""" """Velocity analysis results."""
commits_per_day: float total_commits: int = 0
commits_per_week: float commits_per_day: float = 0.0
commits_per_month: float commits_per_week: float = 0.0
velocity_trend: str velocity_trend: str = "stable"
top_contributors: List[Author] most_active_day: str = ""
most_active_day: str most_active_hour: str = ""
most_active_hour: str weekly_totals: Dict[str, int] = field(default_factory=dict)
daily_totals: Dict[str, int] = field(default_factory=dict)
def to_dict(self) -> Dict[str, Any]:
"""Convert to dictionary."""
return {
"total_commits": self.total_commits,
"commits_per_day": self.commits_per_day,
"commits_per_week": self.commits_per_week,
"velocity_trend": self.velocity_trend,
"most_active_day": self.most_active_day,
"most_active_hour": self.most_active_hour,
"weekly_totals": self.weekly_totals,
"daily_totals": self.daily_totals,
}
@dataclass_json @dataclass_json
@@ -98,7 +155,8 @@ class ProductivityReport:
"""Comprehensive productivity report.""" """Comprehensive productivity report."""
repository_path: str repository_path: str
analysis_days: int analysis_days: int
commit_analysis: Optional[CommitAnalysis] commit_analysis: Optional[CommitAnalysis] = None
code_churn_analysis: Optional[CodeChurnAnalysis] code_churn_analysis: Optional[CodeChurnAnalysis] = None
risky_commit_analysis: Optional[RiskyCommitAnalysis] risky_commit_analysis: Optional[RiskyCommitAnalysis] = None
velocity_analysis: Optional[VelocityAnalysis] velocity_analysis: Optional[VelocityAnalysis] = None
generated_at: datetime = field(default_factory=datetime.now)