Хуки срабатывают на разные события Subversion, вот некоторые из них:
- start-commit — запускается до начала транзакции, может быть использован для проверки прав.
- pre-commit — запускается в конце транзакции, но до commit, часто используется для валидации данных, например для проверки не пустых лог-собщений.
- post-commit — запускается после транзакции, может быть использовано для отправки e-mail или для резервирования хранилища.
- pre-revprop-change — запускается до изменений в ревизии, могут быть использованы для проверки доступа.
- post-revprop-change — запускается после изменений в ревизии, могут быть использованы для отправки e-mail или для резервирования изменений.
- Есть еще «post-lock», «post-unlock», «pre-lock» и «pre-unlock», как видно из названий он срабатывают при блокировке.
Самый интересный из всех - это конечно "pre-commit". Именно в этот момент мы имеем весь текст транзакции, можем ее обработать или даже изменить.
Хук должен находится на сервере svn в папке "hooks", файл прекоммита называется "pre-commit.bat". Т.е. предполагается, что хук будет на батниках, к которым у меня хроническая нелюбовь. Так что мой батник будет вызывать vbs, а вся логика будет в вбсине.
Часть 1: батник, вызывающий VBS:
SETLOCAL SET PATH=C:\Windows;C:\Windows\system32;C:\Program Files\VisualSVN Server\bin; cscript.exe //NoLogo D:\Repositories\TradingSystem\hooks\pre-commit.wsf %1 %2 IF %ERRORLEVEL% EQU 1 GOTO fail IF %ERRORLEVEL% EQU 2 GOTO fail2 :success EXIT 0 :fail echo Введите описание к commit! 1>&2 EXIT 1 :fail2 echo Обнаружено не закрытое подключение к базе! 1>&2 EXIT 1Где "C:\Program Files\VisualSVN Server\bin" - путь до исполняемых файлов сервера SVN
"D:\Repositories\TradingSystem\hooks\pre-commit.wsf" - путь до запускаемого скрипта VBS
Т.е. роль нашего bat файла, вызвать VBS с параметрами и получить код возврата.
Сам VBS под катом: В скриптах мы ограничены списком объектов. В блоке "reference" мы должны указать список объектов, которые мы будем использовать.
VBS принимает от BAT 2 параметра:
- strRepoPath - путь до репозитория
- strRevision - идентификатор, добавляемой ревизии
<package> <job id="hPreCommit"> <reference object="WScript.Shell"/> <reference object="Scripting.Dictionary"/> <reference object="CDO.Message"/> <reference object="Scripting.FileSystemObject"/> <script language="VBScript"> Option Explicit 'путь до файла svnlook Public Const SVNLOOK_PATH = "C:\Program Files\VisualSVN Server\bin\svnlook.exe" Private retVal Private strRepoPath Private strRevision Private colArgs Public wshShell Set wshShell = WScript.CreateObject("WScript.Shell") Set colArgs = WScript.Arguments strRepoPath = colArgs(0) strRevision = colArgs(1) Dim command '1. получаем лог комита, если он пустой, то ругаемся command = "svnlook log " & strRepoPath & " -t " & strRevision Dim res:res = runCMD(command) '1.1. если есть ключевое слово, то пропускаем if InStr(res, "!skip") > 0 Then WScript.Quit(0) end if Dim l:l = Len(res) if l < 3 THEN WScript.Quit(1) end if '1.5 если добавление, то пропускаем command = "svnlook changed " & strRepoPath & " -t " & strRevision res = runCMD(command) if InStr(res, "A ") > 0 Then WScript.Quit(0) end if 'Ищем ключевые слова в добавляемом тексте 2. connected = true command = "svnlook diff " & strRepoPath & " -t " & strRevision & " --no-diff-deleted --no-diff-added -x -w -x -u -x --ignore-eol-style" res = runCMD(command) if InStr(res, "Connected = True") > 0 AND InStr(res, "- Connected = True") = 0 AND InStr(res, "- Connected = True") = 0 Then WScript.Quit(2) end if 'передаем результат в BAT WScript.Quit(0) 'пишем в лог ошибку провеки Function SendMail(subj, text, mailto) 'smtp сервер компании 'Dim smtp:smtp = "rassrv.domain.central" 'Dim myMail:Set myMail = CreateObject("CDO.Message") 'myMail.Subject = subj 'myMail.From = "svn@maxi-net.ru" 'myMail.To = mailto & "@central.local" 'myMail.TextBody = text 'myMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 'myMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = smtp 'myMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25 'myMail.Configuration.Fields.Update 'myMail.Send Dim fso:Set fso = CreateObject("Scripting.FileSystemObject") Dim cerr:Set cerr = fso.OpenTextFile(strRepoPath & "\hooks\error.log", 8, 1) cerr.WriteLine(Now() & ": " & text) cerr.Close SendMail = true End Function 'функция запускает cmd команду 'на команду дается 45 секунд, если не успеваем, то выходим Function runCMD(strRunCmd) Dim strOut Dim objExec Set objExec = wshShell.Exec(strRunCmd) Dim i Do While objExec.Status = 0 WScript.Sleep 100 i = i + 1 'ограничение в 45 секунд на комит IF i = 450 THEN runCMD = Empty SendMail "Commit Err", strRunCmd, "skan" WScript.Quit(4) exit function END IF Loop strOut = objExec.StdOut.ReadAll() Set objExec = Nothing strOut = Trim(strOut) If (Len(strOut) = 0) Then runCMD = Empty Else runCMD = strOut End If End Function </script> </job> </package>
Вот и все. Есть только один косяк - хук на содержание "svnlook diff" довольно часто зависает, эту проблему я пока не решил, буду рад, если кто подскажет.
А вот хуки на powershell намного сексуальнее, лол.
ОтветитьУдалить