アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

symfony/lime + phpUnderControl を使ってみる

こんにちは、亀本です。アシアルも技術者の人数がそこそこ増えてきて、技術ブログの当番が回ってくるまで日数がかかるようになったためか、久方ぶりのブログです。

さてさて、今回はちょっとツール使う系の話です。
ちょっと前にPHP勉強会で「phpUnderControl」というツールの事が話題に上がっていたのを見たのですが、これが個人的にはなかなか惹かれるツールでした。

phpUnderContorl とは

phpUnderControlとは、「継続インテグレーション」というアジャイル開発手法(厳密には、アジャイルで提唱されたというより昔からあった概念のようです)を実現するための自動ビルド/テスト/開発支援ツールです。

PHPはビルドいらずのスクリプト言語なので、自動ビルドと言われても( ゚Д゚)ハァ?って感じですが、phpUnderControlは単純なビルドにとどまらず、色々な事をやってくれます。

・アプリケーションのリビジョン最新化(svn up)
・phpDocumenterによるAPIドキュメント生成
PHP_CodeSnifferでのコード標準のチェック
PHPUnitによるユニットテストとかcoverageとか

これらを自動的に行い、綺麗なWebインターフェースに表示してくれます。

これを知った時、あー、これはすごく便利だなー・・・symfonyでも使いたいなーと思っていたのですが、symfonyでやるならどうせならlimeを使ってやりたい。。。という考えが浮かんできました。

無論、symfonyにはsfPHPUnitPluginというPHPUnitを組み込むプラグインもあるので、phpUnderControl対応を軸に考える時はこっちを使ってあげる形がいいかな、という気もしますが、やはりsymfonyを使う以上、limeでのテストもちゃんと考えてあげた方がいいよね、ということで、symfony/limeでphpUnderControl利用する、というトライをしてみました。

phpUnderControl をsymfony/lime で使う

結論から言うと、PMDとCoverageは対応できていませんが、他の一通りはpluginを組み込ませたりすることで対応する事ができました。

必要だったのは、limeのテスト結果をxUnitが出力するXMLに整形して出力する対応でしたが、この機能自体は、symfonyのサイト内にsymfony 1.0用っぽいプラグインが置かれていた(放置?)ので、これを元にsymfony 1.2対応を行いました。

本当は対応したものをフィードバックしたいんですが、pluginのリポジトリツリーにも該当プラグインがないので(^^;
公開しちゃっていいのか。。。というのは迷いどころだったので、いったん自分のがわで作った部分だけ公開しておきます。
あとは、元のプラグインのlibから1枚コピーしてきて新しいプラグインのlibに配置するだけ。。。という状態です(READMEに書いてあります)。
http://blog.asial.co.jp/data/sgTest4CruisePlugin.tar.gz

ちなみに、上のような事情があるので、pearパッケージにはなってません。ただのtarballです。
これ、どうするかは作者にメールなりしつつ、今後どうしていくかを考えます(^^;

なお、元のプラグインの配置場所も再掲しておきます。
http://trac.symfony-project.org/wiki/HowToSaveLimeTestsInXUnitFormatAndIntegrateThemWithCruiseControl


(なお余談ですが、PHPUnit形式のXML出力は、lime 2.0では標準機能として採用される。。。っぽいです。現在limeのリポジトリbranchesの中にある2.0-experimentalのツリーでは、LimeTestクラス内にtoXML()メソッドというPHPUnit形式のXMLを構築するメソッドが実装されているので、そのうち利用可能になるのではないかと思います。)

方法

さて、それでは実際に対応方法を紹介していきます。

phpUnderContorlの導入方法ですが、これはid:miauさんのブログが非常に詳しいです。
http://d.hatena.ne.jp/miau/20090525/1243209286
http://d.hatena.ne.jp/miau/20090527/1243424606

ここでは、まとめ的に手順だけ紹介していきます。

CriuseControlの準備

まず最初に、ベースとなるJava + CruiseContorlをインストールします。

今回、自分はdebian環境を使いましたが、debianではsunのJavaパッケージが既に標準のdebパッケージとして提供しているので、


% sudo apt-get install sun-java6-jdk

とすれば必要な物がひと通り入ります。rpm系の方はsunのサイトからダウンロードしたりとか、色々な文章が世に出回っているのでそちらを参照して下さい。

CruiseContorlは、Sourcefogeでバイナリ版が提供されているので、それを使えば十分です。
http://cruisecontrol.sourceforge.net/download.html

これを適当な所に展開すれば、CruiseControlはインストール完了です。
今回は、


/data/cctest

と言うディレクトリに展開したという前提で説明していきます。

CruiseControlを起動するには、展開したディレクトリ直下にあるcruisecontorl.shを実行します。


% ./cruisecontorl.sh

気をつけるべき点は、起動時に環境変数の$JAVA_HOMEを呼び出して使う点です。
debianの場合だと、/usrを指定してやらないと、javaコマンドの呼び出しに失敗します。
exportするなり、cruisecontrol.shの中でJAVA_HOME=/usrを指定してやるなり、何かしらの対策処理は施しておきましょう。

phpUnderControl の準備

次に、phpUnderControlとそれに関連するるライブラリをインストールします。
phpUnderControl、および関連ライブラリは独自のpearチャンネル上で配布されているので、それらのチャンネルを登録したうえでpearコマンドでインストールします。



% sudo pear channel-discover components.ez.no
% sudo pear channel-discover pear.phpunit.de
% sudo pear install -alldeps phpunit/phpUnderControl-beta


これで必要なライブラリがひと通りインストール完了し、phpucというコマンドが使えるようになります。
pearでのインストールが終わったら、そのphpucコマンドを使ってCruiseControlにパッチを当て、phpUnderControl用の画面を生成します。



% phpuc install /data/cctest


以上で、phpUnderControlのインストールは完了です。

pluginのインストールとプロジェクトの設定

今回の対応用に使うpluginは、上述の説明の通り、pluginディレクトリで展開してからlibの中身を古いものから移植してきてください。

pluginごとsvnなどのリポジトリに入れてしまい、phpUnderControlにプロジェクトを作成します。
なお、今回はアプリケーションとしてsymfonyのサンプルであるjobeet(ただし、lib/vendro/symofnyを除いたもの)を使ってみました。

以下のようにしてjobeetという名のプロジェクトを生成します。


% phpuc project -j jobeet -v svn -x http://svn.example.com/svn/jobeet -s . /data/cctest


こうしてプロジェクトを生成すると、CruiseControl(/data/cctest)のprojectsディレクトリ以下にjobeetというプロジェクトが生成され、sourceがチェックアウトされます。また、/data/cctest直下のconfig.xmlへプロジェクトが追記されます。

プロジェクトが生成されたら、config.xmlとjobeetプロジェクトのbuild.xmlを以下のように編集します。

config.xml


<?xml version="1.0"?>
<cruisecontrol>
  <project name="jobeet" buildafterfailed="false">
    <listeners>
      <currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
    </listeners>
    <modificationset>
      <svn localWorkingCopy="/data/cruisecontrol/cruisecontrol-bin-2.8.2/projects/jobeet/source"/>
    </modificationset>
    <bootstrappers>
      <svnbootstrapper localWorkingCopy="/data/cctest/projects/jobeet/source"/>
    </bootstrappers>
    <schedule interval="300">
      <ant anthome="apache-ant-1.7.0" buildfile="projects/${project.name}/build.xml"/>
    </schedule>
    <log dir="logs/${project.name}">
      <merge dir="projects/${project.name}/build/logs/"/>
    </log>
    <publishers>
      <currentbuildstatuspublisher file="logs/${project.name}/buildstatus.txt"/>
      <artifactspublisher dir="projects/${project.name}/build/api" dest="artifacts/${project.name}" subdirectory="api"/>
      <execute command="phpuc graph logs/${project.name} artifacts/${project.name}"/>
    </publishers>
  </project>
</cruisecontrol>


まずconfig.xmlですが、ほとんどの部分は自動生成されていて変更の必要はなく、<publishers>要素の中のみ変更をします。
変更されているのは、<publishers>の中の<execute>タグが追加になっている点と、<artifactspublisher>の中のdest属性のディレクトリを、logsからartifactsに変更してある点です。

build.xml


<?xml version="1.0" encoding="UTF-8"?>
<project name="jobeet" default="build" basedir=".">
  <target name="build" depends="checkout,php-documentor,php-codesniffer,unit-test"/>
  <target name="checkout">
    <exec executable="svn" dir="${basedir}/source" failonerror="on">
      <arg line="up"/>
    </exec>
  </target>
  <target name="unit-test">
    <exec executable="php" dir="${basedir}/source" failonerror="on">
      <arg line="symfony test:all-cruise --log-dir=${basedir}/build/logs" />
    </exec>
  </target>
  <target name="php-documentor">
    <exec executable="phpdoc" dir="${basedir}/source" logerror="on">
      <arg line="--title '${ant.project.name}' -ue on -t ${basedir}/build/api -d . -tb '/usr/local/lib/php/data/phpUnderControl/data/phpdoc' -o HTML:Phpuc:phpuc"/>
    </exec>
  </target>
  <target name="php-codesniffer">
    <exec executable="phpcs" dir="${basedir}/source" output="${basedir}/build/logs/checkstyle.xml" error="/tmp/checkstyle.error.log">
      <arg line="--report=checkstyle --standard=PEAR ."/>
    </exec>
  </target>
</project>


次に、projects/jobeet以下のbuild.xmlですが、<target>要素としてunit-testを追記しています。また、その追加に伴って、一番上の<target name="build">のタグの中に、unit-testがビルド対象として加えてあります。


以上の設定が終われば、準備完了です。
あとは、CruiseContorlを起動すれば、


% ./cruisecontrol.sh

(時々Exceptionはいてたりもしますがw)そのまま一気にドキュメント生成やらテストの実行やらが行われます。

しばらく完了したら、http:// 「phpUnderControlのサーバ」:8080/cruisecontrol/
にアクセスしてjobeet プロジェクトを見ると、テスト結果等が見えるようになってるのがわかるかと思います。



coverageやPMDの機能はまだ利用できないものの、limeでテストを作成して行く際に継続インテグレーションを導入するには、基本的な機能は利用できるので、結構ちゃんと使えるんじゃないでしょうか。


追記:なお、本文に書き忘れていましたが。。。symfonyは、本体がとても巨大なため、へたにfreezeした状態でphpUnderControlと組み合わせると、phpDocumentorなどがメモリの使用量オーバーを起こしたりしてAPIドキュメントが正常に生成できなくなる場合があります。(memory_limit = 128Mでダメでした)
そのあたりも、気をつけましょう(^^;