Add source code files
This commit is contained in:
76
src/codeguard/git/hooks.py
Normal file
76
src/codeguard/git/hooks.py
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
"""Git hooks management for CodeGuard."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import stat
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
class HookManager:
|
||||||
|
HOOK_SCRIPT = """#!/bin/bash
|
||||||
|
# CodeGuard pre-commit hook
|
||||||
|
# This hook runs CodeGuard security analysis before commit
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Get the root directory of the git repository
|
||||||
|
GIT_DIR=$(git rev-parse --git-dir)
|
||||||
|
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||||
|
|
||||||
|
# Change to repository root
|
||||||
|
cd "$REPO_ROOT"
|
||||||
|
|
||||||
|
# Run CodeGuard scan
|
||||||
|
# Exit with error code if scan fails or finds critical issues
|
||||||
|
exec codeguard scan --fail-level critical
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, repo_path: str = "."):
|
||||||
|
self.repo_path = Path(repo_path).resolve()
|
||||||
|
self.git_dir = self.repo_path / ".git"
|
||||||
|
self.hooks_dir = self.git_dir / "hooks"
|
||||||
|
|
||||||
|
def install(self, force: bool = False) -> bool:
|
||||||
|
if not self.git_dir.exists():
|
||||||
|
raise NotAGitRepository(f"Not a git repository: {self.repo_path}")
|
||||||
|
|
||||||
|
self.hooks_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
hook_path = self.hooks_dir / "pre-commit"
|
||||||
|
|
||||||
|
if hook_path.exists() and not force:
|
||||||
|
existing_content = hook_path.read_text()
|
||||||
|
if "codeguard" in existing_content.lower():
|
||||||
|
return False
|
||||||
|
|
||||||
|
hook_content = self._generate_hook_script()
|
||||||
|
hook_path.write_text(hook_content)
|
||||||
|
|
||||||
|
os.chmod(hook_path, hook_path.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def uninstall(self) -> None:
|
||||||
|
hook_path = self.hooks_dir / "pre-commit"
|
||||||
|
if hook_path.exists():
|
||||||
|
hook_path.unlink()
|
||||||
|
|
||||||
|
def _generate_hook_script(self) -> str:
|
||||||
|
return self.HOOK_SCRIPT
|
||||||
|
|
||||||
|
def check_installed(self) -> bool:
|
||||||
|
hook_path = self.hooks_dir / "pre-commit"
|
||||||
|
if not hook_path.exists():
|
||||||
|
return False
|
||||||
|
|
||||||
|
content = hook_path.read_text()
|
||||||
|
return "codeguard" in content.lower()
|
||||||
|
|
||||||
|
def get_hook_path(self) -> Path:
|
||||||
|
return self.hooks_dir / "pre-commit"
|
||||||
|
|
||||||
|
|
||||||
|
class NotAGitRepository(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class HookAlreadyInstalled(Exception):
|
||||||
|
pass
|
||||||
Reference in New Issue
Block a user