Phingのインストールガイドや簡単な紹介記事は見かけますが、日本語のドキュメントはまだ少ないです。
そこで、よく使いそうな設定やタスクをメインに紹介しようと思います。
なお、Phingのインストール方法についてはよく紹介されているので割愛します。
Phingとは
Phingとは、PHP向けのビルドツールです。
Phingを使うことによってテストや解析などを一元管理し、コマンド一発で実行できるようになります。
まだイメージがつかないでしょうか。
例えば、あるプログラムファイルを修正するとします。修正後、関係するテストを実行、ついでにPHPMDも実行・・・などをしようとすると
$ phpunit tests/foo/bar.php
$ phpunit tests/foo/bar/baz.php
$ phpmd foo.php xml ruleset.xml
$ phpcpd --min-lines 5 --min-tokens 5 foo/bar.php
...
などとたくさんのコマンドを実行する必要があります。
ところが、Phingを導入していると以下のコマンド一発で上記の全てをやってくれるのです。
$ phing build
とても簡単になりましたね。
また、設定ファイルをバージョン管理することによってみんなで共有できるので、人によってテスト内容に差異が出ません。
Phingの実行方法
build.xmlの生成
Phingで実行したい内容はbuild.xmlというビルドファイルに記述します。
難しいものではないので、例を見たほうが早いでしょう。
<?xml version="1.0" encoding="UTF-8"?>
<project name="プロジェクト名" default="dist">
<property name="outputDir" value="./result/" override="false"/>
<!-- 初期設定 -->
<target name="prepare">
<echo msg="初期設定" />
<mkdir dir="./build" />
</target>
<target name="phpmd">
<phpmd rulesets="ruleset.xml">
<!-- 対象ディレクトリをmain下に設定 -->
<fileset dir="/main">
<!-- phpファイルのみを対象にする -->
<include name="**/*.php" />
<!-- vendorsディレクトリ下を対象外にする -->
<exclude name="vendors/" />
</fileset>
<!-- 結果をXMLでphpmd.xmlとして出力 -->
<formatter type="xml" outfile="${outputDir}/phpmd.xml" />
</phpmd>
</target>
<target name="phpunit">
<phpunit codecoverage="false" bootstrap="bootstrap.php">
<batchtest>
<fileset dir="/main" >
<include name="**/*Test.php" />
<exclude name="vendors/" />
</fileset>
</batchtest>
<formatter type="xml" outfile="${outputDir}/phpunit.xml"/>
</phpunit>
</target>
<target name="build" depends="prepare, phpmd, phpunit" />
</project>
なるほど。phpmdとphpunitが実行される指定です。さらに、初期設定も行っているようですね。
Phingの実行
build.xmlを記述したら、あとはPhingコマンドを実行するだけです。
実行コマンドは以下。
phing <オプション> -buildfile <build.xmlのパス> <ターゲット>
phing -DoutputDir=./result/ -buildfile ./test/build.xml phpmd
<build.xmlのパス>
は指定しない場合、デフォルトでbuild.xml
を見に行きます。
<ターゲット>
はどのタスクを実行するかを指定できます。デフォルトでbuild
という名前のターゲットを実行します。詳しくは後ほど説明しましょう。
オプション
ついでにPhingコマンドのオプションを紹介しておきましょう。
よく使うオプションは以下。
-
-l -list
ビルドファイルで実行されるターゲットの一覧が見られます。 -
-D<property>=<value>
プロパティを指定できます。ここで指定したプロパティはbuild.xml内で使用できます。 -
-buildfile
ビルドファイルを指定します。デフォルトはbuild.xml
です。
その他のオプション。
-
-h -help
ヘルプが見られます。 -
-v -version
Phingのバージョンが確認できます。 -
-propertyfile <file>
プロパティをファイルからロードします。 -
-debug
デバッグ出力できます。 -
-q -quiet
指定するとビルド実行時に何も出力しません。 -
-verbose
ビルド実行の詳細な内容を出力します。 -
-logfile <file>
ビルド実行のログ出力先を指定します。 -
-logger path.to.Logger
ロガーを指定します。デフォルトはphing.listener.AnsiColorLoggerです。 - その他のロガーは phing.listener.NoBannerLogger, phing.listener.DefaultLogger, phing.listener.XmlLogger, phing.listener.TargetLogger, phing.listener.HtmlColorLogger があります。
メインのタグとその属性の説明
project
projectは1つのbuild.xmlに必ず1つでなければなりません。
projectタグの中に実行したいタスクを記述していきます。
また、default
でPhing実行時にターゲットが指定されていなかった場合に実行するタスクを指定できます。
<project name="mainProject" default="main" >
上記のように書くと、何も指定せずPhingを実行した場合はmainと名前のつけられたタスクが実行されます。
target
targetタグの中には、実行したいタスクをまとめて書いておくことが出来ます。
targetにはname
を指定します。こうすることによって、Phingを実行する際に特定のタスクだけ実行したり、実行する順番を指定できたりします。
これは最初のbuild.xmlの例を見るとイメージしやすいでしょう。
depends
を指定すると他のtargetに依存させることが出来ます(カンマ区切りで複数指定可能)。便利ですが、この指定の仕方が勘違いしやすいところなので注意しましょう。
例えば、以下の例を見てみます。
<target name="a" />
<target name="b" depends="a" />
これを見ると b が実行された後に a が実行されるかと思うのでしょうが、逆です。b は a に"依存"しているので、a が実行された後に b が実行されるのです。複数指定になるともっと複雑になるので注意しましょう。
property
プロパティ(変数的なもの)を設定できます。例えば、以下をご覧ください。
<property name="outputDir" value="./result/" override="false"/>
outputDirというプロパティに「./result」を代入しています。
そうするとのちの記述で
<formatter type="xml" outfile="${outputDir}/phpunit.xml"/>
のようにして使用することが出来るのです。
結果ファイルの出力先を固定したり、設定値を持つのに便利ですね。
また、Phingは実行時にパラメータを受け取れるので、そのパラメータの初期値として設定しておくのも良いかもしれません。
phing build -DoutputDir=./result
ちなみに、override="true"
を指定しておくと、外から何を指定しようがbuild.xmlの記述でオーバーライドされます。逆にoverride="true"
を指定すると外からパラメータを指定した場合はそれが使用されます。
実行対象ファイルの絞り込みに使うタグ
タスクの実行対象のファイルを絞り込む時に使うタグを紹介します。
fileset
対象のファイル・ディレクトリを指定することが出来ます。
dir
でディレクトリを指定でき、include
で対象ファイルを指定、exclude
で非対象ファイルを指定できます。
ファイル指定は*
(アスタリスク)が使用できます。また、**
で全てのディレクトリを対象に出来ます。
<!-- 対象ディレクトリをmain下に設定 -->
<fileset dir="/main">
<!-- 全てのphpファイルのみを対象にする -->
<include name="**/*.php" />
<!-- vendorsディレクトリ下を対象外にする -->
<exclude name="vendors/" />
</fileset>
filelist
対象ファイルのリスト形式で指定できます。
dir
で対象のディレクトリを指定し、files
やfilelist
で実際にファイルを指定します。
files
では、単なるファイルのリストを羅列して指定できます。
<filelist dir="/conf" files="foo.conf,bar.conf,baz.conf"/>
ファイルの羅列をbuild.xmlに書くのが嫌な場合は、別ファイルにして読み込ませることも出来ます。
その場合はlistfile
にそのリストを羅列したファイルを以下のように指定します。
<filelist dir="conf/" listfile="conf/file_list.txt"/>
オプションタスク
さて、続いてはオプションタスクです。
"オプション"と言いますが、実際メインで使いたいのはこれでしょう。phpunit、phpmd、phpcpd等、テスト系のタスクが実行できます。
書くのが疲れてきたので代表的なもののリンクを貼っておきます。
あとでまた書きます
phpunit
phpmd
phpcpd
phplint
その他、よく使う基本的なタスク
ちょっと凝ったビルド設定を書かなければいけない時は以下のタスクが役に立ちそうです。
echo
メッセージを出力します。ビルドの開始メッセージや、デバッグなどに使えますね。
シンプルな書き方は2パターン。
<echo message="ビルド開始" />
<echo>ビルド終了</echo>
if
if文が使えます。
環境やフラグによって条件分岐できるのは便利ですね。<elseif>
も使えます。
<if>
<istrue value="${success}" />
<then>
<echo message="build success" />
</then>
<else>
<echo message="build failur" />
</else>
</if>
条件指定は例えば以下のものがあります。
<equals arg1="${foo}" arg2="test" />
<istrue value="${flag}" />
<isfalse value="${flag}" />
<isset value="${dir}" />
condition
ifタスクでは1つの条件しか判定できませんが、複雑な条件で何かを判定したい場合にはconditionタスクを使用します。
<condition property="isLocal">
<equals arg1="${env}" arg2="local" />
<socket server="localhost" port="80" />
</condition>
こうすると、isLocalというプロパティに結果が格納されます。
条件にどんな指定が出来るかはドキュメントをご覧ください。
http://www.phing.info/docs/guide/trunk/ch05s08.html
delete
ファイルの削除が出来ます。
テストによって作られたテンポラリファイルを削除するのに使ったりとかしますね。
quiet
をtrueにすると、タスクが失敗してもエラーと判定しません。
verbose
をtrueにしておくと、タスクが失敗した場合に詳細なエラーメッセージを出してくれます。
<delete file="/tmp/foo.bar" />
ディレクトリごと削除したい場合はこう。
<delete dir="/tmp/darl" includeemptydirs="true" verbose="true" failonerror="true" />
copy
ファイルのコピーが出来ます。
file
でコピー元を指定、tofile
でコピー先を指定します。また、overwrite="true"
でファイルを上書きします。
<copy file="somefile.txt" tofile="/tmp/anotherfile.bak" overwrite="true"/>
あるディレクトリにいろんなファイルをコピーしたいときは以下のように指定します。
<!-- /backupディレクトリにconfとiniファイルをコピーする -->
<copy todir="/backup">
<fileset dir=".">
<include name="**/*.conf" />
<include name="**/*.ini" />
</fileset>
</copy>
chmod
chmodがかけられます。
deleteタスクと同様にquiet
とverbose
が指定できます。
<chmod file="/home/test/mine.txt" mode="0500" verbose="true" />
loadfile
ファイルを読み込んでプロパティにセットすることが出来ます。
環境変数や設定値を切り出しておいて読み込むとか。
<loadfile property="version" file="version.txt"/>
php
最後の力技手段。phpを直接実行できます。
<php expression="echo 'test';">
その他
composerインストールしたパッケージが使える
phingで実行するphpunitやphpmdは通常pearでインストールされたパッケージが使われますが、composerインストールしたphpunitやphpmdを使うことも出来ます。
その場合は特にbuild.xmlに記述を増やす必要はなく、同じくcomposerインストールしたPhingを指定して実行したらautoload.phpが呼ばれて自動的に解決してくれます。
./vendors/bin/phing -DoutputDir=./result/ -buildfile ./test/build.xml phpmd
Phingが定義した変数が使える
実行ホストのOSバージョンを取得したり、環境変数を取得できたりします。
環境によって切り替えたいものがある場合は重宝しそうです。
http://www.phing.info/docs/guide/stable/apa.html
PhingのJenkinsプラグインがある
PhingはJenkinsプラグインがあるので、連携するとかなり強力になります。
GitにマージされたらJenkins経由でPhingを実行し、結果を画面に出力・・・なんてことも簡単にできます。