Хук - это набор команд на определенное действие с репозиторием SVN.Хуки срабатывают на разные события 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 намного сексуальнее, лол.
ОтветитьУдалить