ソフトウェアの開発ではバグ管理とソースコード管理は必須のツールです。この二つのツールを連携させることで、作業を軽減させる方法を紹介します。
Tracの概要
ソフトウェアの開発においてバージョン管理システムと並ぶ重要なツールの一つとして、プロジェクトのタスクや不具合を管理、トラッキングするバグ管理システムがあります。バグトラッキングシステムや、イシュートラッキングシステムと呼ばれることもあります。最近では、バグ管理システムでタスクや不具合を管理するだけなく、作業の進捗管理や必要な情報の共有を行なうなど、コラボレーションツールとしての色合いを強めてきている傾向にあるようです。
バグ管理システムとしては、オープンソースのBugzillaが有名で、古くから使われてきました。最近注目を浴びているバグ管理システムの一つとして、Trac があります。TracはEdgewall Softwareが提供しているオープンソースのソフトウェアです。Tracはバグ管理だけでなく、Wikiによる情報の共有機能やSubversionとの連携機能を提供しており、これらの機能に対して細かな権限設定もできます。
Wikiを使うことで、プロジェクトのドキュメントや議事録、備忘録を簡単に作成、共有できます。必要な情報を一カ所に集中できるため、管理が容易になります。Tracでは、Wiki記法での記述が標準となっています。Wiki記法になじめない人は、htmlで記述することができます。しかし、Wiki記法はとてもシンプルな書式なので、慣れれば効率的に文書を作成できるようになります。
Subversionとの連携機能として、コミットログを閲覧、Webブラウザ経由でのリポジトリ参照、リビジョン間の相違点の閲覧ができます。また、Subversionへコミットすると同時に、関連したバグのステータスを変更できる機能があります。
Tracではロードマップというビューがあります。ロードマップはプロジェクトの計画管理や進捗管理に役立つ機能です。ロードマップは単なるマイルストーンのリストですが、マイルストーンごとに開発方針などの説明を設定できます。また、マイルストーンごとに対応するバグ(チケット)の数が表示され、未解決バグと解決済みバグの比率がマイルストーンの進捗インジケータに表示されます。これにより、プロジェクトの進捗状況が一目で分かります。
また、プラグインによる機能拡張が可能で、Trac Hacks ではサードパーティ製の様々なプラグインが提供されています。TracとEclipseを連携するもの、バグやWikiページにタグを設定するものなど有用なプラグインが100個以上集められています。
Tracの現在の安定版のバージョンは0.10.4ですが、既にRuby on Railsなど多くのオープンソースのプロジェクトで利用されています。NASAのバグ管理システムとしても利用されており、Tracのサポートを行なう企業もあります。また、筆者の勤務先でもTracを利用しています。利用しているユーザやサイトは、http://trac.edgewall.org/wiki/TracUsers から確認できます。また、次のバージョンの0.11もまもなくリリース予定です。0.11では、バグのステータスをカスタマイズできるようになるなど、多くの改良点があります。
Tracは非常に多くの機能を持っています。その中から今回は、TracとSubversionの連携を中心に説明します。
Tracのインストールと設定
Tracのインストール方法と基本的な設定を説明します。本格的にTracを導入するためには、ApacheやPython、関連するライブラリのインストールが必要です。Linux環境ではパッケージ管理が充実していため、比較的簡単に導入できます。一方、Windows環境で一からこれらのソフトウェア、ライブラリをインストールして、Tracの動作環境を整える作業は非常に煩雑になります。幸い、WindowsでもTracを簡単に導入するためのプロジェクトが進行しており、All-In-One Trac やTrac月 を使うことで、簡単に運用が始められます。All-In-One TracはTracのバージョン0.9を元に作られています。Trac月はバージョン0.10をベースにしています。両者とも、TracだけでなくSubversionやTracとSubversionとの連携機能も標準でインストールされます。Trac月の方が機能が充実しており開発も活発なため、これから導入する場合はTrac月をインストールすることをお勧めします。
サーバにはLinuxを使っている方が多いと思います。筆者の勤務先でも、ほとんどのサーバがLinuxで構成されています。また、バージョン管理システムとして既にSubversionを導入済みで、Tracはまだ導入していない方も多いと思います。ここでは、基本的なソフトウェア構成を学ぶと言う観点と、既存システムにインストールする場合を顧慮して、Ubuntu Linux 7.10を使ってTracのインストールと基本設定を行なう方法を説明します。また、SubversionサーバをApache経由で使用する方法も説明します。
まず、TracとApache、ApacheのSubversionとの連携モジュールとmod_pythonをインストールします。Tracは単体でもWebサーバの機能やCGIとして動作する機能を持っていますが、mod_pythonを使って運用する方がパフォーマンス面で優位です。これらのソフトウェア・モジュールをインストールするには、次のコマンドを実行します。
$ sudo aptitude install trac apache2 libapache2-svn libapache2-mod-python
次にリポジトリ上のソースコードをシンタックスハイライトするためのモジュールをインストールします。Trac 0.10では、シンタックスハイライトのために、SilverCityかenscriptモジュールを使用できます。enscriptはUbuntuのパッケージになっているので、ここではenscriptを使用します。SilverCityを使いたい場合は、ソースコードをダウンロードして、ビルド/インストールする必要があります。enscriptはSilverCityに比べて多くの言語に対応していますが、処理速度はSilverCityの方が優れています。SilverCityとenscript両方がインストールされている場合は、SilverCityが使われます。なお、次期バージョンのTrac 0.11からは、ソースコードハイライトにPygmentsが使われるようになります。
enscriptをインストールするには、次のコマンドを実行します。
$ sudo aptitude install enscript
これで、最低限必要なパッケージのインストールが完了です。次にSubversion用のリポジトリを準備します。前回は/tmp/myrepositoryにリポジトリを作成しました。今回は、/var/lib/svnにMyProjectと言うリポジトリを作成し直します。実行例でchownでオーナーをwww-dataに変更しているのは、このリポジトリをApacheのフロントエンドで運用するため、Apacheの実行ユーザでディレクトリに読み書きできる必要があるためです。
$ sudo mkdir /var/lib/svn
$ sudo svnadmin create /var/lib/svn/MyProject
$ sudo chown -R www-data /var/lib/svn/
Subversionのリポジトリを作成後、Trac用にディレクトリを準備して、Tracの環境を構築します。ここでは、/var/lib/tracディレクトリにMyProjectというプロジェクトを開始するように指定します。tracadminコマンド実行中に、Tracの環境へのパス、Tracのプロジェクト名、Subversionのリポジトリへのパスを指定しています。それ以外の項目はデフォルトのまま(リターンキーを押す)です。これらの項目は、初期設定後にも変更できます。
ここでも、最後にApacheの実行ユーザでディレクトリへの読み書きができるようにオーナーをwww-dataに変更しています。
$ sudo mkdir /var/lib/trac
$ sudo trac-admin /var/lib/trac/MyProject initenv
[中略]
Project Name [My Project]> My Project
[中略]
Database connection string [sqlite:db/trac.db]>
[中略]
Repository type [svn]>
[中略]
Path to repository [/path/to/repos]> /var/lib/svn/MyProject
[中略]
Templates directory [/usr/share/trac/templates]>
[中略]
Congratulations!
$ sudo chown -R www-data:www-data /var/lib/trac
Trac単体でもWebサーバの機能を持っているため、以上の操作でTracの起動はできます。今回は、ApacheをWebサーバとして動作する設定を行ないます。あわせて、SubversionのフロントエンドにApacheを設定します。
まず、ApacheのTracに対する設定を行います。/etc/apache2/sites-available/defaultの<VirtualHost *>の行と</VirtualHost>の行の間に次の設定を記述します。この設定では、http://ホスト名/tracで/var/lib/trac/MyProjectにアクセスできるようになります。/trac/loginでは/etc/apache2/svn.passwdファイルを使用して基本認証でログインできるようにしています。
<Location /trac>
SetHandler mod_python
PythonHandler trac.web.modpython_frontend
PythonOption TracEnv /var/lib/trac/MyProject
PythonOption TracUriRoot "/trac"
</Location>
<Location "/trac/login">
AuthType Basic
AuthName "My Project"
AuthUserFile /etc/apache2/svn.passwd
Require valid-user
</Location>
/trac以下すべてを基本認証で保護したい場合は、次のように設定してください。
<Location /trac>
SetHandler mod_python
PythonHandler trac.web.modpython_frontend
PythonOption TracEnv /var/lib/trac/MyProject
PythonOption TracUriRoot "/trac"
AuthType Basic
AuthName "My Project"
AuthUserFile /etc/apache2/svn.passwd
Require valid-user
</Location>
以上の設定を行って次のコマンドでApacheを再起動します。
$ sudo /etc/init.d/apache2 restart
ブラウザからhttp://ホスト名/tracにアクセスしてみてください。図1 のような画面が表示されれば成功です。
図1 Tracのインストール直後の画面
次にApacheとSubversionを連携します。/etc/apache2/mods-available/dav_svn.confを次のように記述します。この設定では、/var/lib/svnにあるリポジトリにhttp://ホスト名/svn/MyProjectでアクセスできるようになります。また、前回の記事ではコンソールからsvnコマンドを使ってリポジトリにアクセスする場合、「 svn checkout svn://localhost/」とアクセスしていました。Apacheをフロントエンドに配置することで、「 svn checkout http://localhost/svn/MyProject」のようにhttpでアクセスできるようになります。
<Location /svn>
DAV svn
SVNParentPath /var/lib/svn
AuthType Basic
AuthName "MyProject subversion repository"
AuthUserFile /etc/apache2/svn.passwd
</Location>
設定が終わったらApacheを再起動してください。
Apacheをフロントエンドに配置した場合のTracとSubversionの設定で、今回は基本認証のパスワードファイルに/etc/apache2/svn.passwdを指定しています。TracとSubversionで同じパスワードファイルを参照することで、ユーザ管理を統一することができます。また、Apacheをフロントエンドに配置することで、パスワードファルではなくLDAPによる認証などApacheの柔軟な設定、豊富な機能を活用できます。
次のコマンドでTrac、Subversionで使用するユーザとパスワードを設定します。ここでは、「 user1」というユーザを作成しています。
$ sudo htpasswd -cm /etc/apache2/svn.passwd user1
コマンドを実行するとパスワードの入力を求められますので、パスワードを指定してください。
最後に、次のコマンドを実行して、「 user1」をTracの管理者に設定します。
$ sudo trac-admin /var/lib/trac/MyProject permission user1 TRAC_ADMIN
TracとSubversionの連携
ここまで、TracとSubversionのApacheとの連携について説明しました。次に、TracとSubversionの連携について説明します。ここまでの設定で、既に次のことが可能になっています。
SubversionのリポジトリをTracのリポジトリブラウザから閲覧
Subversionの更新ログ、差分表示
Subversionの更新履歴(ログ)の検索
Subversionの更新履歴一覧の表示
Subversionのファイル、リビジョンとTracのWiki、チケットの相互リンク
SubversionのリポジトリをTracから見ると図2 のように表示されます。対応しているソースコードであれば、色分けされてハイライト表示されます。また、右上の「Revision Log」のリンクをクリックすると、履歴の一覧が表示され、特定のリビジョンのファイルを表示でき、リビジョン間の差分をハイライト表示することができます。また、更新履歴はTracのWikiやチケットと同様に全文検索対象となります。Tracを検索すればプロジェクトに必要な情報が得られるようになります。
図2 Tracのリポジトリビューワ
前回の記事 では、Subversionのフック機能を使ってコミットログをメール送信する設定を行ないました。昨今のメール事情として、大量のスパムと格闘する日々が続いていて、これ以上メールのインフラに頼りたくない人も多いかも知れません。TracではWikiやチケットの更新履歴だけでなく、Subversionの更新履歴もRSSとして配信できます。取得したRSSは現在お使いのRSSリーダで購読できます。
WikiやチケットにSubversionのファイルやリビジョンへのリンクを設定できます。反対に、コミットログからチケットへのリンクの設定もできます。このリンクを利用すれば、チケットを登録するときに問題のソースコードの場所を明示できます。筆者の勤務先では、バグ修正をSubversionにコミットするときに、該当チケットの番号を明記することで、チケットとコミットログに相互にリンクを張るようにしています。
チケットへのリンク設定
「#チケット番号」と書くことで、チケットへのリンクになります。「 ticket:チケット番号」と書くこともできます。「 comment:ticket:チケット番号:コメント番号」と書くことで、指定したチケットの特定のコメントへのリンクを作成できます。残念ながら筆者の勤務先では、誰もこのリンクを使っていません。チケット番号1のチケットへのリンクは次のように記述します。
#1
リポジトリへのリンク設定
Subversionのリポジトリ内のファイルへのリンクの記述方法は、「 source:ファイルへのパス」です。例えば、http://localhost/svn/MyProject/trunk/ReadMe.txtへのリンクは次のように記述します。
source:trunk/ReadMe.txt
Subversion内の特定のリビジョンのファイルへのリンクは、上の記述のあとに「@リビジョン番号」と記述します。リビジョン10のtrunk/ReadMe.txtへのリンクは次のようになります。
source:trunk/ReadMe.txt@10
特定のリビジョンの更新ログと差分を表示する場合は、「 rリビジョン番号」と記述します。「 changeset:リビジョン番号」と記述することもできます。リビジョン番号2の更新ログを表示する場合は、次のように記述します。
r2
リビジョン間やファイル間の更新履歴、差分表示をするリンクは少し複雑です。この他にも様々なリンクを作成することができます。詳細はオンラインマニュアルを参照してください。
Tracチケットの自動クローズ
開発サイクルの中では、バグを修正するとSubversionに適切なコメントと一緒にソースコードをコミットします。あわせて、対応するチケット(バグ)にも同じようなコメントを追加してチケットを閉じることが多いです。同じような作業を2回行なうことはプログラマの美徳に反します。同じことを2回繰り返さないために、TracにはSubversionのコミットと同時にチケットを自動的にクローズする機能があります。この処理は、Subversionのpost-commitで行ないます。
まず、Ubuntu Linuxでは、Tracのチケットの状態を変更するスクリプトが/usr/share/doc/trac/contrib/trac-post-commit-hook.gzにあります。これを展開します。
$ sudo gunzip /usr/share/doc/trac/contrib/trac-post-commit-hook.gz
次にSubversionのリポジトリのpost-commitを編集します。/var/lib/svn/MyProject/hooks/post-commitは次のようになります。
#!/bin/sh
REPOS="$1"
REV="$2"
export LANG=ja_JP.UTF-8
LOG=`/usr/bin/svnlook log -r $REV $REPOS`
AUTHOR=`/usr/bin/svnlook author -r $REV $REPOS`
TRAC_ENV='/var/lib/trac/MyProject'
TRAC_URL='http://localhost/trac'
/usr/bin/python /usr/share/doc/trac/contrib/trac-post-commit-hook \
-p "$TRAC_ENV" \
-r "$REV" \
-u "$AUTHOR" \
-m "$LOG" \
-s "$TRAC_URL"
ファイルを編集後、ファイルのオーナーを変更して実行権限を与えます。
$ sudo chown www-data /var/lib/svn/MyProject/hooks/post-commit
$ sudo chmod u+x /var/lib/svn/MyProject/hooks/post-commit
これで準備ができました。Subversionへのコミット時のログを所定の書式で記述すれば、チケットの状態を変更できます。書式は単純で次のようになっています。
command #チケット番号
command #チケット番号, #チケット番号
command #チケット番号 & #チケット番号
command #チケット番号 and #チケット番号
コマンドは次の2種類あります。
チケットを閉じる : fixes, closes
チケットにコメントを追加 : references, refs, addresses, re
チケットを閉じる場合は、次のようにコミットログを記述します。
typoでした。 fixes #10
チケットにコメントを追加する場合は、次のようにコミットログを記述します。
この修正を試してみてください。 refs #10
また、複数のチケットを同時に閉じて、別の関連バグにコメントを追加できます。
typoでした。 refs #5 はこのバグに関連しているかも知れません。 Fixes #10, #20
これで、チケット番号10と20のチケットは自動的に閉じて、チケット番号5のチケットにはコメントが追加されます。
他のBTSからTracへの移行
/usr/share/doc/trac/contribのディレクトリの下には、trac-post-commit-hook以外に複数のスクリプトがあります。bugzilla2trac.pyはbugzillaからTracへの移行ツールです。sourceforge2trac.pyはSourceForgeのBTSをTracに移行できます。http://trac.edgewall.org/wiki/TracImport には、他のBTSからTracへ移行する方法がまとめられています。ただし、バージョンの違いによりスクリプトがそのままでは動作しないことがあります。また、独自のフィールドの追加などカスタマイズを行なっている場合、すべてのデータがインポートできないケースがあります。移行スクリプトはTracと同様にPythonで書かれており、比較的読み易いコードになっているため手を入れるのはそれほど難しくありません。もし、データのインポートがうまくいかない場合は、これを機会にPythonに挑戦してみてはどうでしょうか?
他のBTSとSubversion
Tracの登場以降、他のバグトラッキングシステムでもバージョン管理システムとの連携が活発に行なわれるようになりました。オープンソースのBTSの代表的存在だったBugzillaも周辺環境と組み合わせることで連携することができます(http://sean-janus.optionpc.com/me/software/bugtraq/ やhttp://oss.segetech.com/bugzilla-svn-wiki.html ) 。
筆者の勤務先では以前、Mantis を使っていました。当初はバージョン管理システムとの連携はプラグインとして提供されていましたが、Version1.1(まもなくリリースされます)からは標準機能として提供されるようです。また、バージョン管理システムとの統合以外にもレポート機能など非常に機能が豊富です。プラグインの仕組みにより、さらに機能も拡張できます。