SVN 预提交钩子逻辑
SVN pre-commit hook logic
我在我的 svn 预提交挂钩中添加了一个逻辑,以检查提交消息中是否有 QA(大写字母以 space 开头),然后提交应该会失败。但它不起作用。请帮助我如何正确编写它。
REPOS=""
TXN=""
# Make sure that the log message contains some text.
SVNLOOK=/usr/bin/svnlook
LOGMSG=$($SVNLOOK log -t "$TXN" "$REPOS")
# check if any comment has supplied by the commiter
if [ -z "$LOGMSG" ]; then
echo "Your commit was blocked because it have no comments." 1>&2
exit 1
fi
#check minimum size of text
if [ ${#LOGMSG} -lt 15 ]; then
echo "Your Commit was blocked because the comments does not meet minimum length requirements (15 letters)." 1>&2
exit 1
fi
# get TaskID by regex
TaskID=$(expr "$LOGMSG" : '\([#][0-9]\{1,9\}[:][" "]\)[A-Za-z0-9]*')
# Check if task id was found.
if [ -z "$TaskID" ]; then
echo "" 1>&2
echo "No Task id found in log message \"$LOGMSG\"" 1>&2
echo "" 1>&2
echo "The TaskID must be the first item on the first line of the log message." 1>&2
echo "" 1>&2
echo "Proper TaskID format--> #123- 'Your commit message' " 1>&2
exit 1
fi
#Check that QA should not be present in log message.
QA=$(expr "$LOGMSG" : '\(*[" "][QA][" "]\)')
if [ "$QA" == "QA" ]; then
echo "" 1>&2
echo "Your log message \"$LOGMSG\" must not contain QA in upper case." 1>&2
echo "" 1>&2
exit 1
fi
这可能是您的正则表达式检查“QA”时出错。
我发现使用此站点对测试正则表达式非常有用 - RegExr。
我将您的 (*[" "][QA][" "]) 表达式放入网站,当我查看它的详细信息时(页面底部的选项卡 link) ,它会准确地分解你的正则表达式匹配的内容。由此,它说它正在寻找以下内容:
- 0 个或更多(
- " 或 space
- Q 或 A(不是两者)
- " 或 space
- 以 ) 结尾
我将以下表达式放入其中 - ( (QA) ) 并且它能够在示例 svn 消息(TEST-117 QA 测试消息)中找到匹配项。
正则表达式不正确:
\(
在 expr
中启动捕获组,但您的任务不需要捕获组
- 当
*
在模式中跟随 \(
时,它会尝试匹配文字 *
[QA]
匹配单个字符,可以是Q
或A
expr
的模式必须从字符串的开头开始匹配
实际上,正则表达式不符合您的要求。
即使以上几点是固定的,QA
、"QA" 周围有 space 的模式也不会匹配这样的提交消息:
- "Fix the build of QA"
- "Broken in QA, temporarily"
- ...等等...
也就是说,您可能希望将 QA 与 字边界 相匹配,而不是 "QA" 左右。
使用 grep -w QA
.
很容易做到这一点
正如您在评论中澄清的那样,您确实想要 "Q" 之前的 space。
在那种情况下,grep
的 -w
标志不合适,
因为这需要在模式的两边都有一个单词边界。
还有另一种匹配单词边界的方法,
使用 \<
作为单词的开头,使用 \>
作为单词的结尾。
所以要在 "Q" 前面有一个 space,
和 "A" 之后的单词边界,你可以写 QA\>
,像这样:
if grep -q ' QA\>' <<< "$LOGMSG"; then
echo
echo "Your log message \"$LOGMSG\" must not contain QA in upper case."
echo
exit 1
fi 1>&2
注意其他一些改进:
- 您可以重定向整个
if
语句 ,而不是每个 echo
都重定向到 stderr
- 而不是
echo ""
你可以简单地写 echo
- 您可以在命令的退出代码上编写条件,而不是将命令的结果存储在临时变量中
我在我的 svn 预提交挂钩中添加了一个逻辑,以检查提交消息中是否有 QA(大写字母以 space 开头),然后提交应该会失败。但它不起作用。请帮助我如何正确编写它。
REPOS=""
TXN=""
# Make sure that the log message contains some text.
SVNLOOK=/usr/bin/svnlook
LOGMSG=$($SVNLOOK log -t "$TXN" "$REPOS")
# check if any comment has supplied by the commiter
if [ -z "$LOGMSG" ]; then
echo "Your commit was blocked because it have no comments." 1>&2
exit 1
fi
#check minimum size of text
if [ ${#LOGMSG} -lt 15 ]; then
echo "Your Commit was blocked because the comments does not meet minimum length requirements (15 letters)." 1>&2
exit 1
fi
# get TaskID by regex
TaskID=$(expr "$LOGMSG" : '\([#][0-9]\{1,9\}[:][" "]\)[A-Za-z0-9]*')
# Check if task id was found.
if [ -z "$TaskID" ]; then
echo "" 1>&2
echo "No Task id found in log message \"$LOGMSG\"" 1>&2
echo "" 1>&2
echo "The TaskID must be the first item on the first line of the log message." 1>&2
echo "" 1>&2
echo "Proper TaskID format--> #123- 'Your commit message' " 1>&2
exit 1
fi
#Check that QA should not be present in log message.
QA=$(expr "$LOGMSG" : '\(*[" "][QA][" "]\)')
if [ "$QA" == "QA" ]; then
echo "" 1>&2
echo "Your log message \"$LOGMSG\" must not contain QA in upper case." 1>&2
echo "" 1>&2
exit 1
fi
这可能是您的正则表达式检查“QA”时出错。
我发现使用此站点对测试正则表达式非常有用 - RegExr。
我将您的 (*[" "][QA][" "]) 表达式放入网站,当我查看它的详细信息时(页面底部的选项卡 link) ,它会准确地分解你的正则表达式匹配的内容。由此,它说它正在寻找以下内容:
- 0 个或更多(
- " 或 space
- Q 或 A(不是两者)
- " 或 space
- 以 ) 结尾
我将以下表达式放入其中 - ( (QA) ) 并且它能够在示例 svn 消息(TEST-117 QA 测试消息)中找到匹配项。
正则表达式不正确:
\(
在expr
中启动捕获组,但您的任务不需要捕获组- 当
*
在模式中跟随\(
时,它会尝试匹配文字*
[QA]
匹配单个字符,可以是Q
或A
expr
的模式必须从字符串的开头开始匹配
实际上,正则表达式不符合您的要求。
即使以上几点是固定的,QA
、"QA" 周围有 space 的模式也不会匹配这样的提交消息:
- "Fix the build of QA"
- "Broken in QA, temporarily"
- ...等等...
也就是说,您可能希望将 QA 与 字边界 相匹配,而不是 "QA" 左右。
使用 grep -w QA
.
正如您在评论中澄清的那样,您确实想要 "Q" 之前的 space。
在那种情况下,grep
的 -w
标志不合适,
因为这需要在模式的两边都有一个单词边界。
还有另一种匹配单词边界的方法,
使用 \<
作为单词的开头,使用 \>
作为单词的结尾。
所以要在 "Q" 前面有一个 space,
和 "A" 之后的单词边界,你可以写 QA\>
,像这样:
if grep -q ' QA\>' <<< "$LOGMSG"; then
echo
echo "Your log message \"$LOGMSG\" must not contain QA in upper case."
echo
exit 1
fi 1>&2
注意其他一些改进:
- 您可以重定向整个
if
语句 ,而不是每个 - 而不是
echo ""
你可以简单地写echo
- 您可以在命令的退出代码上编写条件,而不是将命令的结果存储在临时变量中
echo
都重定向到 stderr