darudaru

だるだるしてるエンジニア

Travis CIでcomposerのautoloadが効かずに悩んだ話

デザインパターンを学ぶために各デザインパターンのコードをPHPで書きつつ、勉強もかねてテストコードも書いているのですが。そのテストコードをCI環境で走らせてみようと思い、Travic CIを使おうとしたら、composerのautoloadがきかずにfatalエラーが出てかなり悩みました。Macのローカル環境だと大丈夫なのですが、Travis CIでテストを実行するとエラーが起きるという。

ちなみにTravis CIを選んだ理由は、Githubでバッジをつけてみたかったからです。

起きたエラー

autoloadが効かずにクラスが見つからないというエラーが出ていました。

PHP Fatal error: Class 'DesignPatterns\Src\Structural\Bridge\SmartphoneHeader' not found in /home/travis/build/kanoemon/php-design-pattern/tests/Structural/BridgeTest.php on line 11

原因

Travis CIはcase-sensitiveファイルシステムのため、大文字・小文字が区別されるらしく。 composerのautoloadはPSR-4で設定していたので、namespaceの区切りがそのままディレクトリの区切りと解釈されます。キャメルケースでnamespaceを定義しているのに、実際のディレクトリパスは小文字だったため、Travis CIはでクラスが見つからない状態となっていました。

解決策

namespaceとディレクトリの名称を大文字小文字を一致させること。

私の場合、ディレクトリパスが/src/Structural/~となっていたのですが、srcをキャメルケースにするのは嫌だったので、composerのautoloadの指定パスを変更しました。

{
    "require-dev": {
        "phpunit/phpunit": "5.5.*"
    },
    "autoload": {
        "psr-4": {
            "DesignPatterns\\" : "src/",
            "DesignPatternsTests\\" : "tests/"
        }
    }
}

namespaceも下記に変更しました。

<?php
namespace DesignPatterns\Structural\Bridge;

Mac OS Xのデフォはcase-insensitiveのため、ローカル環境だとエラーが起きなかったということでした。なるほど。