O-AAの開発が割りと加速してきた風なので、標題のようなことを考え付いていろいろ調べてみたところ、SVN::Logというモジュールを発見。
...が、ソースを読んでみるとまだまだって感じ。SWIGでAPI叩く方法とsvnコマンドラインをopenしてパイプ(!)する方法から選べる実装なんだけど、SWIGでは「特定のリポジトリに関する最新のリビジョン番号を取得する」方法がない(subversionのAPIにはあるけどモジュールで対応してない)し、コマンドラインだとなぜか引数が固定(!)になってて「こっからここまでのりビジョンを取得」しかできない上に、存在しない番号を与えるとこける...。これじゃあ「特定のリポジトリのtrunkに関するログをとりあえず全部取得」とかできないじゃん。
# でもまぁつい先日バージョンアップしたみたいだし、今後に期待ってところですな
というわけで仕方なく自力(かつ力技)でゴリゴリと。
長いのでいったん区切り。以下読みたい人だけどうぞ。
#!/usr/bin/perl -w
use strict;
use lib qw(/path/to/lib);
use Unicode::Japanese;
use Date::Parse;
use DateTime;
use Cache::FileCache;
my $PROJECT = 'Object-AutoAccessor';
my $SVN = '/path/to/svn';
my $REPOS = 'repository URL';
my $LIMIT = 10; # お好みで
my $cache = new Cache::FileCache({
cache_root => '/path/to/cache',
namespace => $PROJECT,
default_expires_in => 60 * 60,
});
my $data = '';
unless ($data = $cache->get($PROJECT)) {
my $line = '';
open(SVN, "$SVN log $REPOS|") or die;
binmode SVN;
{
local $/ = undef;
$line = ;
$line =~ s/^\-+\x0D?\x0A?//;
$line =~ s/\-+\x0D?\x0A?$//;
}
close SVN;
my @chunks = ();
@chunks = split /^\-+$/m, $line;
my @logs = ();
for my $chunk (@chunks) {
my ($rev, $author, $time, $log) = map { s/^\x0D?\x0A?//m; s/\x0D?\x0A?$//m; $_ } split /\s*\|\s*/m, $chunk;
$rev =~ s/^r//;
$log =~ s/^\d+ lines?\x0D?\x0A?//;
$log =~ s/\x0D?\x0A?$//mg;
$log =~ s/\?\\(\d+)/chr($1)/eg;
$log ||= '(no logs)';
$log = Unicode::Japanese->new($log)->euc;
$time =~ s/\s*\(.*?\)$//;
$time = str2time($time);
push @logs, {revision => $rev, author => $author, time => $time, log => $log};
}
my $limit = 0;
for my $log (sort { $b->{revision} <=> $a->{revision} } @logs) {
$limit++;
my $dt = DateTime->from_epoch( epoch => $log->{time}, time_zone => 'Asia/Tokyo' );
my $date_time = join(' ', $dt->ymd('/'), $dt->hour.':'.$dt->min);
$log->{log} =~ s/\n/
└ /g;
$log->{log} =~ s/'/\\'/g;
my $output = "Rev.$log->{revision} - $log->{author}
└ $log->{log}
($date_time)
";
$output = Unicode::Japanese->new($output, 'euc')->get;
$output = "document.write('$output')\n";
$data .= $output;
last if $limit >= $LIMIT;
}
$cache->set($PROJECT => $data);
}
print "Content-Type: text/javascript\n\n";
print $data;
1;
__END__
なにげに思い出したように Cache::Cache 使ってます。たろさんありがとー。


あけましておめでとうございます!
昨年のうちにレスするつもりが orz
> なにげに思い出したように Cache::Cache 使ってます。たろさんありがとー。
いえいえー。今年も頑張って Perl 界隈の Watcher やっていきますのでよろしくお願いしますヽ(´ー`)ノ
ではでは、本年もよろしくお願いいたします~。