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