Skip to main content

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.

by lee.rowlands /

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.

Tagged

Composer, Drupal 8

Posted by lee.rowlands
Senior Drupal Developer

Dated

Comments

Comment by Brian

Dated

Wow, never knew about the "why" and "why-not" commands. Very good to know for future debugging! Thanks

Comment by James Williams

Dated

As long as your package version constraints in your composer.json file are appropriate - e.g. drupal/core could be "~8.3.3", and drush/drush at "~8.1.10" then updating both at the same time, like this, should have worked:

composer update drupal/core drush/drush --with-dependencies

You did mention updating them both in a single command, but not with the 'with-dependencies' bit, perhaps that's all that was needed? (As it's a common dependency that needed changing.)
Or maybe there's something else in your repo / configuration / composer files that was causing this?

Comment by Benji Fisher

Dated

Sometimes the dependency chains are a lot longer. If you do not want to use "composer why" three times to figure out that sugar/white is required by pancake/blueberry, which is required by sunday/brunch which is required by your project, then you can use the --recursive (-r) flag:

composer why -r sugar/white

Also, I wonder how different the results would have been if you had let composer deal with it:

rm composer.lock && composer install

Comment by greg.1.anderson

Dated

Thanks for a great explanation of `composer why` and `composer why-not`. This is a good guide on how to diagnose and get around problems with updates and the composer.lock file.

However, running `composer update "drupal/core" --with-dependencies` is in general not something that you want to do on your Drupal site. The reason is that the Drupal core developers only update Drupal's dependencies on minor releases -- e.g. from 8.3.x to 8.4.0. If you use `composer update` to get a newer patch release of Drupal core, then you will end up with a different set of dependencies than Drupal is currently using. While this should, in general work, your configuration will not be exactly the same as the one that the core committers are testing, so you become more likely to encounter new dependency bugs before the rest of the community. If your goal is to update a site that is in production, this is generally not what you want.

To work around this problem, try using https://github.com/webflo/drupal-core-strict. This project contains tagged releases that strongly constrain the versions of all of Drupal's dependencies to match what is being tested in Drupal core. If you require this project in your Composer-managed Drupal site, then you will be able to use `composer update` to update your non-Drupal-core-releated dependencies without bringing in more updates than intended.

For additional background on phpdocumentor version constraints and Drush, see https://github.com/drush-ops/drush/pull/2877

Comment by kim.pepper

Dated

We had an issue where a Guzzle security update was needed, but we didn't want to wait for a core release in order to fix it. If core sets its version ranges correctly, updating patch versions should not be a problem.

Pagination

Add new comment

Restricted HTML

  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <h2> <h3> <h4> <h5> <h6>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.