Lee RowlandsSenior Developer
Using Composer to debug issues updating Drupal core
This week whilst trying to update one of our projects to the latest version of Drupal 8 core, we had some issues.
We use Composer to manage our dependencies, modules etc, and on this particular occasion, things weren't straightforward.
In order to solve it, we had to use some of the lesser known features of Composer, so decided to share.
The problem
So updating Drupal core with composer is normally pretty simple. And on this occasion, we had no reason to suspect it would be anything different.
Normally we'd just run
composer update "drupal/core" --with-dependencies
But this time, nothing happened.
So we checked that there was a newer version available
composer show -a "drupal/core"
And sure enough, we can see 8.3.6 in the available versions.
Time to dig deeper.
The why
Luckily, composer will tell you why it won't install something.
composer why-not "drupal/core:8.3.6"
Which yielded
drupal/core 8.3.6 conflicts drush/drush (<8.1.10)
Aha, so drush is the issue.
So maybe we just update both
composer update "drupal/core" "drush/drush"
Nope.
Digging deeper
So after trying a few different combinations of version constraints etc, we decided to remove drush, update and then add it back.
composer remove --dev "drush/drush"
Which worked.
composer update "drupal/core" --with-dependencies
Ok, nice, we now have Drupal 8.3.6
composer require --dev "drush/drush"
Nope.
Your requirements could not be resolved to an installable set of packages. Problem 1 - Installation request for drush/drush 8.1.12 -> satisfiable by drush/drush[8.1.12]. - Conclusion: remove phpdocumentor/reflection-docblock 3.2.2 - Conclusion: don't install phpdocumentor/reflection-docblock 3.2.2 - drush/drush 8.1.12 requires phpdocumentor/reflection-docblock ^2.0 -> satisfiable by phpdocumentor/reflection-docblock[2.0.0, 2.0.0a1, 2.0.0a2, 2.0.0a3, 2.0.1, 2.0.2, 2.0.3, 2.0.4, 2.0.5]. - Can only install one of: phpdocumentor/reflection-docblock[2.0.0, 3.2.2]. - Can only install one of: phpdocumentor/reflection-docblock[2.0.0a1, 3.2.2]. - Can only install one of: phpdocumentor/reflection-docblock[2.0.0a2, 3.2.2]. - Can only install one of: phpdocumentor/reflection-docblock[2.0.0a3, 3.2.2]. - Can only install one of: phpdocumentor/reflection-docblock[2.0.1, 3.2.2]. - Can only install one of: phpdocumentor/reflection-docblock[2.0.2, 3.2.2]. - Can only install one of: phpdocumentor/reflection-docblock[2.0.3, 3.2.2]. - Can only install one of: phpdocumentor/reflection-docblock[2.0.4, 3.2.2]. - Can only install one of: phpdocumentor/reflection-docblock[2.0.5, 3.2.2]. - Installation request for phpdocumentor/reflection-docblock (locked at 3.2.2) -> satisfiable by phpdocumentor/reflection-docblock[3.2.2]. Installation failed, reverting ./composer.json to its original content.
Hm, so we have a version of phpdocumentor/reflection-docblock in our lock file that is too high for drush.
composer why "phpdocumentor/reflection-docblock"
Yields
phpspec/prophecy v1.6.1 requires phpdocumentor/reflection-docblock (^2.0|^3.0.2)
Aha, so prophecy - but it allows either version .. but our lock file has pinned it to the 3.x branch
So lets force composer to downgrade that
composer require --dev "phpdocumentor/reflection-docblock:^2.0"
Now lets see if we can add drush back
composer require --dev "drush/drush"
Success!
Now all that remains is to clean up, because we don't really want to depend on phpdocumentor/reflection-docblock
composer remove --dev "phpdocumentor/reflection-docblock"
Done - quick - commit that lock file while you're winning!
Summary
So while it might be easy to curse Composer for not letting you upgrade, its actually doing exactly what you told it to do.
Your lock file has a pinned version, it is honoring that.
And in order to resolve it, Composer provides all the tools you need in the form of the why and the why-not commands.