2010-12-02 90 views
2

我有以下的pre-commit钩子使用JavaScript Lint检查JavaScript文件提交之前:为什么我的SVN预先提交挂钩在本地工作,但没有提交?

#!/bin/env bash 

REPOS="$1" 
TXN="$2" 

ECHO=/bin/echo 
GREP=/bin/grep 
SED=/bin/sed 

SVN=/usr/bin/svn 
SVNLOOK=/usr/bin/svnlook 
FILES_CHANGED=`$SVNLOOK changed -r$TXN $REPOS | $SED -e "s/^....//g"` 

JSL=/usr/local/bin/jsl 
JSL_CONF=/usr/local/etc/jsl.conf 

for FILE in $FILES_CHANGED 
do 
     if $ECHO $FILE | $GREP "\.js$" 
     then 
       $SVN cat -r$TXN file://$REPOS/$FILE | $JSL -conf $JSL_CONF -stdin 1>&2 
       JSL_ERROR_CODE=$? 
       if [ $JSL_ERROR_CODE != 0 ] 
       then 
         exit $JSL_ERROR_CODE 
       fi 
     fi 
done 

# If we got here, nothing is wrong. 
exit 0 

此代码本地工作如下: ./pre-commit /我的/ SVN /回购/位置6781#号码是交易号码

但是它在svn commit上没有错误。

我已经占到:

  • 由于没有$ PATH,我明确设置的所有命令的路径。
  • 我正在从jsl命令中捕获正确的错误代码以退出。
  • 我正在将STDOUT推送到STDERR作为jsl命令,因此它将显示在提交失败中。

我错过了什么?

你的,
特雷弗

回答

3

我发现了一个漫长而曲折的道路之后的答案。基本上,在我上面的脚本中,我在我的svn命令中使用了-r,在中使用了,而在中,使用了钩子you must use -t, not -r。完整的脚本如下:

#!/bin/sh 

REPOS="$1" 
TXN="$2" 

ECHO=/bin/echo 
GREP=/bin/grep 
SED=/bin/sed 

SVNLOOK=/usr/bin/svnlook 
FILES_CHANGED=`$SVNLOOK changed -t$TXN $REPOS | $SED -e "s/^....//g"` 

JSL=/usr/local/bin/jsl 
JSL_CONF=/usr/local/etc/jsl.default.conf 

for FILE in $FILES_CHANGED 
do 
    if $ECHO $FILE | $GREP "\.js$" 
    then 
     $SVNLOOK cat -t$TXN $REPOS $FILE | $JSL -conf $JSL_CONF -stdin -nologo 1>&2 
     JSL_ERROR_CODE=$? 
     if [ $JSL_ERROR_CODE != 0 ] 
     then 
      exit $JSL_ERROR_CODE 
     fi 
    fi 
done 

# If we got here, nothing is wrong. 
exit 0 
+0

是的,我正要向你指出,在提交之前你不能有一个修订号,对于预先提交的钩子,你必须使用事务编号,我把我的pre-commit钩子脚本写成从pre-commit脚本中分离出脚本,我只需要脚本“pre-commit”调用它,我的pre-commit钩子可以同时使用-r或者-t参数,并且在脚本中称为pre-commit,I用“-t”来调用它。这样,我可以从命令行直接测试我的pre-commit钩子脚本。 – 2010-12-03 18:33:48

3

这可能是你正在运行指望一些环境变量要设置的项目之一。

Repository Creation and Configuration

出于安全原因,Subversion版本库有一个空的环境,也就是说,没有环境变量在所有设置,甚至没有$ PATH或%PATH%执行钩子脚本。正因为如此,很多管理员在他们的钩子脚本手工运行时会感到困惑,但当他们运行在Subversion上时却不起作用。一定要在你的钩子中明确地设置环境变量和/或使用程序的绝对路径。

尝试在没有任何环境变量集的情况下在本地执行它们,看看是否有效。

我通常最终会在我的钩子脚本的第一行输入我的环境:

source /home/username/.bash_profile 
0

如果你正在寻找从svn进入的管道,而该jsl错误,然后$? ISN将不会包含返回码。改为使用${PIPESTATUS[@]}。它是一个包含管道每个成员的返回码的数组。一个快速的方法来检查任何未指定的失败将是:

$SVN cat -r$TXN file://$REPOS/$FILE | $JSL -conf $JSL_CONF -stdin 1>&2 
[[ ! ${PIPESTATUS[@]} =~ 1 ]] 
JSL_ERROR_CODE=$? 
if [ $JSL_ERROR_CODE != 0 ] 

$SVN cat -r$TXN file://$REPOS/$FILE | $JSL -conf $JSL_CONF -stdin 1>&2 
[[ ${PIPESTATUS[@]} != *1* ]] 
JSL_ERROR_CODE=$? 
if [ $JSL_ERROR_CODE != 0 ] 
+0

这是一个有用的提示,但我期待的退出状态来自jsl,而不是svn。 :( – 2010-12-03 14:33:01