From 4e93eb5b7dba431e9ff25dc77444a0c93011901b Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 17 Nov 2015 13:38:40 +0100 Subject: [PATCH 1/6] Added an article to explain how to upgrade third-party bundles to Symfony 3 --- cookbook/map.rst.inc | 1 + cookbook/upgrade/bundles.rst | 36 ++++++++++++++++++++++++++++++++++++ cookbook/upgrade/index.rst | 1 + 3 files changed, 38 insertions(+) create mode 100644 cookbook/upgrade/bundles.rst diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc index 5ba5d97ff1c..1df049cebb2 100644 --- a/cookbook/map.rst.inc +++ b/cookbook/map.rst.inc @@ -227,6 +227,7 @@ * :doc:`/cookbook/upgrade/patch_version` * :doc:`/cookbook/upgrade/minor_version` * :doc:`/cookbook/upgrade/major_version` + * :doc:`/cookbook/upgrade/bundles` * :doc:`/cookbook/validation/index` diff --git a/cookbook/upgrade/bundles.rst b/cookbook/upgrade/bundles.rst new file mode 100644 index 00000000000..ec5120a1dc7 --- /dev/null +++ b/cookbook/upgrade/bundles.rst @@ -0,0 +1,36 @@ +.. index:: + single: Upgrading; Bundle; Major Version + +Upgrading a Third-Party Bundle for a Major Symfony Version +========================================================== + +Symfony 3 was released on November 2015. Although this version doesn't contain +any new feature, it removes all the backwards compatibility layers included in +the previous 2.8 version. If your bundle uses any deprecated feature and it's +published as a third-party bundle, applications upgrading to Symfony 3 will no +longer be able to use it. + +Allow to Install Symfony 3 Components +------------------------------------- + +.. TODO + +* Change symfony/... ~2.N by ~2.N|~3.M + +Look for Deprecations and Fix Them +---------------------------------- + +.. TODO + +* Install: composer require --dev "symfony/phpunit-bridge" and run your test suite +* Use for basic fixes: https://github.com/umpirsky/Symfony-Upgrade-Fixer +* Read the "UPGRADE from 2.x to Sf3" guide (https://github.com/symfony/symfony/blob/2.8/UPGRADE-3.0.md) + +Test your Bundle in Symfony 3 +----------------------------- + +.. TODO + +* Upgrade a test app to Sf3 or create an empty app (symfony new my_app 3.0) +* Use the "ln -s my_bundle vendor/.../my_bundle" trick to use the new code in the 3.0 app +* Configure Travis CI to test your bundle in both 2 and 3 versions. diff --git a/cookbook/upgrade/index.rst b/cookbook/upgrade/index.rst index b943f2ae32a..27785a07b09 100644 --- a/cookbook/upgrade/index.rst +++ b/cookbook/upgrade/index.rst @@ -16,3 +16,4 @@ There are three types of upgrades, all needing a little different preparation: /cookbook/upgrade/patch_version /cookbook/upgrade/minor_version /cookbook/upgrade/major_version + /cookbook/upgrade/bundles From 0e585b41da3d1ebd3625ab08cfa05d26c66824e6 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 17 Nov 2015 15:10:43 +0100 Subject: [PATCH 2/6] Completed "Allow to Install Symfony 3 Components" section --- cookbook/upgrade/bundles.rst | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/cookbook/upgrade/bundles.rst b/cookbook/upgrade/bundles.rst index ec5120a1dc7..296ff34a5d4 100644 --- a/cookbook/upgrade/bundles.rst +++ b/cookbook/upgrade/bundles.rst @@ -13,9 +13,35 @@ longer be able to use it. Allow to Install Symfony 3 Components ------------------------------------- -.. TODO - -* Change symfony/... ~2.N by ~2.N|~3.M +Most third-party bundles define their Symfony dependencies using the ``~2.N`` or +``^2.N`` constraints in the ``composer.json`` file. For example: + +.. code-block:: json + + { + "require": { + "symfony/framework-bundle": "~2.3", + "symfony/finder": "~2.3", + "symfony/validator": "~2.3", + } + } + +These constraints prevent the bundle from using Symfony 3 components, so it makes +it impossible to install it in a Symfony 3 based application. This issue is very +easy to solve thanks to the flexibility of Composer dependencies constraints. +Just replace ``~2.N`` by ``~2.N|~3.0`` (or ``^2.N`` by ``^2.N|~3.0``). + +The above example can be updated to work with Symfony 3 as follows: + +.. code-block:: json + + { + "require": { + "symfony/framework-bundle": "~2.3|~3.0", + "symfony/finder": "~2.3|~3.0", + "symfony/validator": "~2.3|~3.0", + } + } Look for Deprecations and Fix Them ---------------------------------- From 4b13fab55504c4254152ecfc55f34b870f2136e2 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 17 Nov 2015 16:11:39 +0100 Subject: [PATCH 3/6] Completed the section "Look for Deprecations and Fix Them" --- cookbook/upgrade/bundles.rst | 60 ++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/cookbook/upgrade/bundles.rst b/cookbook/upgrade/bundles.rst index 296ff34a5d4..f22cadb1ac9 100644 --- a/cookbook/upgrade/bundles.rst +++ b/cookbook/upgrade/bundles.rst @@ -22,7 +22,7 @@ Most third-party bundles define their Symfony dependencies using the ``~2.N`` or "require": { "symfony/framework-bundle": "~2.3", "symfony/finder": "~2.3", - "symfony/validator": "~2.3", + "symfony/validator": "~2.3" } } @@ -39,18 +39,61 @@ The above example can be updated to work with Symfony 3 as follows: "require": { "symfony/framework-bundle": "~2.3|~3.0", "symfony/finder": "~2.3|~3.0", - "symfony/validator": "~2.3|~3.0", + "symfony/validator": "~2.3|~3.0" } } Look for Deprecations and Fix Them ---------------------------------- -.. TODO +Besides allowing to install Symfony 3 component, your bundle must stop using +any feature deprecated in 2.8 version, because they'll throw exceptions in 3.0 +version. The easiest way to detect deprecations is to install the `PHPUnit Bridge`_ +component and then run the test suite. + +First, install the component as a ``dev`` dependency of your bundle: + +.. code-block:: bash + + $ composer require --dev "symfony/phpunit-bridge" + +Then, run your test suite and look for the deprecation list displayed after the +PHPUnit test report: + +.. code-block:: bash + + $ phpunit + + // ... PHPUnit output ... -* Install: composer require --dev "symfony/phpunit-bridge" and run your test suite -* Use for basic fixes: https://github.com/umpirsky/Symfony-Upgrade-Fixer -* Read the "UPGRADE from 2.x to Sf3" guide (https://github.com/symfony/symfony/blob/2.8/UPGRADE-3.0.md) + Remaining deprecation notices (3) + + The "pattern" option in file ... is deprecated since version 2.2 and will be + removed in 3.0. Use the "path" option in the route definition instead ... + + Twig Function "form_enctype" is deprecated. Use "form_start" instead in ... + + The Symfony\Component\Security\Core\SecurityContext class is deprecated since + version 2.6 and will be removed in 3.0. Use ... + +Fix the reported deprecations, run the test suite again and repeat the process +until no deprecation usage is reported. + +Useful Resources +~~~~~~~~~~~~~~~~ + +There are several resources that can help you detect, understand and fix the use +of deprecated features: + +* `Official Symfony Guide to Upgrade from 2.x to 3.0`_, the full list of changes + required to upgrade to Symfony 3.0 and grouped by component. +* `SensioLabs DeprecationDetector`_, it runs a static code analysis against your + project's source code to find usages of deprecated methods, classes and + interfaces. It works for any PHP application, but it includes special detectors + for Symfony application, where it can also detect usages of deprecated services. +* `Symfony Upgrade Fixer`_, it analyzes Symfony projects to find deprecations. In + addition it solves automatically some of them thanks to the growing list of + supported "fixers". Test your Bundle in Symfony 3 ----------------------------- @@ -60,3 +103,8 @@ Test your Bundle in Symfony 3 * Upgrade a test app to Sf3 or create an empty app (symfony new my_app 3.0) * Use the "ln -s my_bundle vendor/.../my_bundle" trick to use the new code in the 3.0 app * Configure Travis CI to test your bundle in both 2 and 3 versions. + +.. _`PHPUnit Bridge`: https://github.com/symfony/phpunit-bridge +.. _`Official Symfony Guide to Upgrade from 2.x to 3.0`: https://github.com/symfony/symfony/blob/2.8/UPGRADE-3.0.md +.. _`SensioLabs DeprecationDetector`: https://github.com/sensiolabs-de/deprecation-detector +.. _`Symfony Upgrade Fixer`: https://github.com/umpirsky/Symfony-Upgrade-Fixer \ No newline at end of file From 1e2ccd118e94bf50536934b208f33c6084364d72 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 17 Nov 2015 17:30:46 +0100 Subject: [PATCH 4/6] Completed the section "Test your Bundle in Symfony 3" --- cookbook/upgrade/bundles.rst | 55 ++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/cookbook/upgrade/bundles.rst b/cookbook/upgrade/bundles.rst index f22cadb1ac9..fc7cadab99b 100644 --- a/cookbook/upgrade/bundles.rst +++ b/cookbook/upgrade/bundles.rst @@ -98,13 +98,58 @@ of deprecated features: Test your Bundle in Symfony 3 ----------------------------- -.. TODO +Now that your bundle has removed all deprecations, it's time to test it for real +in a Symfony 3 application. Assuming that you already have a Symfony 3 application, +you can test the updated bundle locally without having to install it through +Composer. -* Upgrade a test app to Sf3 or create an empty app (symfony new my_app 3.0) -* Use the "ln -s my_bundle vendor/.../my_bundle" trick to use the new code in the 3.0 app -* Configure Travis CI to test your bundle in both 2 and 3 versions. +If your operating system supports symbolic lings, just point the appropriate +vendor directory to your local bundle root directory: + +.. code-block:: bash + + $ ln -s /path/to/your/local/bundle/ vendor/you-vendor-name/your-buncle-name + +If your operating system doesn't support symbolic links, you'll need to copy +your local bundle directory into the appropriate directory inside ``vendor/``. + +Update the Travis CI Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to running tools locally, it's recommended to set-up Travis CI service +to run the tests of your bundle using different Symfony configurations. Use the +following recommended configuration as the starting point of your own configuration: + +.. code-block:: yaml + + language: php + sudo: false + php: + - 5.3 + - 5.6 + - 7.0 + + matrix: + include: + - php: 5.3.3 + env: COMPOSER_FLAGS='--prefer-lowest --prefer-stable' SYMFONY_DEPRECATIONS_HELPER=weak + - php: 5.6 + env: SYMFONY_VERSION='2.3.*' + - php: 5.6 + env: DEPENDENCIES='dev' SYMFONY_VERSION='2.8.*@dev' + - php: 5.6 + env: SYMFONY_VERSION='3.0.*@dev' + + before_install: + - composer self-update + - if [ "$DEPENDENCIES" == "dev" ]; then perl -pi -e 's/^}$/,"minimum-stability":"dev"}/' composer.json; fi; + - if [ "$SYMFONY_VERSION" != "" ]; then composer require symfony/symfony:${SYMFONY_VERSION}; fi; + + install: composer update $COMPOSER_FLAGS + + script: phpunit -v .. _`PHPUnit Bridge`: https://github.com/symfony/phpunit-bridge .. _`Official Symfony Guide to Upgrade from 2.x to 3.0`: https://github.com/symfony/symfony/blob/2.8/UPGRADE-3.0.md .. _`SensioLabs DeprecationDetector`: https://github.com/sensiolabs-de/deprecation-detector -.. _`Symfony Upgrade Fixer`: https://github.com/umpirsky/Symfony-Upgrade-Fixer \ No newline at end of file +.. _`Symfony Upgrade Fixer`: https://github.com/umpirsky/Symfony-Upgrade-Fixer From 3697d81c538aef65f693eae739f2b04012ae1419 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 23 Nov 2015 09:37:02 +0100 Subject: [PATCH 5/6] Fixed a lot of issues reported by Wouter --- cookbook/upgrade/bundles.rst | 49 +++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/cookbook/upgrade/bundles.rst b/cookbook/upgrade/bundles.rst index fc7cadab99b..0ae9d0f6f9f 100644 --- a/cookbook/upgrade/bundles.rst +++ b/cookbook/upgrade/bundles.rst @@ -43,19 +43,26 @@ The above example can be updated to work with Symfony 3 as follows: } } +.. tip:: + + Another common version constraint found on third-party bundles is ``>=2.N``. + You should avoid using that constraint because it can wrongly consider as + valid some Symfony versions which are in fact incompatible with your bundle. + Use instead ``~2.N|~3.0`` or ``^2.N|~3.0`` to make your bundle future-proof. + Look for Deprecations and Fix Them ---------------------------------- -Besides allowing to install Symfony 3 component, your bundle must stop using -any feature deprecated in 2.8 version, because they'll throw exceptions in 3.0 -version. The easiest way to detect deprecations is to install the `PHPUnit Bridge`_ -component and then run the test suite. +Besides allowing to install Symfony 3 packages, your bundle must stop using +any feature deprecated in 2.8 version, because they are removed (and you'll get +exceptions or PHP errors). The easiest way to detect deprecations is to install +the `symfony/phpunit-bridge package`_ and then run the test suite. First, install the component as a ``dev`` dependency of your bundle: .. code-block:: bash - $ composer require --dev "symfony/phpunit-bridge" + $ composer require --dev symfony/phpunit-bridge Then, run your test suite and look for the deprecation list displayed after the PHPUnit test report: @@ -64,7 +71,7 @@ PHPUnit test report: $ phpunit - // ... PHPUnit output ... + # ... PHPUnit output Remaining deprecation notices (3) @@ -85,15 +92,17 @@ Useful Resources There are several resources that can help you detect, understand and fix the use of deprecated features: -* `Official Symfony Guide to Upgrade from 2.x to 3.0`_, the full list of changes - required to upgrade to Symfony 3.0 and grouped by component. -* `SensioLabs DeprecationDetector`_, it runs a static code analysis against your - project's source code to find usages of deprecated methods, classes and - interfaces. It works for any PHP application, but it includes special detectors - for Symfony application, where it can also detect usages of deprecated services. -* `Symfony Upgrade Fixer`_, it analyzes Symfony projects to find deprecations. In - addition it solves automatically some of them thanks to the growing list of - supported "fixers". +`Official Symfony Guide to Upgrade from 2.x to 3.0`_ + The full list of changes required to upgrade to Symfony 3.0 and grouped + by component. +`SensioLabs DeprecationDetector`_ + It runs a static code analysis against your project's source code to find + usages of deprecated methods, classes and interfaces. It works for any PHP + application, but it includes special detectors for Symfony applications, + where it can also detect usages of deprecated services. +`Symfony Upgrade Fixer`_ + It analyzes Symfony projects to find deprecations. In addition it solves + automatically some of them thanks to the growing list of supported "fixers". Test your Bundle in Symfony 3 ----------------------------- @@ -103,12 +112,12 @@ in a Symfony 3 application. Assuming that you already have a Symfony 3 applicati you can test the updated bundle locally without having to install it through Composer. -If your operating system supports symbolic lings, just point the appropriate +If your operating system supports symbolic links, just point the appropriate vendor directory to your local bundle root directory: .. code-block:: bash - $ ln -s /path/to/your/local/bundle/ vendor/you-vendor-name/your-buncle-name + $ ln -s /path/to/your/local/bundle/ vendor/you-vendor-name/your-bundle-name If your operating system doesn't support symbolic links, you'll need to copy your local bundle directory into the appropriate directory inside ``vendor/``. @@ -143,13 +152,13 @@ following recommended configuration as the starting point of your own configurat before_install: - composer self-update - if [ "$DEPENDENCIES" == "dev" ]; then perl -pi -e 's/^}$/,"minimum-stability":"dev"}/' composer.json; fi; - - if [ "$SYMFONY_VERSION" != "" ]; then composer require symfony/symfony:${SYMFONY_VERSION}; fi; + - if [ "$SYMFONY_VERSION" != "" ]; then composer --no-update require symfony/symfony:${SYMFONY_VERSION}; fi; install: composer update $COMPOSER_FLAGS - script: phpunit -v + script: phpunit -.. _`PHPUnit Bridge`: https://github.com/symfony/phpunit-bridge +.. _`symfony/phpunit-bridge package`: https://github.com/symfony/phpunit-bridge .. _`Official Symfony Guide to Upgrade from 2.x to 3.0`: https://github.com/symfony/symfony/blob/2.8/UPGRADE-3.0.md .. _`SensioLabs DeprecationDetector`: https://github.com/sensiolabs-de/deprecation-detector .. _`Symfony Upgrade Fixer`: https://github.com/umpirsky/Symfony-Upgrade-Fixer From cb31c16a2861761b89f2fcaa7e23c27685e1e1a0 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 23 Nov 2015 10:46:28 +0100 Subject: [PATCH 6/6] Added a new section of tips and tricks to upgrade bundles to Symfony 3.0 --- cookbook/upgrade/bundles.rst | 71 +++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/cookbook/upgrade/bundles.rst b/cookbook/upgrade/bundles.rst index 0ae9d0f6f9f..f30b53fb5eb 100644 --- a/cookbook/upgrade/bundles.rst +++ b/cookbook/upgrade/bundles.rst @@ -10,8 +10,8 @@ the previous 2.8 version. If your bundle uses any deprecated feature and it's published as a third-party bundle, applications upgrading to Symfony 3 will no longer be able to use it. -Allow to Install Symfony 3 Components -------------------------------------- +Allowing to Install Symfony 3 Components +---------------------------------------- Most third-party bundles define their Symfony dependencies using the ``~2.N`` or ``^2.N`` constraints in the ``composer.json`` file. For example: @@ -46,12 +46,12 @@ The above example can be updated to work with Symfony 3 as follows: .. tip:: Another common version constraint found on third-party bundles is ``>=2.N``. - You should avoid using that constraint because it can wrongly consider as - valid some Symfony versions which are in fact incompatible with your bundle. - Use instead ``~2.N|~3.0`` or ``^2.N|~3.0`` to make your bundle future-proof. + You should avoid using that constraint because it's too generic (it means + that your bundle is compatible with any future Symfony version). Use instead + ``~2.N|~3.0`` or ``^2.N|~3.0`` to make your bundle future-proof. -Look for Deprecations and Fix Them ----------------------------------- +Looking for Deprecations and Fix Them +------------------------------------- Besides allowing to install Symfony 3 packages, your bundle must stop using any feature deprecated in 2.8 version, because they are removed (and you'll get @@ -104,8 +104,8 @@ of deprecated features: It analyzes Symfony projects to find deprecations. In addition it solves automatically some of them thanks to the growing list of supported "fixers". -Test your Bundle in Symfony 3 ------------------------------ +Testing your Bundle in Symfony 3 +-------------------------------- Now that your bundle has removed all deprecations, it's time to test it for real in a Symfony 3 application. Assuming that you already have a Symfony 3 application, @@ -158,6 +158,59 @@ following recommended configuration as the starting point of your own configurat script: phpunit +Updating your Code to Support Symfony 2.x and 3.x at the Same Time +------------------------------------------------------------------ + +The real challenge of adding Symfony 3 support for your bundles is when you want +to support both Symfony 2.x and 3.x simultaneously using the same code. There +are some edge cases where you'll need to deal with the API differences. + +Before diving into the specifics of the most common edge cases, the general +recommendation is to **not rely on the Symfony Kernel version** to decide which +code to use:: + + if (Kernel::VERSION_ID <= 20800) { + // code for Symfony 2.x + } else { + // code for Symfony 3.x + } + +Instead of checking the Symfony Kernel version, check the version of the specific +component. For example, the OptionsResolver API changed in its 2.6 version by +adding a ``setDefined()`` method. The recommended check in this case would be:: + + if (!method_exists('Symfony\Component\OptionsResolver\OptionsResolver', 'setDefined')) { + // code for the old OptionsResolver API + } else { + // code for the new OptionsResolver API + } + +Form Name Refactoring +~~~~~~~~~~~~~~~~~~~~~ + +.. TODO + + - how to check which version to use + - how to update FormType classes + - how to update type service definitions + - how to update FormTypeExtension classes & service definition + +OptionsResolver API Refactoring +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. TODO + + - how to check which version to use + - how to both APIs + +Service Factory Refactoring +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. TODO + + - how to support both APIs ==> Is there a nice way except from (a) doing + it in the DI extension or (b) creating 2 service definition files? + .. _`symfony/phpunit-bridge package`: https://github.com/symfony/phpunit-bridge .. _`Official Symfony Guide to Upgrade from 2.x to 3.0`: https://github.com/symfony/symfony/blob/2.8/UPGRADE-3.0.md .. _`SensioLabs DeprecationDetector`: https://github.com/sensiolabs-de/deprecation-detector