From d20c16aa5a6197f2a455bba0f85e216ad124d170 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Fri, 30 Jan 2026 20:35:22 +0000 Subject: [PATCH] Initial upload: git-insights-cli with CI/CD workflow --- src/analyzers/risky_commit.py | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/analyzers/risky_commit.py diff --git a/src/analyzers/risky_commit.py b/src/analyzers/risky_commit.py new file mode 100644 index 0000000..e1cbbcb --- /dev/null +++ b/src/analyzers/risky_commit.py @@ -0,0 +1,49 @@ +from dataclasses import dataclass +from typing import Any, Dict, List, Optional + +from src.analyzers.git_repository import GitRepository +from src.models.data_structures import RiskyCommitAnalysis, Commit + + +@dataclass +class RiskyCommitDetector: + """Detects risky commits.""" + + repo: GitRepository + days: int + + def analyze(self) -> Optional[RiskyCommitAnalysis]: + """Detect risky commits.""" + commits = self.repo.get_commits() + + if not commits: + return None + + large_change_commits = [] + merge_commits = [] + revert_commits = [] + + for commit in commits: + if commit.is_revert: + revert_commits.append(commit) + elif commit.is_merge: + merge_commits.append(commit) + + threshold = 500 + if commit.lines_added + commit.lines_deleted > threshold: + large_change_commits.append(commit) + + total_risky = len(large_change_commits) + len(merge_commits) + len(revert_commits) + risk_score = total_risky / max(1, len(commits)) * 100 + + return RiskyCommitAnalysis( + total_risky_commits=total_risky, + large_change_commits=sorted( + large_change_commits, + key=lambda c: c.lines_added + c.lines_deleted, + reverse=True, + )[:20], + merge_commits=merge_commits[:20], + revert_commits=revert_commits[:20], + risk_score=risk_score, + )