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

メモ:  Category:windows

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

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<bnote@xxx.xxx.net>"

' -- 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

bluenote by BBB