Subversionサーバー(Windows)で日本語コミットメールを送る
今、古いWindowsNT4サーバーの廃止に向けて、いろいろとWindows Server2003に移動しています。思ってみれば、NT4もずいぶん使い出のあったものです。しかしさすがにセキュリティパッチも出ませんし、そろそろ廃止しなければ、と。
最近はバージョン管理システムもCVSからSubversionに移行しつつある様子ですが、この際ということで、本格的にSubversionサーバーをセットアップすることにしました。なお、うちではサーバー類を全部Windowsで動かすのがポリシーのようになってきていますので、Windows環境(Windows Server 2003)です。
#ちなみに、ircサーバーだけは、Windows版バイナリがウイルス扱いされるので(苦笑)vmware上のlinuxで動かしています・・・
Subversionの設置手法は svnserve.exe(Subversion付属サーバーソフト) + cygwin sshd といった感じです。
SVN+SSHの設定も多少面倒だったのですが、だいたいポイントは以下のような感じ。
・Windows上に追加するSSH使用ユーザーは1人分で良く、home/svn_user/.ssh/authorized_keys 内に複数人分のエントリを書いておき、SVN上で記録するユーザー名の指定は svnserve のパラメータ --tunnel-user で可能。
(もちろんWindows上で複数ユーザーを作成し、それぞれにSSHを設定する方法もあるが、この場合ユーザーのファイル関連パーミッション設定などに注意する必要がある。umask 002を設定するシェルスクリプトでsvnserve.exeをラップするといいらしい)
・authorized_keys内、svnserveの-rで設定するリポジトリ位置は C:/xxx/xxx の記法でうまくいった
・authorized_keysに書く暗号規格の文字列は RSAの場合はssh-rsa だが DSAの場合はssh-dss
・sshd_config内で UseDNS no にしないとSSHDにリモートから接続するたびに数秒ラグが発生する
・cygwinのシェルスクリプトでは、改行コードをUNIX系にしないと誤動作する
さて、本題のコミットメールです。
とにかく成果物ということで・・・
以下の2つのファイルを設置すればWindows版Subversionで日本語コミットメールが送れます。
ただし、大したテストはしていませんし、もちろん無保証です。自己責任でどうぞ。
Perl5.8.x必須です。
sendmail代替用にsendまね~るがおすすめです。
・commit-email-jp.pl
コンピュータ内の任意のフォルダにおいてください。
Configuration sectionあたりの変数を修正して、
svnlookの位置、sendmail (sendまね~る)の位置を指定してください。また、出力エンコーディングの変更も可能です。
一応、本家からのパッチはこれ。パッチ自体は設置の必要はありません。
2007/12/4 メールの送信時刻がずれる問題を修正しました(Dateヘッダを出力しないよう修正)
・post-commit.bat
リポジトリのhooksディレクトリに置いてください。
perlのパスと上記commit-email-jp.plへのパスを設定してください。
なお、特にWindowsじゃないと動かないというような修正はしていないつもりですが、UNIX環境でどうなるかはテストしていません。
以下、経緯や詳細など。
経緯というか・・・
CVSでは、CVSMailerでコミットメールを送っていましたが、
Windows版Subversionの場合、リポジトリ内のhooksディレクトリにpost-commit.batというバッチファイルを置くとそれを実行してくれる、というような構造のようです。
そこで、何か良いソフトはないかと、svnmailer,UmiNotify と試してみたが、文字化けが発生。
Windows系のファイルを管理していることもあり、
- ログメッセージはUTF-8 (さらにsvnlookは妙なエンコードで吐き出す)
- Commitするファイル自体はSJIS
という環境のため、これらを問題なく表示できるものがありませんでした。
仕方ないので、svnlog2utf8 なども参考にして commit-email.pl.in を修正。
なんとか表示できるようにしました。(Perl5.8用)
ポイントだけいくつか。
- 送りたいメールはJISエンコーディング(7bit-jis)だが、sendまね~るに食わせる内容はSJIS(shiftjis)で良い
- setftimeだと日本語の日付文字列が出てしまうので、dateコマンドで出力することにしました。(このため、もしかするとcygwinが入ってないと動作が違うかも??)
- svnlookの出力文字列は、1行ごとにエンコーディングを判別するようにしました。判別不可能の場合は$default_log_encodingを使用します。
ViewVCとの連携もしたいところですが、今日はここまで。
技術的な話:Perl5.8.xのEncodeモジュールについて
Perl自体かなり久々にいじることもあって、
日本語変換に使用するEncodeモジュールの特性を見極めるのにしばらくかかりました。
だいたい以下の点がポイントに思えました。
・UTF-8フラグについて
Perlの文字列変数にはUTF-8フラグというものが属性としてついており、
これがONであるような文字列は、Encode::encode() や binmode 等を使用して、
自動的にエンコーディング変換することができます。
しかし注意しなければならないのは、特定の関数・設定をつかわなければこのUTF-8フラグがONにならず、その場合適切に変換されない ということ。
・Encode::encodeについて
$out = encode(文字コード, $in) では、$inがutf-8ならば、「文字コード」エンコーディングに変換して$outに出力。
出力結果$outは必ずUTF-8フラグが外れる(バイト列扱い)
・Encode::decodeについて
$out = decode(文字コード, $in) では、$inが「文字コード」でエンコードされたバイト列と考えて、
UTF-8文字列に変換した上で$outに出力される。必ずUTF-8フラグがつく。
・Encode::from_to
from_to() では、基本的にUTF-8フラグは外れる。入力も出力も「バイト列」扱い。
・binmodeについて
binmode STDOUT, ":encoding(shiftjis)";
のような方法で標準入出力への出力・入力時のエンコーディング変換を指定できるが、
UTF-8フラグが立った状態の文字列を出力するのでなければ、まともに動作しない。
枠組みとしてはこんなもんだと思いますが、
あんまり確認していないので間違いあると思いますし、包括的な説明でもありませんね。
間違っている点などあればご指摘くださいませ・・・。
詳細はこのあたりを参照してください。
http://perldoc.perl.org/Encode.html#The-UTF-8-flag(英語)
2007.11.26 | Comments(0) | Trackback(0) | プログラミング
