Initial upload of auto-changelog-generator
Some checks failed
CI / test (push) Has started running
CI / build (push) Has been cancelled

This commit is contained in:
2026-01-29 12:00:30 +00:00
parent bc8d571785
commit 9f948a803a

View File

@@ -0,0 +1,136 @@
from pathlib import Path
from typing import Optional
import os
import stat
class GitHookType:
PREPARE_COMMIT_MSG = "prepare-commit-msg"
COMMIT_MSG = "commit-msg"
def get_git_hooks_dir(repo_path: Optional[Path] = None) -> Path:
"""Get the git hooks directory for a repository."""
if repo_path is None:
repo_path = Path.cwd()
git_dir = repo_path / ".git"
hooks_dir = git_dir / "hooks"
return hooks_dir
def get_hook_script_path(hook_type: str, repo_path: Optional[Path] = None) -> Path:
"""Get the path for a specific hook script."""
hooks_dir = get_git_hooks_dir(repo_path)
return hooks_dir / hook_type
def install_prepare_hook(
repo_path: Optional[Path] = None,
model: str = "llama3.2",
branches: Optional[list[str]] = None
) -> Path:
"""Install prepare-commit-msg hook for automatic changelog generation."""
hook_path = get_hook_script_path(GitHookType.PREPARE_COMMIT_MSG, repo_path)
branches_str = ",".join(branches) if branches else "*"
hook_content = f'''#!/bin/bash
# Auto Changelog Generator - prepare-commit-msg hook
# Generated by changeloggen
CHANGELOGGEN_MODEL="{model}"
CHANGELOGGEN_BRANCHES="{branches_str}"
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
if [ "$CHANGELOGGEN_BRANCHES" != "*" ]; then
if ! echo "$CHANGELOGGEN_BRANCHES" | grep -q "$BRANCH_NAME"; then
exit 0
fi
fi
STAGED_FILES=$(git diff --cached --name-only)
if [ -z "$STAGED_FILES" ]; then
echo "No staged files found. Skipping changelog generation."
exit 0
fi
echo "Generating changelog for commit on branch: $BRANCH_NAME"
python -m changeloggen generate --model "$CHANGELOGGEN_MODEL" --output commit-message
exit 0
'''
return _write_hook(hook_path, hook_content)
def install_commit_msg_hook(
repo_path: Optional[Path] = None,
model: str = "llama3.2",
branches: Optional[list[str]] = None
) -> Path:
"""Install commit-msg hook for validating/updating commit messages."""
hook_path = get_hook_script_path(GitHookType.COMMIT_MSG, repo_path)
branches_str = ",".join(branches) if branches else "*"
hook_content = f'''#!/bin/bash
# Auto Changelog Generator - commit-msg hook
# Generated by changeloggen
CHANGELOGGEN_MODEL="{model}"
CHANGELOGGEN_BRANCHES="{branches_str}"
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
if [ "$CHANGELOGGEN_BRANCHES" != "*" ]; then
if ! echo "$CHANGELOGGEN_BRANCHES" | grep -q "$BRANCH_NAME"; then
exit 0
fi
fi
exit 0
'''
return _write_hook(hook_path, hook_content)
def _write_hook(hook_path: Path, content: str) -> Path:
"""Write hook script and make it executable."""
hook_path.parent.mkdir(parents=True, exist_ok=True)
with open(hook_path, 'w') as f:
f.write(content)
os.chmod(hook_path, hook_path.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
return hook_path
def remove_hook(hook_type: str, repo_path: Optional[Path] = None) -> bool:
"""Remove a git hook."""
hook_path = get_hook_script_path(hook_type, repo_path)
if hook_path.exists():
hook_path.unlink()
return True
return False
def is_hook_installed(hook_type: str, repo_path: Optional[Path] = None) -> bool:
"""Check if a hook is installed."""
hook_path = get_hook_script_path(hook_type, repo_path)
return hook_path.exists()
def list_installed_hooks(repo_path: Optional[Path] = None) -> list[str]:
"""List all installed changeloggen hooks."""
hooks = []
for hook_type in [GitHookType.PREPARE_COMMIT_MSG, GitHookType.COMMIT_MSG]:
if is_hook_installed(hook_type, repo_path):
hooks.append(hook_type)
return hooks