同上一篇trac中安裝插件的文章的出發點同樣,感受用文檔和口頭制定規則在執行上會有誤差而且須要常常引導新人去熟悉規則。python
因此,又費了幾個小時去琢磨怎麼改進svn提交代碼的鉤子,現有的鉤子的功能比較簡單,只是驗證提交時的日誌字數有沒有超過5個,而我想將其改進爲驗證是否是符合「問題修復:#1234 xxxx」的這種格式,這裏處理的是 版本庫/hooks/pre-commit.bat 這個鉤子。正則表達式
話很少說,svn鉤子原理和規則不表,先上原鉤子代碼:ide
@echo off rem SVN強制寫註釋的hooks腳本(Windows) rem 文件名是: pre-commit.bat,放到repository/hooks目錄下 setlocal set SVN_BINDIR="D:\service\Subversion\bin" set REPOS=%1 set TXN=%2 rem check that logmessage contains at least 10 characters %SVN_BINDIR%\svnlook log "%REPOS%" -t "%TXN%" | findstr "......" > nul if %errorlevel% gtr 0 goto err exit 0 :err echo 提交時必須填寫說明(Message)! 1>&2 echo "%REPOS%" -t "%TXN%" 1>&2 exit 1
一開始嘗試使用直接修改bat,改進findstr來支持更復雜的正則表達式,可是遇到各類問題。svn
在測試過程當中保留了下面這個奇葩的中間版本(不能正常工做的)。工具
1 @echo off 2 rem SVN強制寫註釋的hooks腳本(Windows) 3 rem 文件名是: pre-commit.bat,放到repository/hooks目錄下 4 setlocal 5 set SVN_BINDIR=C:\Program Files\TortoiseSVN\bin 6 set REPOS=%1 7 set TXN=%2 8 9 rem check that logmessage contains at least 10 characters 10 "%SVN_BINDIR%\svnlook" log "%REPOS%" -t "%TXN%" > t.log 11 12 :set disable=:;'^<^>,。‘*【】{}??《》 13 rem (#[0-9]+ )?[^# 容許帶或不帶ticket號開頭,不支持非中文符號 14 15 findstr "^問題修復:(#[0-9]+ )*..." t.log 16 @echo %errorlevel% 1>&2 17 if not %errorlevel% gtr 0 goto success 18 findstr "^功能開發:(#[0-9]+ )*[^#%disable%]*$" t.log > nul 19 if not %errorlevel% gtr 0 goto success 20 findstr "^功能改進:(#[0-9]+ )*[^#%disable%]*$" t.log > nul 21 if not %errorlevel% gtr 0 goto success 22 findstr "^功能優化:(#[0-9]+ )*[^#%disable%]*$" t.log > nul 23 if not %errorlevel% gtr 0 goto success 24 findstr "^代碼優化:(#[0-9]+ )*[^#%disable%]*$" t.log > nul 25 if not %errorlevel% gtr 0 goto success 26 27 :err 28 echo 未遵循svn提交規範 1>&2 29 :echo "%REPOS%" -t "%TXN%" 1>&2 30 :rm t.log 31 exit 1 32 33 :success 34 :rm t.log 35 exit 1
能夠看到,我無奈地將一個正則表達式一分爲五,而且拆分紅5個以後不會使用管道同時將參數傳遞(也不能吧?)給findstr,關鍵是我那麼一大串在日誌中禁用標點符號不知爲什麼不能工做,反正斷斷續續(常常被人打斷工做,去處理其它事)耗費了我3個小時去寫測試的批處理和這個鉤子批處理,仍是搞不定。一念下,想起python這種神器,花了幾分鐘找到了正則表達式的match示例,又查閱了對於stdin輸入的獲取方法,而後直接寫了個check.py去代替findstr來匹配正則表達式(其實這思路是上午查看trac的TracTicketValidatorPlugin插件時看代碼獲得的),而後再花2分鐘驗證之,搞定,上代碼:測試
1 @echo off 2 rem SVN強制寫註釋的hooks腳本(Windows) 3 rem 文件名是: pre-commit.bat,放到repository/hooks目錄下 4 setlocal 5 set SVN_BINDIR="C:\Program Files\TortoiseSVN\bin" 6 set REPOS=%1 7 set TXN=%2 8 9 rem check that logmessage contains at least 10 characters 10 %SVN_BINDIR%\svnlook log "%REPOS%" -t "%TXN%" | python check.py "......" 1>&2 11 if %errorlevel% gtr 0 goto err 12 exit 0 13 14 :err 15 echo 未遵循svn提交規範! 1>&2 16 echo "%REPOS%" -t "%TXN%" 1>&2 17 exit 1
1 # coding=gbk 2 import re 3 import sys 4 5 input_file = sys.stdin 6 7 # 若是不用unicode模式則在有全角字符的狀況下匹配不成功 8 restr=u'^((問題修復)|(功能開發)|(功能改進)|(功能優化)|(代碼優化)):(#[0-9]+ )?[^#:;\'<>,。‘*【】{}??《》\n\r]+$' 9 for s in input_file: 10 #先解碼爲unicode字符串 11 u = s.decode('GBK') 12 print(u"驗證字符串:" + u) 13 if re.match(restr, u) != None: 14 print("匹配成功") 15 exit(0) 16 else: 17 exit(1)
ps:優化
哎,用幾年批處理,依然被諸如:啓動進程進獲取打印信息,字符串截取,字符串拼裝等一些簡單操做給難倒,感受每次寫批處理都是在 拼湊->試一下 的無限循環,不學點新東西就落後了。spa