Hisashi Morita ([info]hisashim) wrote,
@ 2007-07-24 22:28:00
Previous Entry  Add to memories!  Tell a Friend  Next Entry
[Ruby][Subversion] Using Subversion Ruby binding (libsvn-ruby)
Subversionのリポジトリから情報を引き出すRubyスクリプトを書きたい。というわけでRubyバインディングを使う。

Debianではlibsvn-rubyをインストールすると/usr/lib/ruby/x.y/svn/*.rbに格納される。テストスクリプトはインストールされないようなのでリポジトリを参照(libsvn-devに含まれるのかもしれないけど一緒にいろいろ入るのが面倒なので)。
http://svn.collab.net/viewvc/svn/trunk/subversion/bindings/swig/ruby/test/

何かを始める時は、まず全体像をつかみたい。この記事が参考になる。
偽偽夜食日記: Subversion
http://rryu.sakura.ne.jp/nisenise-fuhito/category/subversion.html

2006年07月17日(月) Subversionブロック図

クライアントは異本的にlibsvn_clientだけを相手にしていれば、基本的にはそれより下の層については何も考えなくて良い。事実、標準のCLIクライアントは、ほぼlibsvn_clientのラッパーという感じになっているようだ。

svnと同じ事がしたいだけならlibsvn_clientにある機能で事が足りる。Rubyなら、test_client.rbでの使われ方を参考にclient.rbを読めばよさそう。

どうやらたいていの場合、Svn::Client::Contextのインスタンスを生成して、それに定義されたメソッドを呼べばいいらしい。
  % ruby -rsvn/client -e 'p Svn::Client::Context.new.methods'

のようにして調べると、Contextにはcheckoutやcommitといったメソッドが定義されている。svnのサブコマンドと同名なので分かりやすい。

svn log -r 10:head --limit 100相当のことをやってみる。
  % ruby -rsvn/client -e \
    'Svn::Client::Context.new.log(
       "/path/to/wc/trunk",
       10, "head", 100, false, false){
       |changed_paths, rev, author, date, message|
       p [changed_paths, rev, author, date, message]}'

  [nil, 10, "jdoe", Sun Apr 1 10:00:00 +0900 2007, "Fix typo."]
  [nil, 11, "jdoe", Sun Apr 2 15:00:00 +0900 2007, "Fix another typo."]

次はsvn diff -r prev:head相当。
  % ruby -rsvn/client -e \
    'Svn::Client::Context.new.diff([],
      "/path/to/wc/trunk/Makefile", "prev",
      "/path/to/wc/trunk/Makefile", "head",
      "/tmp/diffout", "/tmp/differr")'
  % cat /tmp/diffout
  Index: /path/to/wc/trunk/Makefile
  ===================================================================
  --- /path/to/wc/trunk/Makefile (revision 10)
  +++ /path/to/wc/trunk/Makefile (revision 12)
  ...

なかなか便利。ただSSLを扱う正しい方法が分からないので、目的のリポジトリにアクセスできない。今日はここまで。

注意点:

静的な定義が見つからないメソッドは動的に解決されている場合がある。例えばSvn::Client::Context#log()は中でClient.log3()を呼んでいるがlog3()は存在せず、svn_client_log3()が呼ばれる。/usr/lib/ruby/x.y/svn/util.rb参照。

メソッドに渡す引数のうち、pathはexpandしたものを渡す必要があるみたい。

参考:

Greenbear Laboratory - Ruby/SVN
http://mono.kmc.gr.jp/~yhara/w/?Ruby%2FSVN

使用例。svn/infoしか使われていないけれども小さい。
http://svn.collab.net/viewvc/svn/trunk/tools/hook-scripts/commit-email.rb



Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…