Composerを使った簡単Travis CI設定

これは PHP Advent Calendar 2013 - Qiita [キータ] の5日目の記事です。

みなさんこんにちは。fivestarことクロコスの小川です。

Composerを使うと簡単に依存ライブラリを管理することが可能です。Composer とはなんぞや、という方は下記の記事あたりに目を通してみてください。

Composerを活用したモダンな開発手法をPHPカンファレンス2013で発表してきた。 #phpcon2013 | Engine Yard Blog JP

Composerでは例えば次のようにcomposer.jsonファイルを書くことで依存ライブラリを指定できます。この例だとFacebookPHP SDKが使えるようになります。

{
    "require": {
        "facebook/php-sdk": "dev-master"
    }
}

Composerとオートロード

Composerを使うポイントの1つに、オートロードが自動設定される点があります。つまり、requireを書いたり、spl_autoload_register()を書いたりすることなくライブラリのクラスが呼び出せるようになる、ということです。Composerを使ってライブラリをインストールするとvendor/autoload.phpというファイルが自動的に作られるので、それを読み込むだけで外部ライブラリのオートロードが有効になります。シンプルですね。

なので、テストの際もphpunit.xmlにvendor/autoload.phpを読み込むように記述しておけば、オートロードが有効になった状態でテスト可能です。

<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./vendor/autoload.php" colors="true">
  <testsuites>
    <testsuite name="hogeee">
      <directory suffix="Test.php">./Tests</directory>
    </testsuite>
  </testsuites>

  <filter>
    <whitelist>
      <directory>./</directory>
      <exclude>
        <directory>./vendor</directory>
      </exclude>
    </whitelist>
  </filter>
</phpunit>

従来であれば、各ライブラリがオートロードの仕組みを独自で実装していたのですが、Composerがオートロードの仕組みも含めて管理してくれるため、利用者は1ファイル読み込めばよくなり、すごく楽になっています。

require-dev

Composerを使うと、開発時のみに読み込みたいライブラリの指定も可能です。それはcomposer.jsonにて次のように指定します。"require-dev" というのがそれです。

{
    "require": {
        "facebook/php-sdk": "dev-master"
    },
    "require-dev": {
        "phpunit/phpunit": "3.7.*",
        "phake/phake": "2.0.*@dev",
        "piece/stagehand-testrunner": "3.6.*"
    }
}

この例だとPHPUnit、Phake、Stagehand_TestRunnerを開発時のみインストールする、という指定です。このようなテスティングツール系は運用時には基本的に不要なので、require-devに含めておくのがよいです。

なお開発時のみ、という判定はインストール時に--devオプションを指定することで行います。

% php composer.phar install --dev

(追記) --dev がデフォルトでつくようになっていたらしい。今は逆に、require-devを含めたくない場合に--no-devつけろってことでした。 @hidenorigoto @brtriver ご指摘ありがとうございます!

Composer: Installing require-dev by default

Composer: Installing require-dev by default - Jordi Boggiano

参考までに、僕が作っているCrocosSecurityBundle というライブラリは次のようにrequire、require-devを設定しています。

{
    ...
    "require": {
        "php": ">=5.4.0",
        "symfony/framework-bundle": "2.3.*@dev",
        "symfony/http-foundation": "2.3.*@dev",
        "doctrine/common": "2.2.*"
    },
    "require-dev": {
        "symfony/config": "2.3.*@dev",
        "symfony/dependency-injection": "2.3.*@dev",
        "symfony/doctrine-bridge": "2.3.*@dev",
        "symfony/event-dispatcher": "2.3.*@dev",
        "symfony/http-kernel": "2.3.*@dev",
        "doctrine/orm": ">=2.2.3,<2.4-dev",
        "facebook/php-sdk": "dev-master",
        "phake/phake": "2.0.*@dev"
    },
    ...
}

そもそもこのライブラリはSymfonyのバンドルっていう、まあプラグインみたいなもので、基本的にSymfonyに組み込んで使うものなので、Symfonyがあればいいんです。とはいえ開発時にはテストをする必要があります。いちいちSymfonyに組み込んでテストするのも大掛かりで煩わしいので、Symfonyの中で使っているコンポーネントをrequire-devに入れておいて、Symfonyに組み込まなくても自力で依存しているSymfonyコンポーネントをインストールしてテストできるようにしています。

その他にも、Doctrine ORMやFacebook PHP SDKと連携する仕組みも提供していて、これは使いたい人だけ使えよっていう機能なの該当のライブラリはrequireに入れていないのですが、やはりテストは書いておきたいのでrequire-devに指定しています。

あ、ちなみにCrocosSecurityBundleはid:Yudoufuの協力もあってSymfony2.3にようやく対応しました。ゆどうふありがとう。

Travis CI

Travis CIはGitHubのリポジトリをCIするためのサービスで、ご存知の方も多いかと思います。

こういうやつです。
f:id:Fivestar:20131205124618p:plain

サービスフック設定をして、リポジトリに.travis.ymlを入れておくと、自動的にテストをしてくれるやつです。インストール方法はGetting startedをみればわかるっていうか画面をポチポチしてればほとんどやってくれちゃうのでまあやってみればよいです。

f:id:Fivestar:20131206125740p:plain

Travis CIではcomposerがプレインストールされているため、.travis.ymlに次のように書くだけで、自動的にライブラリをインストールしてPHPUnitを実行してくれるようになります。(オートロードはphpunit.xml.distで設定している前提です)

language: php

before_script:
    - composer install --dev

php:
  - 5.4
  - 5.5

Packagist

おまけ。Packagistっていうのは、Composerでインストールできるライブラリのリポジトリです。こいつもGitHubと連携していて、GitHubにあるリポジトリを簡単に登録することができます。せっかくなので、登録方法を簡単に紹介します。

Travis CIは設定を.travis.ymlに書きましたが、Composerはcomposer.jsonにライブラリの説明などを記述します。CrocosSecurityBundleだったら下記みたいに書いています。

{
    "name": "crocos/security-bundle",
    "description": "This bundle provides a way to configure security with annotations",
    "keywords": ["annotations","security","authentication","authorization"],
    "type": "symfony-bundle",
    "homepage": "https://github.com/crocos/CrocosSecurityBundle",
    "license": "MIT",
    "authors": [
        {
            "name": "OGAWA Katsuhiro",
            "email": "ogawa@crocos.co.jp"
        }
    ],
    ...
}

簡単に説明しておくと、下記のような内容を書いておきます。

  • name: パッケージの名称。ベンダー名/ライブラリ名 形式
  • description: 説明
  • keyword: タグを配列で指定
  • type: だいたい "library"
  • homepage: Webサイト。なかったらGitHubのURLでいいと思います


何かいていいかわからなかったら、Composerのリポジトリブラウザで適当に同じようなやつ探してまねればいいと思います。

で、とりあえず書き終わったら次のコマンドでチェック。is validとでれば大丈夫らしいです。

% php composer.phar validate
./composer.json is valid

そこまでできたらGitHubにpushして、あとはPackagistにGitHubのリポジトリを登録します。Packagist内でそこら中にある「Submit Package
Packagist」をおして登録画面にいき、リポジトリのURLを登録します。登録したときのこと忘れたんですが、HTTPSで登録した気がします。 (https://github.com/xxx/xxx.git)

あとはcomposer.jsonを勝手にみてうまいことやってくれます。

https://packagist.org/packages/crocos/security-bundle

で、Travis CIと同様、Packagistもサービスフックを設定することで、pushするたびにPackagistの情報も自動更新されるようになります。登録したGitHubリポジトリのSettingsからService Hooksを開き、Packagistを選んでAPI Tokenの登録をします。API TokenはPackagistのマイページ(右上のユーザ名のリンク)からYour API Tokenのところにあります。

f:id:Fivestar:20131205124707p:plain


さてさて、たいした内容ではありませんでしたが今回はここまで。Composer関連はその辺のPHPライブラリのcomposer.jsonみればいろいろヒントが書いてあるので、いっぱい探してみましょう。

次は @hidenorigoto さんのMVCの記事ですね。楽しみですね。

追記:

実装の問題としてクラスの関係がどうだとか、どことどこに関連があるのが正しい/間違いだとかいうレベルのことではないのです。ソフトウェアがどういう構成になっていればよいのかを抽象的に示したものなのです。

PHPメンターズ -> Beyond MVC

期待通り、すばらしい記事でした。