目次

, ,

Composer bin スクリプトの作り方

composer をインストールすると、パッケージに含まれる CLI ベースの補助ツールのシンボリックリンクが、自動的に vendor/bin に作られます。
この補助ツールを自分で作る方法について、いろいろと罠にハマったので記録しておきます。

composer.json の編集

composer.json の bin プロパティに補助ツールのパスを記述します。パスはプロジェクトルートからの相対パスとします。

composer.json
{
  "bin": [
    "path/to/bin",
    "path/to/another",
    ...
  ]
}

autoloader の解決

#!/usr/bin/env php
<?php
$autoloaders = [
    __DIR__ . '/../vendor/autoload.php', // 自プロジェクトからの呼び出し
    __DIR__ . '/../../../../vendor/autoload.php' // composer インストールされた先からの呼び出し
];
 
foreach ($autoloaders as $file) {
    if (file_exists($file)) {
        define('AUTOLOADER_PATH', $file);
        break;
    }
}
unset($file);
require AUTOLOADER_PATH;
 
// Call Main Script
Some\Cli\Application::main();

ファイルパスの解決

autoloader と同様、コマンドの引数にパスを渡すような場合、実ファイルのパスをベースに解決しようとすると、自身の存在するパスが変化するため、実装が難しい。
このため、getcwd() という関数を使用することでパスの解決を行う。

Phinx では Symfony\Component\Config\FileLocator というパッケージを使って設定ファイルのパスを解決をしている。

https://github.com/cakephp/phinx/blob/master/src/Phinx/Console/Command/AbstractCommand.php
https://github.com/symfony/config/blob/5.3/FileLocator.php

なお、vendor/bin にはシンボリックリンクが作られるが、シンボリックリンクから実行しても、実行した場所のディレクトリ(シンボリックリンクの親ディレクトリ)を得られるため、気にせず実装できる。