LoginSignup
2
1

More than 1 year has passed since last update.

composerのupdateコマンドが中途半端な綴りでもOKな理由を探る

Last updated at Posted at 2021-12-27

要するに

  • 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 の案内と違うけどなー?」と、しばらく混乱したのでした。

それではごきげんよう。

2
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1