PHP 用の CI 設定のまとめ。

PHP コードのコーディング規約をチェックすることにした って記事を書いたので、ついでに現在の PHP 用 CI 環境を晒してみる。

と言っても、ほとんどが yamashiro 先生のPHPでTDD&CIワークショップ、Jenkins + PHP の各種プラグインパート資料がベースなので、
そっちを読んだほうがいいと思います。

使ってるツール

  • composer
    • 依存パッケージをインストールする。昨日使い始めた。
  • phing
    • ビルドツール。各種コマンドをまとめておくために利用。
  • PHPUnit
  • PHPMD
    • コードチェッカー。PHP のダメなコードを探してくれるツール。
  • PHPCPD
    • コピペ検出ツール。重複コードを探してくれるツール。
  • PHP_CodeSniffer
    • コーディング規約チェッカー。

インストールする

この composer.json を使ってます。

{
    "require-dev": {
        "phing/phing": "*",
        "phpunit/phpunit": "*",
        "phpmd/phpmd": "*",
        "sebastian/phpcpd": "*",
        "squizlabs/php_codesniffer": "*"
    },
    "config": {
        "bin-dir" : "bin/"
    }
}

CI 用ツールしか入れてません。アプリ本体はなんにも依存していません、はい。

build.xml

こいつを使うと phing を実行するだけで PHPMD, PHPCPD, PHP_CodeSniffer, PHPUnit をまとめて実行してくれます。

<?xml version="1.0" encoding="utf-8" ?>
<project name="foo_project" basedir="." default="all">
  <property name="outputDir" value="_build"/>
  <property name="targetDir" value="src"/>

  <target name="phpcpd">
    <mkdir dir="${outputDir}" />
    <phpcpd minTokens="10">
      <fileset dir="${targetDir}">
        <include name="**/**/*.php"/>
      </fileset>
      <formatter type="pmd"
                 outfile="${outputDir}/cpd.xml"/>
    </phpcpd>
  </target>

  <target name="phpmd">
    <mkdir dir="${outputDir}" />
    <phpmd rulesets="tests/etc/ruleset.xml">
      <fileset dir="${targetDir}">
        <exclude name="exclude.php"/>
      </fileset>
      <formatter type="xml"
                 outfile="${outputDir}/pmd.xml"/>
    </phpmd>
  </target>

  <target name="phpcs" description="Generate phpcs.xml using PHP_CodeSniffer" >
    <mkdir dir="${outputDir}" />
    <phpcodesniffer standard="PSR2" file="${targetDir}/" allowedFileExtensions="php" >
      <formatter type="checkstyle"
                 outfile="${outputDir}/phpcs.xml"/>
    </phpcodesniffer>
  </target>

  <target name="phpunit">
    <mkdir dir="${outputDir}" />
    <mkdir dir="${outputDir}/coverage" />
    <exec command="phpunit -c tests/etc/phpunit_config.xml" logoutput="true" />
  </target>

  <target name="all" depends="phpcpd,phpmd,phpcs,phpunit">
  </target>
</project>

phpunit の設定ファイルを tests/etc/phpunit_config.xml においてある。

<phpunit>
  <testsuites>
    <testsuite name="Test">
      <directory>../</directory>
    </testsuite>
  </testsuites>
  <filter>
    <whitelist>
      <directory suffix=".php">../../src/</directory>
    </whitelist>
    <blacklist>
      <directory suffix=".php">../../vendor</directory>
    </blacklist>
  </filter>
  <logging>
    <log type="junit" target="../../_build/phpunit.xml" />
    <log type="coverage-html" target="../../_build/coverage/" charset="UTF-8"
         yui="true" highlight="true" lowUpperBound="35" highLowerBound="70" />
    <log type="coverage-clover" target="../../_build/clover.xml" />
  </logging>
</phpunit>

あと PHPMD 用の設定ファイル、tests/etc/ruleset.xml

<?xml version="1.0"?>
<ruleset name="Hyper mANAGE PHPMD ruleset"
         xmlns="http://pmd.sf.net/ruleset/1.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
                             http://pmd.sf.net/ruleset_xml_schema.xsd"
         xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
  <rule ref="rulesets/codesize.xml" />
  <rule ref="rulesets/design.xml" />
  <rule ref="rulesets/naming.xml">
    <exclude name="ShortVariable" />
    <exclude name="LongVariable" />
  </rule>
  <rule ref="rulesets/unusedcode.xml" />
</ruleset>

Jenkins 側の設定

次のプラグインを使っています。

  • DRY Plugin
    • CheckStyle Plug-in
    • PMD Plug-in
    • Duplicate Code Scanner Plug-in
    • Task Scanner Plug-in
  • Jenkins Clover PHP plugin

設定は各ツールが生成した XML を食わせるだけなので割愛します。