Files
xsk-education-management/app/scripts/install_gitea_backup_hook.py
T
2026-06-14 21:10:59 +08:00

102 lines
2.9 KiB
Python

#!/usr/bin/env python3
from __future__ import annotations
import argparse
from pathlib import Path
import stat
import subprocess
import sys
PROJECT_DIR = Path(__file__).resolve().parents[1]
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="安装提交后自动推送到 Gitea 的 Git hook")
parser.add_argument("--remote", default="origin", help="Gitea remote 名称,默认 origin")
parser.add_argument("--force", action="store_true", help="覆盖已有 post-commit hook")
parser.add_argument("--dry-run", action="store_true", help="只打印将要写入的 hook 内容")
return parser.parse_args()
def run_git(args: list[str]) -> str:
result = subprocess.run(
["git", *args],
cwd=PROJECT_DIR,
text=True,
capture_output=True,
check=False,
)
if result.returncode != 0:
raise RuntimeError(result.stderr.strip() or result.stdout.strip())
return result.stdout.strip()
def hook_text(remote: str) -> str:
return f"""#!/bin/sh
set -eu
remote={remote!r}
branch=$(git symbolic-ref --quiet --short HEAD || true)
if [ -z "$branch" ]; then
echo "[gitea-backup] detached HEAD,跳过自动推送" >&2
exit 0
fi
if ! git remote get-url "$remote" >/dev/null 2>&1; then
echo "[gitea-backup] remote '$remote' 不存在,跳过自动推送" >&2
exit 0
fi
echo "[gitea-backup] pushing $branch to $remote"
if ! git push "$remote" "HEAD:$branch"; then
echo "[gitea-backup] push 失败;本地提交已保留,请检查 SSH key 或远端权限" >&2
exit 0
fi
"""
def main() -> int:
args = parse_args()
git_dir = Path(run_git(["rev-parse", "--git-dir"]))
if not git_dir.is_absolute():
git_dir = PROJECT_DIR / git_dir
hook_path = git_dir / "hooks" / "post-commit"
try:
remote_url = run_git(["remote", "get-url", args.remote])
except RuntimeError:
remote_url = ""
content = hook_text(args.remote)
if args.dry_run:
print(content)
if remote_url:
print(f"# remote {args.remote}: {remote_url}")
else:
print(f"# remote {args.remote}: 未配置")
return 0
if hook_path.exists() and not args.force:
raise RuntimeError(f"{hook_path} 已存在;如需覆盖,请加 --force")
hook_path.parent.mkdir(parents=True, exist_ok=True)
hook_path.write_text(content, encoding="utf-8")
mode = hook_path.stat().st_mode
hook_path.chmod(mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
print(f"已安装 {hook_path}")
if remote_url:
print(f"提交后将自动推送到 {args.remote}: {remote_url}")
else:
print(f"注意:当前尚未配置 remote '{args.remote}',请先设置 Gitea SSH 地址")
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except Exception as exc:
print(f"安装失败: {exc}", file=sys.stderr)
raise SystemExit(1)