PHP
JSON
Composer

PHPのComposerでコマンドを定義したら開発がすごく便利でした

はじめに

チーム開発を行う際に、よく使うコマンドをComposerにまとめました。
こうすることでフレームワークで使う「あのコマンドってどうだっけ?」というのを共有しやすくなりました。

書き方

基本的な書き方としては、scripts[command]でアクセスできる箇所に配列で列挙していきます。
例えばcomposer testcomposer test-phpcsというコマンドを発行したい場合には下記のように書きます。

composer.json
{
  "scripts": {
    "test": [
      "composer test-phpcs",
    ]
  }
}

この配列には複数のコマンドを書くことが出来ます。

composer.json
{
  "scripts": {
    "test": [
      "composer test-phpcs",
      "composer test-behat",
    ]
  }
}

またComposerから他のComposerのサブコマンドを呼び出す場合、コマンド名に@をつけることで省略可できます。
@mosa7さん指摘ありがとうございます!)

composer.json
{
  "scripts": {
    "test": [
      "@test-phpcs",
      "@test-behat",
    ]
  }
}

ちなみにこのケースではComposerでComposerのコマンドを呼んでいるので、無限ループにならないように気をつける必要があります。

予約キーワード

Composerでは特定のscriptsが定義されています。
これらのScriptsをcomposer.jsonで定義することで、特定のタイミングで呼ばれるコマンドになります。

コマンド名 呼び出される条件
post-install-cmd installの前。
pre-update-cmd updateの前。
post-update-cmd updateの後。
post-status-cmd statusの後。
pre-archive-cmd archiveの前。
post-archive-cmd archiveの後。
pre-autoload-dump install / update中のdump-autoloadの前。
post-autoload-dump install / update中のdump-autoloadの後。
post-root-package-install create-project中にあるルートパッケージのインストール後。
post-create-project-cmd create-projectの後。
pre-dependencies-solving 依存が解決される前。
post-dependencies-solving 依存が解決された後。
pre-package-install パッケージのインストール前
post-package-install パッケージのインストール後
pre-package-update パッケージのアップデート前
post-package-update パッケージのアップデート後
pre-package-uninstall パッケージのアンインストール前
post-package-uninstall パッケージのアンインストール後
init composerインスタンスが初期化された後
command composerコマンドが実行される前。
pre-file-download ファイルダウンロードの前。

正しいマニュアルについてはこちらを参考にしてください。

https://getcomposer.org/doc/articles/scripts.md#command-events

例えばcomposer updateの後に独自で定義した初期化系のコマンドを実行したい場合いにはこのように書きます。

composer.json
{
  "scripts": {
    "post-update-cmd": [
      "@set-wp-content",
      "@init-phpcs"
    ]
  }
}

https://getcomposer.org/doc/articles/scripts.md#command-events

パスについて

Composerが実行される場合のパスは、vendors配下のバイナリが含まれるようになっています。
@mosa7さんご指摘ありがとうございます!)

composer.json
{
  "scripts": {
    "env": "env"
  }
}

例えばこんな感じです。

$ composer env

PATH=/Users/yousan/repository/vendor/bin:/Users/yousan/.nvm/versions/node/v6.9.1/bin:/usr/local/opt/php70/bin:/Users/yousan/bin:/Users/yousan/sh:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/yousan/.composer/vendor/bin:/Users/yousan/.composer/vendor/bin

PHPUnitがBrewなどのローカルでインストールされていて、でもリポジトリにあるComposerでバージョン指定を行いたい場合があります。
その場合のcomposer.jsonでは、Composerでインストールされるパッケージの方が優先的に呼び出されるので、相対パスの前置詞(./vendor/phpunit/phpunitなど)は不要です。

実例

実際に案件で使ったcomposer.jsonのサブコマンド集です。

composer.json
{
  "scripts": {
    "test": [
      "composer test-phpcs",
      "composer test-behat"
    ],
    "_test-behat": "behatへのパスは相対パスで書かなくても良い",
    "test-behat": [
      "./vendor/bin/behat --config ./tests/behat.yml"
    ],
    "test-phpcs": [
      "./vendor/bin/phpcs --standard=phpcs.ruleset.xml"
    ],
    "init-phpcs": [
      "rm -rf ./vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/WordPress",
      "git clone git@github.com:WordPress-Coding-Standards/WordPress-Coding-Standards.git ./vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/WordPress",
      "./vendor/bin/phpcs --config-set installed_paths `pwd -P`/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/WordPress"
    ],
    "set-wp-content": [
      "rm -rf public/wp/wp-content/themes",
      "ln -s ../../../themes public/wp/wp-content/",
      "rm -rf public/wp/wp-content/plugins",
      "ln -s ../../../plugins public/wp/wp-content/",
      "cp etc/wp-config.php public/wp/",
      "cp etc/wp.gitignore public/wp/.gitignore",
      "cp etc/wp.htaccess public/wp/.htaccess",
      "cp -R etc/languages public/wp/wp-content/"
    ],
    "db-export": [
      "wp db export - | gzip > etc/dump_`whoami`.sql.gz",
      "wp db export - | gzip > etc/dump.sql.gz"
    ],
    "db-import": [
      "wp db export - | gzip > etc/dump_`whoami`.sql.gz",
      "gunzip -c -f etc/dump.sql.gz > etc/dump.sql",
      "wp db import etc/dump.sql",
      "rm  etc/dump.sql"
    ],
    "db-staging": [
      "composer db-export",
      "wp search-replace --url=ex.dev/wp ex.dev/wp example.com",
      "wp db export - | sed -e 's/utf8mb4/utf8/g' | gzip - > etc/for_example.com.gz",
      "composer db-import"
    ],
    "post-install-cmd": [
      "composer set-wp-content",
      "composer init-phpcs"
    ],
    "post-update-cmd": [
      "composer set-wp-content",
      "composer init-phpcs"
    ]
  }
}

良いComposerライフをお送りください!