From 1c11de6f3b5c51a1cd2e87f16f53a9c3e4ffb820 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Fri, 30 Jan 2026 20:35:16 +0000 Subject: [PATCH] Initial upload: git-insights-cli with CI/CD workflow --- src/git_insights.py | 95 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/git_insights.py diff --git a/src/git_insights.py b/src/git_insights.py new file mode 100644 index 0000000..ede0990 --- /dev/null +++ b/src/git_insights.py @@ -0,0 +1,95 @@ +from dataclasses import dataclass +from datetime import datetime +from typing import Any, Dict, List, Optional + +from src.analyzers.commit_pattern import CommitPatternAnalyzer +from src.analyzers.code_churn import CodeChurnAnalyzer +from src.analyzers.risky_commit import RiskyCommitDetector +from src.analyzers.velocity import VelocityAnalyzer +from src.analyzers.git_repository import GitRepository +from src.models.data_structures import ( + CommitAnalysis, + CodeChurnAnalysis, + ProductivityReport, + RiskyCommitAnalysis, + VelocityAnalysis, +) + + +@dataclass +class AnalysisResult: + """Container for all analysis results.""" + commit_analysis: Optional[CommitAnalysis] = None + code_churn_analysis: Optional[CodeChurnAnalysis] = None + risky_commit_analysis: Optional[RiskyCommitAnalysis] = None + velocity_analysis: Optional[VelocityAnalysis] = None + timestamp: datetime = None + + def to_dict(self) -> Dict[str, Any]: + """Convert results to dictionary.""" + return { + "commit_analysis": self.commit_analysis.to_dict() if self.commit_analysis else None, + "code_churn_analysis": self.code_churn_analysis.to_dict() if self.code_churn_analysis else None, + "risky_commit_analysis": self.risky_commit_analysis.to_dict() if self.risky_commit_analysis else None, + "velocity_analysis": self.velocity_analysis.to_dict() if self.velocity_analysis else None, + "timestamp": self.timestamp.isoformat() if self.timestamp else None, + } + + +class GitInsights: + """Main orchestrator for git analysis.""" + + def __init__( + self, + repo_path: str, + days: int = 30, + config: Optional[Dict[str, Any]] = None, + ) -> None: + """Initialize GitInsights analyzer.""" + self.repo_path = repo_path + self.days = days + self.config = config or {} + self.repo = GitRepository(repo_path) + + def analyze(self) -> AnalysisResult: + """Run all analyzers and return combined results.""" + result = AnalysisResult(timestamp=datetime.now()) + + try: + commit_analyzer = CommitPatternAnalyzer(self.repo, self.days) + result.commit_analysis = commit_analyzer.analyze() + except Exception: + pass + + try: + churn_analyzer = CodeChurnAnalyzer(self.repo, self.days) + result.code_churn_analysis = churn_analyzer.analyze() + except Exception: + pass + + try: + risky_detector = RiskyCommitDetector(self.repo, self.days) + result.risky_commit_analysis = risky_detector.analyze() + except Exception: + pass + + try: + velocity_analyzer = VelocityAnalyzer(self.repo, self.days) + result.velocity_analysis = velocity_analyzer.analyze() + except Exception: + pass + + return result + + def get_productivity_report(self) -> ProductivityReport: + """Generate a comprehensive productivity report.""" + result = self.analyze() + + return ProductivityReport( + repository_path=self.repo_path, + analysis_days=self.days, + commit_analysis=result.commit_analysis, + code_churn_analysis=result.code_churn_analysis, + risky_commit_analysis=result.risky_commit_analysis, + velocity_analysis=result.velocity_analysis, + )