Subversion(SVN)钩子脚本是一种用于在特定事件发生时自动执行指定操作的机制。钩子脚本在管理和维护版本库中非常有用,能够实现自动化任务、强制策略、以及与其他工具集成。
以下是一些常见的 SVN 钩子脚本及其用途:
常见钩子类型
pre-commit: 在提交事务被接受之前执行。用于检查提交的内容,例如代码风格、文件大小限制等。
示例:禁止提交包含调试代码的文件
#!/bin/sh REPOS="$1" TXN="$2" SVNLOOK=/usr/bin/svnlook $SVNLOOK diff -t "$TXN" "$REPOS" | grep "^+.*DEBUG" && { echo "禁止提交包含调试代码的文件。" >&2 exit 1 } exit 0post-commit: 在提交事务完成后执行。通常用于通知、持续集成触发、备份等任务。
示例:提交后发送邮件通知
#!/bin/sh REPOS="$1" REV="$2" SVNLOOK=/usr/bin/svnlook MAIL=/usr/bin/mail SUBJECT="SVN Commit Notification: r$REV" TO="team@example.com" BODY=$($SVNLOOK info -r "$REV" "$REPOS") echo "$BODY" | $MAIL -s "$SUBJECT" "$TO" exit 0
pre-revprop-change: 在版本库的修订属性被修改之前执行。用于限制修订属性的更改,例如禁止修改作者或日期属性。
示例:禁止修改作者属性
#!/bin/sh REPOS="$1" REV="$2" USER="$3" PROP="$4" ACTION="$5" if [ "$PROP" = "svn:author" ]; then echo "禁止修改作者属性。" >&2 exit 1 fi exit 0
post-revprop-change: 在版本库的修订属性被修改之后执行。用于记录属性更改历史或发送通知。
示例:修订属性修改后发送通知
#!/bin/sh REPOS="$1" REV="$2" USER="$3" PROP="$4" ACTION="$5" SVNLOOK=/usr/bin/svnlook MAIL=/usr/bin/mail SUBJECT="SVN Revision Property Change: r$REV" TO="admin@example.com" BODY="Property $PROP was $ACTION by $USER in revision $REV." echo "$BODY" | $MAIL -s "$SUBJECT" "$TO" exit 0
pre-lock: 在文件被锁定之前执行。用于检查是否允许锁定操作。
示例:限制锁定文件的用户
#!/bin/sh REPOS="$1" PATH="$2" USER="$3" if [ "$USER" != "allowed_user" ]; then echo "只有allowed_user用户可以锁定文件。" >&2 exit 1 fi exit 0
post-lock: 在文件被锁定之后执行。用于记录锁定历史或发送通知。
示例:锁定文件后发送通知
#!/bin/sh REPOS="$1" USER="$2" MAIL=/usr/bin/mail SUBJECT="SVN Lock Notification" TO="team@example.com" BODY="$USER has locked files in repository $REPOS." echo "$BODY" | $MAIL -s "$SUBJECT" "$TO" exit 0
pre-unlock: 在文件被解锁之前执行。用于检查是否允许解锁操作。
示例:限制解锁文件的用户
#!/bin/sh REPOS="$1" PATH="$2" USER="$3" if [ "$USER" != "allowed_user" ]; then echo "只有allowed_user用户可以解锁文件。" >&2 exit 1 fi exit 0
post-unlock: 在文件被解锁之后执行。用于记录解锁历史或发送通知。
示例:解锁文件后发送通知
#!/bin/sh REPOS="$1" USER="$2" MAIL=/usr/bin/mail SUBJECT="SVN Unlock Notification" TO="team@example.com" BODY="$USER has unlocked files in repository $REPOS." echo "$BODY" | $MAIL -s "$SUBJECT" "$TO" exit 0
pre-commit: 检查提交消息格式
确保提交消息包含特定的格式,例如必须包含 JIRA 票据编号。
#!/bin/sh REPOS="$1" TXN="$2" SVNLOOK=/usr/bin/svnlook LOGMSG=$($SVNLOOK log -t "$TXN" "$REPOS") if ! echo "$LOGMSG" | grep -qE "JIRA-[0-9]+"; then echo "提交消息必须包含 JIRA 票据编号 (例如: JIRA-1234)。" >&2 exit 1 fi exit 0
10. pre-commit: 检查代码风格
使用外部代码风格检查工具,如 eslint 对 JavaScript 代码进行检查。
#!/bin/sh
REPOS="$1"
TXN="$2"
TMP_DIR=/tmp/svn-check
SVNLOOK=/usr/bin/svnlook
ESLINT=/usr/bin/eslint
mkdir -p $TMP_DIR
$SVNLOOK changed -t "$TXN" "$REPOS" | grep "^A\|^M" | awk '{print $2}' | grep "\.js$" | while read FILE; do
$SVNLOOK cat -t "$TXN" "$REPOS" "$FILE" > "$TMP_DIR/$FILE"
$ESLINT "$TMP_DIR/$FILE" --quiet
if [ $? -ne 0 ]; then
echo "JavaScript 代码不符合风格要求: $FILE" >&2
rm -rf $TMP_DIR
exit 1
fi
done
rm -rf $TMP_DIR
exit 011. post-commit: 自动部署网站
在提交完成后,自动将代码部署到测试服务器。
#!/bin/sh
REPOS="$1"
REV="$2"
SVNLOOK=/usr/bin/svnlook
SSH=/usr/bin/ssh
# 提取提交的文件列表
FILES=$($SVNLOOK changed -r "$REV" "$REPOS" | awk '{print $2}')
DEPLOY_DIR=/var/www/html
# 使用 rsync 将文件同步到远程服务器
rsync -avz --delete $FILES user@remote-server:$DEPLOY_DIR
# 触发远程服务器重启服务
$SSH user@remote-server 'sudo systemctl restart apache2'
exit 012. pre-revprop-change: 限制属性修改时间
仅允许在提交后的 24 小时内修改修订属性。
#!/bin/sh REPOS="$1" REV="$2" USER="$3" PROP="$4" ACTION="$5" SVNLOOK=/usr/bin/svnlook TIMESTAMP=$($SVNLOOK date -r "$REV" "$REPOS") CURRENT_TIME=$(date +%s) COMMIT_TIME=$(date -d "$TIMESTAMP" +%s) TIME_DIFF=$(($CURRENT_TIME - $COMMIT_TIME)) if [ $TIME_DIFF -gt 86400 ]; then echo "只允许在提交后 24 小时内修改属性。" >&2 exit 1 fi exit 0
13. post-revprop-change: 记录属性变更历史
将属性变更记录保存到日志文件中。
#!/bin/sh REPOS="$1" REV="$2" USER="$3" PROP="$4" ACTION="$5" SVNLOOK=/usr/bin/svnlook LOGFILE=/var/log/svn-revprop-change.log echo "[$(date)] User: $USER, Revision: $REV, Property: $PROP, Action: $ACTION" >> $LOGFILE exit 0
14. pre-lock: 禁止特定文件类型锁定
禁止用户锁定某些特定类型的文件,例如图像文件。
#!/bin/sh
REPOS="$1"
PATH="$2"
USER="$3"
EXTENSION="${PATH##*.}"
case "$EXTENSION" in
jpg|jpeg|png|gif)
echo "禁止锁定图像文件。" >&2
exit 1
;;
esac
exit 015. pre-commit: 检查文件名合法性
确保提交的文件名不包含非法字符。
#!/bin/sh
REPOS="$1"
TXN="$2"
SVNLOOK=/usr/bin/svnlook
INVALID_CHARS='[:space:][:cntrl:]@#'
$SVNLOOK changed -t "$TXN" "$REPOS" | awk '{print $2}' | while read FILE; do
if echo "$FILE" | grep -q "[$INVALID_CHARS]"; then
echo "文件名包含非法字符: $FILE" >&2
exit 1
fi
done
exit 016. post-commit: 更新项目文档
在提交代码后,自动更新项目文档。
#!/bin/sh REPOS="$1" REV="$2" SVNLOOK=/usr/bin/svnlook DOC_DIR=/path/to/docs REPO_URL=file://$REPOS # 更新本地文档目录 svn update $DOC_DIR # 生成新的文档(假设使用 Doxygen) cd $DOC_DIR doxygen Doxyfile exit 0


网友留言: