要するに
-
composer upda
とかの中途半端なコマンドでもupdate
と解釈してくれる - symfony が前方一致で探索してくれているおかげ
ことの始まり
[higa@local]$ composer upda
あらー。 update
としたいところ、間違えて upda
って打っちゃったー。
これはコマンド失敗でしょうねー。
[higa@local]$ composer upda
Loading composer repositories with package information
へ?
[higa@local]$ composer upda
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 1 update, 0 removals
# 以下略
ほ?
普段の update
と同じ出力が流れ始めたんですがー。
# もちろん成功
composer update
# もちろん成功 (公式でエイリアスを用意している)
composer u
# updateコマンドとして処理してくれる
composer updat
# 同上
composer upda
# 同上
composer upd
# 同上
composer up
どういうことー?
composer のマニュアル
マニュアルやコードによると、アップデートできるコマンドは update
。
エイリアスとして u
, upgrade
を用意しています。
他の、途切れた文字列は未定義です。
[higa@local]$ composer
______
/ ____/___ ____ ___ ____ ____ ________ _____
/ / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
/_/
Composer version 2.2.1
Usage:
command [options] [arguments]
Available commands:
u Upgrades your dependencies to the latest version according to composer.json, and updates the composer.lock file.
update Upgrades your dependencies to the latest version according to composer.json, and updates the composer.lock file.
upgrade Upgrades your dependencies to the latest version according to composer.json, and updates the composer.lock file.
https://github.com/composer/composer/blob/2.2.1/src/Composer/Command/UpdateCommand.php#L48
class UpdateCommand extends BaseCommand
{
/**
* @return void
*/
protected function configure()
{
$this
->setName('update')
->setAliases(array('u', 'upgrade'))
symfony のコード
composer は symfony/console などのライブラリを使っています。
下記は Application::find()
の一部です。この下で、引数が ambiguous かどうかを判断しますが、composer では u
から始まるコマンド・エイリアスが、たまたま update
1種類しかありません。
そのため、右文字がいかに削れようとも、無事に update
コマンドと解釈して処理するようです。
https://github.com/symfony/console/blob/v2.8.52/Application.php#L493
public function find(string $name)
{
// 中略
$allCommands = $this->commandLoader ? array_merge($this->commandLoader->getNames(), array_keys($this->commands)) : array_keys($this->commands);
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
// 引数 (composerのコマンド) が、途中で切れた `upda` であったとき、
// $expr = 'upda[^:]*[^:]*';
// になる。
$commands = preg_grep('{^'.$expr.'}', $allCommands);
// 正規表現で前方一致探索してくれるので、
// $commands = ['update'];
// を選定する。
おわりに
この記事では composer update
コマンドが途中で切れていても動作する理由を探りました。
原因の箇所が vendor
ディレクトリ配下にあるので、「composer の案内と違うけどなー?」と、しばらく混乱したのでした。
それではごきげんよう。