Symfony Flex/Recipesの仕組みをおさらいしてみよう
Symfony3から導入された Symfony Flex/Recipes ですが、意外と皆さん仕組みを理解せず適当に使ってませんか?(僕は適当に使ってました)
分かってしまえば簡単な話なので、改めてちょっと整理しておきましょう✋
Symfony FlexはComposerプラグイン
Symfony Flex は、Symfonyアプリへのライブラリの追加に伴う雑多なタスク(バンドルの登録や設定ファイルの作成など)を自動化してくれる Composerプラグインです。
symfony/flex
をインストールすると、そのプロジェクト配下では composer install
や composer 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.json
の require
フィールドにもエイリアス名ではなくライブラリの正式名称が記載されます。
ちなみに、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
はインストールされたレシピのバージョンを記録しておくファイル - レシピはあとでインストールし直すこともできる
Discussion