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