🎻

Symfony Flex/Recipesの仕組みをおさらいしてみよう

2020/04/11に公開

Symfony3から導入された Symfony Flex/Recipes ですが、意外と皆さん仕組みを理解せず適当に使ってませんか?(僕は適当に使ってました)

分かってしまえば簡単な話なので、改めてちょっと整理しておきましょう✋

Symfony FlexはComposerプラグイン

Symfony Flex は、Symfonyアプリへのライブラリの追加に伴う雑多なタスク(バンドルの登録や設定ファイルの作成など)を自動化してくれる Composerプラグインです。

symfony/flex をインストールすると、そのプロジェクト配下では composer installcomposer require したときの挙動がSymfony Flexによって拡張されます。

また、 composer コマンドに以下のようにいくつかのサブコマンドが追加されます。

Available commands:
 :
 :
 recipes
  recipes:install          Installs or reinstalls recipes for already installed packages.
 symfony
  symfony:dump-env         Compiles .env files to .env.local.php.
  symfony:generate-id      Generates a unique ID for this project.
  symfony:recipes          Shows information about all available recipes.
  symfony:recipes:install  Installs or reinstalls recipes for already installed packages.
  symfony:sync-recipes     Installs or reinstalls recipes for already installed packages.
  symfony:unpack           Unpacks a Symfony pack.

Symfony RecipesはSymfony Flexが利用する自動化のレシピ

Symfony FlexがインストールされているComposerでライブラリをインストールした際、Symfony Recipesのリポジトリ 内に対応する レシピ が存在していれば、その内容に従って色々なタスクを自動で実行してくれます。(これを「レシピがインストールされる」と表現します)

例えば、symfony/monolog-bundle に対応するレシピは このような内容 でリポジトリに登録されており、manifest.json を見ると、

  • bundles.php"Symfony\\Bundle\\MonologBundle\\MonologBundle"["all"] を対象として追加する
  • config ディレクトリの中身をSymfonyの %CONFIG_DIR% にコピーする
  • symfony/monolog-bundle という正式なライブラリ名ではなく log logger logging logs monolog といったエイリアスでもインストールできるようにする

という定義が書かれていることが分かります。

Symfony Recipsに定義できるオプションの詳細については 公式のREADME をご参照ください。

なお、エイリアスを使ってインストールした場合も、当然ながらライブラリ本体のインストールは普通に packagist.org から行われますし、 composer.jsonrequire フィールドにもエイリアス名ではなくライブラリの正式名称が記載されます。

ちなみに、Symfony FlexがインストールされているComposerでは、 symfony/xxx という名前のライブラリはすべてデフォルトで xxx とベンダー名を省略した名前をエイリアスとして使えるようです。

symfony/monolog-bundle も、レシピに定義されているエイリアスには monolog-bundle という名前はありませんが、 composer require monolog-bundle でインストールすることが可能です。

symfony.lock はインストールされたレシピのバージョンを記録しておくファイル

symfony/flex をインストールすると作成される symfony.lock というファイルは、インストールされたレシピのバージョンなどを記録しておくためのファイルです。

これはGitなどのバージョン管理配下に置くべきとされています。

https://symfony.com/doc/current/setup.html#installing-packages
Flex keeps tracks of the recipes it installed in a symfony.lock file, which must be committed to your code repository.

レシピはあとでインストールし直すこともできる

インストールされているレシピの状態は symfony.lock に記録されているわけですが、 composer resipes コマンドを使うとこれを一覧で確認することができます。

$ composer recipes

 Available recipes.

 * doctrine/annotations
 * sensio/framework-extra-bundle
 * symfony/apache-pack
 * symfony/console (update available)
 * symfony/debug-bundle
 * symfony/flex
 * symfony/framework-bundle
 * symfony/maker-bundle
 * symfony/monolog-bundle
 * symfony/phpunit-bridge
 * symfony/routing
 * symfony/twig-bundle
 * symfony/validator (recipe not installed)
 * symfony/web-profiler-bundle
 * symfony/webpack-encore-bundle

Run:
 * composer recipes vendor/package to see details about a recipe.
 * composer recipes:install vendor/package --force -v to update that recipe.

実際にあなたのお手元のSymfonyプロジェクトで composer recipes を実行してみてほしいのですが、おそらく上記のようにいくつかのライブラリに (recipe not installed)(update available) といったコメントがあると思います。

読んで字のごとく、

  • (recipe not installed) :ライブラリに対応するレシピがリポジトリに存在するのに、プロジェクトにはそれがインストールされていない
  • (update available) :インストール済みのレシピよりも新しいバージョンのレシピがリポジトリに存在する

という意味です。

特にレシピ経由で自動で作成されるバンドルの設定ファイルの雛形などは、レシピの更新差分を自分のプロジェクトにも適用する必要がある場合もあるので、たまに composer recipes をチェックしてみる習慣を持つといいかもしれません。

(recipe not installed)(update available) の状態になっているレシピは、 composer recipes:install コマンドでインストールし直すことができます。

上記の例では symfony/validator のレシピが (recipe not installed) だったので、以下のようにすればレシピのインストールだけを単体でやり直せます。

$ composer recipes:install symfony/validator

同じく上記の例で symfony/console(update available) でしたが、このようにすでにインストール済みのレシピを再インストールする場合には、 --force オプションを指定する必要があります。

$ composer recipes:install symfony/console --force

注意点として、再インストールしたレシピがファイルを自動生成してくれるものだった場合、既存のファイルが雛形で上書きされてしまう ので、インストール後に手動で差分を修正するなりする必要があります。

まとめ

  • Symfony FlexはComposerプラグイン
  • Symfony RecipesはSymfony Flexが利用する自動化のレシピ
  • symfony.lock はインストールされたレシピのバージョンを記録しておくファイル
  • レシピはあとでインストールし直すこともできる
GitHubで編集を提案

Discussion