Symfonyをアップグレードする方法

2016年12月14日

symfony-logo

この記事は Symfony Advent Calendar 2016 の 14 日目の記事です。

Symfony3 がリリースされて 1 年経ちました。そろそろ 3 系へのアップグレードを考えている方も多いと思います。今回は、私がいつもやっているアップグレードの手順をまとめてみました。Symfony2.8 から 3.0 へのバージョンアップを例に紹介しますが、どのバージョンでも見るところは同じなので、いろんなバージョンに適用できる方法かと思います。

目次

  1. Symfony Installer を使って 1 つ上のバーションをダウンロードする
  2. composer.json を比較し、差分を取り込む
  3. サードパーティ製バンドルのバージョンを上げる
  4. composer update コマンドを実行する
  5. 標準のディレクトリ構造が変わっている場合は、新しい構造に合わせる
  6. 標準ファイルを比較し、差分を取り込む
  7. Github symfony の UPGRADE-x.x.md を見ながら、既存コードに変更点を取り込む
  8. アプリケーションと PHPUnit を動かして動作確認
  9. おまけ マネージャーやステークホルダーの説得

Symfony Installer を使って 1 つ上のバーションをダウンロードする

はじめに、Symfony Installer を使って 1 つ上のバージョンの Symfony をダウンロードします。例えば現在のバージョンが 2.8 の場合、3.0 をダウンロードします。この後たくさん diff を取るので、アップグレード対象の近くにダウンロードすると楽です。

Symfony Installer は Download Symfony Framework and Components を見て、あらかじめインストールしておきます。

$ symfony new symfony3.0 3.0

symfony new コマンドを実行すると、カレントディレクトリに symfony3.0 というディレクトリができます。

symfony3.0
├── README.md
├── app
├── bin
├── composer.json
├── composer.lock
├── phpunit.xml.dist
├── src
├── tests
├── var
├── vendor
└── web

composer.json を比較し、差分を取り込む

アップグレード対象の composer.json と、先程ダウンロードした symfony3.0 ディレクトリの composer.json を比較し、差分を取り込みます。

composer.jsonのdiff

上記の画像は、とある Symfony2.8 のプロジェクトの composer.json と Symfony3.0 の composer.json を比較したところです。左が 2.8 右が 3.0 です。各バンドルのバージョンが変わっているのと、Symfony3 になって標準のディレクトリ構造が変わったため、autoload-dev などが差分として現れています。

サードパーティ製バンドルのバージョンを上げる

次に、composer.json に自身で追加したサードパーティ製のバンドルのバージョンを変更します。

Symfony 本体のバージョンが上がった場合 composer.json のバージョンをいくつにするべきか、いろいろ確認方法はあると思いますが、私は Packagist で確認することが多いです。

Packagist alicebundle

上の画像は Packagist の hautelook/alice-bundle の v1.4.1 のページです。requires, requires(dev) のあたりを確認して Symfony3 系の対応を確認します。hautelook/alice-bundle は、nelmio/alice や、doctrine のバンドルに依存していますので、そのパッケージも Packagist で探して確認します。バンドルがバンドルに依存して、確認するバンドルが芋づる式に増えていくことがあるので、注意が必要です。

何かバンドルを導入するときはアップグレードのことも選定基準に入れておきましょう。

composer update コマンドを実行する

composer.json の変更が終わったら、composer update コマンドを実行します。composer.json の書式や指定したバージョンに問題がなければライブラリが更新されます。post-update-cmd の clearCache のあたりでエラーが出て止まることが多いですが、この段階ではパッケージがすべて正常にダウンロードされていれば OK です。

標準のディレクトリ構造が変わっている場合は、新しい構造に合わせる

次にディレクトリ構造やファイルの変更に注目します。ディレクトリ構造が変わっている場合は、新しい構造に合わせます。

例えば Symfony3 では、標準のディレクトリ構造が変わり bin, var, tests といったディレクトリが追加されました。app/cache と app/logs は var 以下に移動になりました。app/phpunit.xml.dist は トップディレクトリ下に移動になりました。確認して変更を取り込みます。

標準ファイルを比較し、差分を取り込む

標準ファイルを比較し、差分をマージします。無くなったファイルがある場合は削除します。対象のファイルは大体こんな感じです。大変ですが 1 つずつ差分を取り込んでいきましょう。

symfony3.0
├── app
│   ├── AppCache.php
│   ├── AppKernel.php
│   ├── autoload.php
│   └── config
│       ├── config.yml
│       ├── config_dev.yml
│       ├── config_prod.yml
│       ├── config_test.yml
│       ├── parameters.yml
│       ├── parameters.yml.dist
│       ├── routing.yml
│       ├── routing_dev.yml
│       ├── security.yml
│       └── services.yml
├── bin
│   ├── console
│   └── symfony_requirements
├── phpunit.xml.dist
└── web
    ├── app.php
    ├── app_dev.php
    └── config.php

Github symfony の UPGRADE-x.x.md を見ながら、既存コードに変更点を取り込む

GitHub の symfony/symfony にある UPGRADE-x.x.md を見ながら、変更点を取り込みます。

今回の例 2.8 から 3.0 へのアップグレードのとき、確認するファイルは symfony/UPGRADE-3.0.md です。

変更作業のイメージは、変更があったクラス名で src ディレクトリ以下を grep して、そのクラスを使っていたら変更点を適用していく感じです。

修正がすべて終わったら composer run-script post-update-cmd コマンドを実行してみます。先程実行した composer update コマンドのときと同様に、post-update-cmd の clearCacheエラーで止まることが多いです。メッセージを見ながら対処し、エラーが出なくなるまで繰り返します。

正常終了すると以下のように出力されます。

$ composer run-script post-update-cmd

ocramius/package-versions:  Generating version class...
ocramius/package-versions: ...done generating version class
> Incenteev\ParameterHandler\ScriptHandler::buildParameters
Updating the "app/config/parameters.yml" file
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache
 // Clearing the cache for the dev environment with debug true
 [OK] Cache for the "dev" environment (debug=true) was successfully cleared.
 ...
 ...
 [OK] All assets were successfully installed.
 ...
 ...

アプリケーションと PHPUnit を動かして動作確認

post-update-cmd が正常終了したら、実際にアプリケーションを動かしたり、PHPUnit を実行して動作確認をしましょう。エラーが出てきたら原因を見つけて対処します。

デバッグツールバーや PHPUnit の実行結果に deprecated 警告がでてくることがあります。UPGRADE-x.x.md の適用漏れかもしれませんので、見つけたら対処します。

問題なく動いていて、deprecated 警告に対処すれば、アップグレード完了です。

おまけ マネージャーやステークホルダーの説得

本筋からちょっと離れた組織的な小話。でもエンジニアが自分たちのやりたいことをやるのに必要な話。

フレームワークのバージョンアップのような「売上に直接つながらないもの」について難色を示すマネージャー・ステークホルダーは多いと思います。システム全体に変更が入るのでリスクも高いですしね。マネージャー側の思考回路を知っておくと、このあたりの説得がしやすくなると思います。

マネージャーの頭の中(私の経験から。組織によってちょっと違うと思います)。

  • 成果物を世の中に届けてお金を儲ける必要がある
  • 納期、進捗、品質、報告、予算、リソース配分、中・長期的な計画、メンバーのキャリアプランとかモチベーションのことをずっと考えている
  • 決断に責任を持つ立場なので、効果がよく分からないものにはリソースを投入できない(ステークホルダーに説明もできない)

これらを踏まえて、次のことを考えて持っていきます。

  • バージョンアップしない場合、起こりうる問題
  • バージョンアップの方法と超概算見積
  • 作業に伴うリスク
  • 費用対効果

リソース投資に対する効果を数値的に感じてもらうことが大事です。

アップグレードすることにより「長期的にみて開発の生産性を下げない」「セキュリティホールへの対応」「関わる人が幸せになる」ロジックを頑張って説明します。

まとめ

手順をざっくりおさらいすると、以下のようになります。

  • composer.json の変更と composer update
  • ディレクトリ構造の変更
  • 標準ファイルの変更
  • UPGRADE-x.x.md 対応

今回のように 2.8 から 3.0、3.0 から 3.1、3.2 へと、目的のバージョンまで 1 つずつ上げていくと問題の切り分けがしやすいです。一気にやらないのが大事。

アップグレードのコミットも他の人になぜやったか伝わるように、できるだけ細かく刻みましょう。

アップグレードするときは新機能の開発をせず、アップグレードに専念したほうが良いです。みんなで一気にやりましょう。

-技術ブログ
-