Windows上のSubversionでコミット時にメールを送信する方法

ソース管理をしていて、例えば共通で使っているライブラリが更新された場合、何らかの手段で 更新されたことを知りたいと思い調べてみました。

Subversionでは、リポジトリディレクトリにあるhooksディレクトリに実行ファイルを配置することで コミット等のイベントで実行してくれる機能があります。

Windows上にインストールしたSubversionを使って作成したリポジトリには、次のスクリプトテンプレートが 作成されていました。

post-commit.tmpl          post-unlock.tmpl          pre-revprop-change.tmpl
post-lock.tmpl            pre-commit.tmpl           pre-unlock.tmpl
post-revprop-change.tmpl  pre-lock.tmpl             start-commit.tmpl

単純にそのまま使うことはできなさそうなので、バッチファイルとVBScriptを使ってコミット時に メール送信が行われるようにしてみます。

Subversionから必要な情報を取得する

hooksのスクリプトは、実行される際、引数が2つ渡されます。

  • %1:リポジトリのディレクトリ
  • %2:リビジョン

Subversionに用意されているコマンドにsvnlookがあります。このコマンドを使って更新者とログメッセージを 取得しメールの本文を作成します。svnlookは、取得したい情報、リポジトリ、リビジョンを引数にとります。

更新者を取得するには、次のように実行します。

svnlook author リポジトリ -r リビジョン

ログメッセージを取得するには、次のように実行します

svnlook log リポジトリ -r リビジョン

コミット時にメールを送信する

実際に作ってみました。ここでは、バッチファイルとVBScriptを使用しています。メールの送信には CDOオブジェクトを使用しています。

post-commit.cmd
hooksディレクトリに配置
postcommit.vbs
メール本文の作成及びメール送信を実行
ml.txt
メールの送信先リスト

バッチファイルの例

@echo off
set path=%PATH%;"C:\Program Files\Subversion\bin"
D:
cd \svn
CScript //Nologo postcommit.vbs %1 %2

VBScriptの例

' /******************************************************
' 
' PostCommit[CScript]
' コミット情報をメール送信します。
'
' 作成:2007/04/26
' 
' /******************************************************

' -- 定数宣言
Const CDO_SENDUSINGMETHOD        = "http://schemas.microsoft.com/" _
                                 & "cdo/configuration/sendusing"
Const CDO_SENDUSINGPORT          = 2
Const CDO_SMTPSERVER             = "http://schemas.microsoft.com/" _
                                 & "cdo/configuration/smtpserver"
Const CDO_SMTPSERVERPORT         = "http://schemas.microsoft.com/" _
                                 & "cdo/configuration/smtpserverport"
Const CDO_SMTPCONNECTIONTIMEOUT  = "http://schemas.microsoft.com/" _
                                 & "cdo/configuration/smtpconnectiontimeout"

' SMTPサーバ
Const SMTP_SERVER                = "192.168.XXX.XXX"
' 送信先のメールアドレス保存ファイル
Const MAIL_LIST_PATH             = "D:\svn\ml.txt"
' 送信元アドレス
Const MAIL_FROM                  = "svn"

' -- Main

' 送信先アドレスの取得
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

Set objFile = objFSO.OpenTextFile(MAIL_LIST_PATH, 1)

Do Until objFile.AtEndOfStream  
   strAddr = strAddr & objFile.ReadLine & ","
Loop
objFile.Close
strAddr = left(strAddr,len(strAddr)-1)

Set objArgs = WScript.Arguments

strRepPath = objArgs(0)
strRepRevision = objArgs(1)

WScript.echo strRepPath 

Set objShell = WScript.CreateObject("WScript.Shell")

' Author 情報の取得
Set objExec = objShell.Exec("svnlook author " + strRepPath + " -r " + strRepRevision)

strAuthor = objExec.StdOut.ReadLine

Set objExec = Nothing

' ログメッセージの取得
Set objExec = objShell.Exec("svnlook log " + strRepPath + " -r " + strRepRevision)

Do Until objExec.StdOut.AtEndOfStream
  strLogMessage = strLogMessage & objExec.StdOut.ReadLine & vbCrLf
Loop


' メール設定
Set objConfig = CreateObject("CDO.Configuration")
Set Fields = objConfig.Fields

With Fields
.Item(CDO_SENDUSINGMETHOD)       = CDO_SENDUSINGPORT
.Item(CDO_SMTPSERVER)            = SMTP_SERVER
.Item(CDO_SMTPSERVERPORT)        = 25
.Item(CDO_SMTPCONNECTIONTIMEOUT) = 10
.Update
End With


' メール送信
Set objMsg = CreateObject("CDO.Message")
Set objMsg.Configuration = objConfig

' メールメッセージの成型
strBody = strBody & "Repository:" & strRepPath & vbCrLf
strBody = strBody & "Date:" & Date() & vbCrLf
strBody = strBody & "Author:" & strAuthor & vbCrLf
strBody = strBody & vbCrLf

strBody = strBody & "Log Message:" & vbCrLf & vbCrLf
strBody = strBody & strLogMessage & vbCrLf

' メールヘッダの成型
objMsg.From = MAIL_FROM
objMsg.To = strAddr
objMsg.Subject = "[svn commit message]"
objMsg.TextBody = strBody

' メール送信処理
objMsg.Send