concov のセットアップ方法例

rubyソースコードを chkbuild で定期ビルドし、concov にデータを登録させる手順をまとめました。
現状では chkbuild のセットアップと concov のセットアップの 2 段階になっています。

1. chkbuild をセットアップする

chkbuild は、rubyソースコードを定期的にチェックアウトし、ビルドし、テスト実行してくれる継続インテグレーション (continuous integration; CI) ツールです。

1.1. chkbuild のソースコードを入手する

chkbuild は以下の箇所にあります。

http://cvs.m17n.org/viewcvs/ruby/chkbuild/

cvs でチェックアウトします。

$ mkdir /home/mame/concov/
$ cd /home/mame/concov/
$ cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/ruby login
CVS password: (just hit enter)
$ cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/ruby co chkbuild

ここでは、ソースコードや設定を /home/mame/concov/ 以下に配置し、ビルドや測定結果の蓄積は /home/chkbuild/ 以下で行うものとします。適宜読み替えてください。

1.2. chkbuild にパッチをあてる

chkbuild に以下のパッチをあててください。
http://dame.dyndns.org/misc/misc/chkbuild-coverage-date.patch

このパッチは chkbuild に以下の機能を追加します。

  • チェックアウトする rubyソースコードの日付を指定できるようにする
  • gcov 測定下でテストを走らせる
  • coverage.so 測定下でテストを走らせる

パッチの当て方はこう。

$ cd chkbuild
$ wget http://dame.dyndns.org/misc/concov/chkbuild-coverage-date.patch
$ patch -p0 < chkbuild-coverage-date.patch
1.3. chkbuild を設定する

chkbuild の README.ja.rd の「設置」の節を参考に、chkbuild を設定してください。

$ su -
# adduser --disabled-login --no-create-home --shell /bin/false chkbuild
# usermod -a -G chkbuild mame
# cd /home
# mkdir chkbuild
# chown mame:chkbuild chkbuild
# chmod 2750 chkbuild
# exit
$ cd /home/chkbuild/
$ mkdir build public_html
$ chgrp chkbuild build public_html
$ chmod 2775 build public_html
$ cd /home/mame/concov/chkbuild/
$ ln -s /home/chkbuild/ tmp

また、start-build を書き換えて、sample/build-ruby-coverage をロードするようにしてください。例えばこのように。

#!/usr/bin/env ruby

require 'chkbuild'

load "sample/build-ruby-coverage"

定期実行の設定は concov の設定も合わせてやるので後回しです。

1.4. 備考: ruby 以外に適用する場合

chkbuild は rubyソースコードにかなり特化した CI ツールなので、ruby 以外に対して concov を適用する場合は chkbuild 以外の CI ツールを検討した方がいいかもしれません。
CI ツールは chkbuild 以外にもいっぱいあります (参考) 。一般的には CruiseControl が有名ですし、Ruby 製の CI ツールとしては CruiseControl.rbCerberus があります。でも、私は chkbuild 以外を試したことはありません。事例募集。

2. concov をセットアップする

concov については過去の記事を参照してください。

2.1. 必要な gem をインストールする

ramaze 、sequel 、amalgalite が必須です。

$ gem19 install ramaze sequel amalgalite

concov のテストを走らせるためには以下も必要です。

$ gem19 install rack-test bacon nokogiri

thin で動作することを確認しています。

$ gem19 install thin
2.2. concov のソースコードを入手する

concov は以下の箇所にあります。

http://github.com/mame/concov/tree/master

git でチェックアウトします。

$ cd /home/mame/concov
$ git clone git://github.com/mame/concov.git
2.3. concov を設定する
  • bin/concov の shebang を環境に合わせて書き換える。
  • concov.conf の database_path を指定する。ここでは /home/chkbuild/concov-data/ に配置することとします。
  • chkbuild の権限で concov のデータベースを初期化する。
$ vi bin/concov
$ vi concov.conf
$ mkdir /home/chkbuild/concov-data
$ chmod 2775 /home/chkbuild/concov-data
$ sudo -u chkbuild bin/concov init
2.4. concov の web インターフェイスを起動する

concov のディレクトリで

$ ramaze start

とすることで、web インターフェイスが立ち上がるはずです。http://server:7000/ で「concov error: no data found; please register first」と表示されたらとりあえずは成功。
thin を使う場合は

$ thin start
2.5. chkbuild の実行後にカバレッジデータを concov に登録する

concov にカバレッジデータを登録するには、以下のようにします。

  • ビルドディレクトリで gcov を使って *.gcov ファイルを作成する (参考) 。
  • bin/concov register を起動する。

/path/to/build/dir/ のディレクトリ以下にあるカバレッジファイルを 20090101 のデータとして登録するには以下のようにします。

$ concov -c <設定ファイル> register -d 20090101 /path/to/build/dir/

定期実行するには、以下のような chkbuild と concov を定期的に呼ぶスクリプトを書いてください。/home/mame/concov/update.rb においたものとします。

#!/usr/bin/ruby

# パスの設定
CHKBUILD_CMD = "/home/mame/concov/chkbuild/start-build"
BUILD_DIR = "/home/chkbuild/build/ruby-trunk-coverage/"
CONCOV_CMD = "/home/mame/concov/concov/bin/concov"
CONCOV_CONF_PATH = "/home/mame/concov/concov/concov.conf"

date = ARGV[0] || Time.now.strftime("%Y%m%d")
build_dir = BUILD_DIR + date + "T000000"

# 今日の 0 時 0 分時点の ruby ソースコードを chkbuild する
result = system(CHKBUILD_CMD, "build", "--date", date)
exit 1 unless result

# build ディレクトリで gcov を走らせ、.gcov ファイルを生成する
pwd = File.join(build_dir, "ruby")
open(File.join(pwd, "gcov.log"), "w") do |log|
  $stdout.reopen(log)
  $stderr.reopen(log)
  Dir.chdir(pwd)
  Dir.glob("**/*.gcda") do |path|
    dir, path = path[/\Aenc/] ? [".", path] : File.split(path)
    Dir.chdir(File.join(pwd, dir))
    system("gcov", "-l", "-p", "-o", File.dirname(path), path)
  end
end

# concov に .gcov や .rbcov を回収・データベースに登録させる
system(CONCOV_CMD, "-c", CONCOV_CONF_PATH, "register", "-d", date, build_dir)

このスクリプトを chkbuild 権限で cron などで定期的に実行させてください。

すぐにテストしたければ

$ sudo -u chkbuild /home/mame/concov/update.rb

として実行します (1 時間くらいかかります) 。
crontab に登録する場合は、

$ sudo crontab -u chkbuild -e

とし、

33 3 * * * /home/mame/concov/update.rb

などと設定すれば、ビルドとカバレッジ測定が毎晩実行され、concov の表示が勝手に更新されるはずです。

備考

非常に面倒くさくてごめんなさい。そのうち改良したいです。あとこの手順は今のところ自分でしか試していないので、うまくいった場合でもうまくいかなかった場合でも、報告していただけると助かります。
ruby 以外でも動くように作っているつもりですが、ruby 以外への適用についてはまだ試したことがないので、そのうち何かでやってみたいと思います (とりあえずは concov 自身とか) 。
ついでに、chkbuild の設定失敗や concov のバグなどによって何らかの不利益が生じた場合でも、私は責任をとりません (とれません) のでご承知おきください。念のため。


追記: 書き忘れがありました。start-build では load "sample/build-ruby-coverage" をしてください。本文は修正済みです。znz さん (地雷踏んでくれて) ありがとう!