Add storage models and monitor modules
Some checks failed
CI / test (push) Failing after 12s

This commit is contained in:
2026-01-30 09:10:47 +00:00
parent cb87ca93ec
commit 2e628e4050

183
src/monitor/git.py Normal file
View File

@@ -0,0 +1,183 @@
"""Git operation tracking using subprocess."""
import subprocess
from pathlib import Path
from typing import Optional, List, Dict, Any
from ..storage import Database, GitEvent
class GitTracker:
"""Tracks git operations in a repository."""
def __init__(self, db: Database, session_id: int):
self.db = db
self.session_id = session_id
self._last_commit: Optional[str] = None
self._last_branch: Optional[str] = None
def _run_git_command(
self,
args: List[str],
cwd: Optional[str] = None
) -> tuple:
"""Run a git command and return output."""
try:
result = subprocess.run(
["git"] + args,
cwd=cwd,
capture_output=True,
text=True,
timeout=5
)
return result.stdout, result.stderr, result.returncode
except (subprocess.TimeoutExpired, FileNotFoundError):
return "", "git not found", 1
def _get_current_branch(self, cwd: Optional[str] = None) -> Optional[str]:
"""Get current git branch."""
stdout, _, rc = self._run_git_command(["branch", "--show-current"], cwd)
if rc == 0:
return stdout.strip() or None
return None
def _get_current_commit(self, cwd: Optional[str] = None) -> Optional[str]:
"""Get current commit hash."""
stdout, _, rc = self._run_git_command(["rev-parse", "HEAD"], cwd)
if rc == 0:
return stdout.strip()
return None
def _get_diff(self, cwd: Optional[str] = None) -> Optional[str]:
"""Get current git diff."""
stdout, _, rc = self._run_git_command(["diff", "--stat"], cwd)
if rc == 0:
return stdout.strip()
return None
def detect_operation(self, cwd: Optional[str] = None) -> Optional[GitEvent]:
"""Detect current git state and operations."""
current_commit = self._get_current_commit(cwd)
current_branch = self._get_current_branch(cwd)
if current_commit is None:
return None
if self._last_commit is None:
self._last_commit = current_commit
self._last_branch = current_branch
return self.db.add_git_event(
session_id=self.session_id,
operation="checkout",
branch=current_branch,
commit_hash=current_commit,
details=f"Started at commit {current_commit[:7]}",
diff=None
)
if current_commit != self._last_commit:
self._last_commit = current_commit
stdout, _, _ = self._run_git_command(["log", "-1", "--format=%s%n%b", current_commit], cwd)
commit_message = stdout.strip().split("\n")[0] if stdout.strip() else ""
diff_stat = self._get_diff(cwd)
return self.db.add_git_event(
session_id=self.session_id,
operation="commit",
branch=current_branch,
commit_hash=current_commit,
details=commit_message,
diff=diff_stat
)
if current_branch != self._last_branch:
self._last_branch = current_branch
return self.db.add_git_event(
session_id=self.session_id,
operation="branch",
branch=current_branch,
commit_hash=current_commit,
details=f"Switched to branch {current_branch}",
diff=None
)
return None
def record_commit(
self,
message: str,
cwd: Optional[str] = None,
diff: Optional[str] = None
) -> int:
"""Record a commit event."""
commit_hash = self._get_current_commit(cwd)
branch = self._get_current_branch(cwd)
self._last_commit = commit_hash
return self.db.add_git_event(
session_id=self.session_id,
operation="commit",
branch=branch,
commit_hash=commit_hash,
details=message,
diff=diff
)
def record_branch(self, branch_name: str, cwd: Optional[str] = None) -> int:
"""Record a branch creation/switch event."""
commit_hash = self._get_current_commit(cwd)
self._last_branch = branch_name
return self.db.add_git_event(
session_id=self.session_id,
operation="branch",
branch=branch_name,
commit_hash=commit_hash,
details=f"Created/switched to branch {branch_name}",
diff=None
)
def record_push(self, remote: str, branch: str, cwd: Optional[str] = None) -> int:
"""Record a push event."""
commit_hash = self._get_current_commit(cwd)
return self.db.add_git_event(
session_id=self.session_id,
operation="push",
branch=branch,
commit_hash=commit_hash,
details=f"Pushed to {remote}/{branch}",
diff=None
)
def get_recent_commits(self, count: int = 10, cwd: Optional[str] = None) -> List[Dict[str, Any]]:
"""Get recent commits."""
stdout, _, rc = self._run_git_command(
["log", f"-{count}", "--format=hash:%H|date:%ad|message:%s", "--date=iso"],
cwd
)
if rc != 0:
return []
commits = []
for line in stdout.strip().split("\n"):
if line.startswith("hash:") and "|date:" in line:
try:
hash_part = line.split("|")[0].replace("hash:", "")
date_part = line.split("|")[1].replace("date:", "")
msg_part = line.split("|")[2].replace("message:", "")
commits.append({
"hash": hash_part,
"date": date_part,
"message": msg_part
})
except IndexError:
continue
return commits