SVNのコメントに記述したRedmineのチケットNoにチケットのタイトルを追加する

RoR入門はお休みしてsubversionのフックスクリプトを試す。
SVNのコミットコメントに記述したチケットNoをキーにしてRedmineを検索し、「#チケットNo チケットタイトル」という形で表示してみる。
Unixでやりたいけれど、会社の環境がWindowsなのでWindows向けで。

  • post-commit.bat
@ECHO OFF

set REPOS="%1"
set REV="%2"

cd %REPOSITORY_ROOT%/hook
ruby post-commit.rb %REPOS% %REV%

%REPOSITORY_ROOT%/hook以下にpost-commit.batというファイルを置いておけばコミット後に実行される。
SVNによるフックスクリプトの実行ではカレントディレクトリがどこになるかは未定義なので、カレントディレクトリをきちんと決めてやる必要がある。
絶対パスで指定しても良いのだけれど、rubyでrequireするときも絶対パスにしなければならなくなってしまうので、カレントディレクトリの指定がよい。

  • post-commit.rb
#! ruby -Ku
require 'active_record'
require 'comment_helper'

repo = ARGV[0]		#リポジトリのパス
rev = ARGV[1]		#リビジョン

#MySQLに接続
ActiveRecord::Base.establish_connection(
	:adapter  => 'mysql',
	:host     => 'localhost',
	:username => 'root',
	:password => 'admin',
	:database => 'redmine',
	:encoding => 'utf8'
)

#Redmineのチケットのモデル
class Issue < ActiveRecord::Base
end

#Redmineの課題番号にタイトルを付加したリストを作成
log = `svnlook log #{repo} -r #{rev} `
ana_res = analyze_comment(log)
titles = ana_res[:issue_numbers].map do |number|
	issue = Issue.find(number[1..number.length])
	"#{number} #{issue.subject.tosjis}"
end

#SVNのコミットコメントを書き換え
new_comment_file_name = "%REPOSITORY_ROOT%/hooks/.newcomments/#{rev}.txt"
File.open(new_comment_file_name, 'w') do |f|
	f.print "#{ana_res[:proc]} #{titles.join(', ')}\n#{ana_res[:rest]}"
end
`svnadmin setlog --bypass-hooks #{repo} -r #{rev} #{new_comment_file_name}`
File.delete(new_comment_file_name)

rubyのソースの中からOSにコマンドを発行できるのがすばらしい。

  • comment_helper.rb
#! ruby -Ku

#SVNコメントの正規表現
COMMENT_PATTERN = /^(ref|fix) (#\d+\s*(,\s*#\d+\s*)*)\s*$(.*)/m

#コメントを正規表現で解析。
#定められた形式にマッチしない場合はnilを戻す
def analyze_comment(comment)
	ret = comment =~ COMMENT_PATTERN
	return nil if ret.nil?

	proc = $1
	rest = ($4 || "").strip
	issue_numbers = $2.split(/[,\s]+/)
	
	{:proc => proc, :issue_numbers => issue_numbers, :rest => rest}
end

想定しているコメントは以下のような形。
チケットを複数指定する場合はカンマで区切る。

ref #1101
何か修正


とりあえずではあるが、できた。
Javaで書く場合と比べて超すっきり。