Mediacurrent: Debugging Composer Dependency Conflicts

Are you ready to upgrade to Drupal 9? If you’re moving from a Drupal 8 site, it needs to be reviewed and updated to remove any deprecated code that will no longer be compatible with Drupal 9. Luckily, there are a few ways to check existing codebases for deprecated code, get a glimpse of what changes need to be made, and even apply the fixes automatically.

We have other blog posts that go into details about how to plan, prepare, and fix issues with deprecated code in preparation for Drupal 9, so we won’t go into those details here, but rather walk through a Composer issue we recently ran into while trying to get Drupal Check and Rector utilities added to perform our own code deprecation checks.

We hope that this blog post helps others with similar Composer issues figure out ways to understand and debug these cryptic errors and be aware of some options and things to try in fixing them.

The Conflict

The issue we faced was where a developer had already added the Drupal Check utility a while back, and when adding Rector, you may get Composer conflict messages like this:

“Your requirements could not be resolved to an installable set of packages.

Problem 1

     - rector/rector-prefixed v0.3.5 requires phpstan/phpstan ^0.11.19 -> satisfiable by phpstan/phpstan[0.11.19] but these conflict with your requirements or minimum-stability.      - Installation request for palantirnet/drupal-rector ^0.5.1 -> satisfiable by palantirnet/drupal-rector[0.5.1].      - Conclusion: remove nikic/php-parser v4.0.2      - Conclusion: don't install nikic/php-parser v4.0.2      - palantirnet/drupal-rector 0.5.1 requires rector/rector-prefixed <0.7.19 -> satisfiable by rector/rector-prefixed[v0.3.5, v0.6.10, v0.6.12, v0.6.13, v0.6.14, v0.6.2, v0.6.4, v0.6.5, v0.6.7, v0.6.8, v0.6.9, v0.7.0, v0.7.1, v0.7.10, v0.7.11, v0.7.12, v0.7.13, v0.7.14, v0.7.15, v0.7.16, v0.7.17, v0.7.18, v0.7.2, v0.7.3, v0.7.4, v0.7.5, v0.7.6, v0.7.7, v0.7.8, v0.7.9].      - rector/rector-prefixed v0.6.10 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.6.12 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.6.13 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.6.14 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.6.2 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.6.4 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.6.5 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.6.7 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.6.8 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.6.9 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.0 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.1 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.10 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.11 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.12 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.13 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.14 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.15 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.16 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.17 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.18 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.2 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.3 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.4 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.5 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.6 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.7 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.8 conflicts with nikic/php-parser[v4.0.2].      - rector/rector-prefixed v0.7.9 conflicts with nikic/php-parser[v4.0.2].      - Installation request for nikic/php-parser 4.0.2 -> satisfiable by nikic/php-parser[v4.0.2].  Installation failed, reverting ./composer.json to its original content.

This can be pretty scary to look at and digest what it all means. But, let’s just start at the top.

Step 1

The first problem stated is:

 - rector/rector-prefixed v0.3.5 requires phpstan/phpstan ^0.11.19 -> satisfiable by phpstan/phpstan[0.11.19] but these conflict with your requirements or minimum-stability.

So, first, let’s look at the composer.json file. We only really care about the “require-dev” section, since we’re only dealing with the development utility scripts Drupal Check and Rector in this example, but these same investigation and debugging steps in Composer can apply similarly to items in the “require” section as well, like Drupal modules and their dependencies.

 "require-dev": {     "drupal/drupal-extension": "^3.4",     "drush-ops/behat-drush-endpoint": "^8.2.4",     "mediacurrent/ci-scripts": "~1.2",     "mediacurrent/ci-tests": "dev-master",     "mediacurrent/mis_vagrant": "^5.1.0",     "mglaman/drupal-check": "^1.0",     "nikic/php-parser": "4.0.2",     "phpro/grumphp": "^0.11.6",     "phpstan/phpstan": "0.11.9",     "webflo/drupal-core-require-dev": "^8.8.1"  },

Notice how there is a strict version set for the phpstan package? What’s happening is the Rector tool is trying to add a dependency package, rector/rector-prefixed v0.3.5, but that requires phpstan ^0.11.19 (so 0.11.19 or greater). And because we have a strict 0.11.9 for phpstan in composer.json, it can’t add what it needs.

A first attempt to fix this would be to try installing a version of phpstan that it wants, so we can try something like:

 composer require --dev phpstan/phpstan:^0.11.19

After running that, it looks better, but still some issues:

 Your requirements could not be resolved to an installable set of packages.

Problem 1

  - Can only install one of: nikic/php-parser[v4.0.2, 4.3.x-dev].      - Can only install one of: nikic/php-parser[4.3.x-dev, v4.0.2].      - Can only install one of: nikic/php-parser[4.3.x-dev, v4.0.2].      - phpstan/phpstan 0.11.19 requires nikic/php-parser ^4.2.3 -> satisfiable by nikic/php-parser[4.3.x-dev].      - Installation request for phpstan/phpstan ^0.11.19 -> satisfiable by phpstan/phpstan[0.11.19].      - Installation request for nikic/php-parser 4.0.2 -> satisfiable by nikic/php-parser[v4.0.2].

That issue is caused because of more strict package versions in composer.json — especially with the nikic/php-parser package.

 "nikic/php-parser": "4.0.2"

This version constraint is causing this issue:

 - phpstan/phpstan 0.11.19 requires nikic/php-parser ^4.2.3 -> satisfiable by nikic/php-parser[4.3.x-dev].

Step 2

Upon further inspection in the repo and commit history, we’ve concluded that the previous developer added those packages manually to the composer.json file (well, Composer-required them), but they shouldn’t have been added in that way, since they should be letting Composer manage them as dependencies.

Sometimes when debugging Composer dependencies we try one strategy and if that doesn’t work we revert back and try something different.

Now that it seems that these packages were added manually to the projects in error, we can pull them out of the codebase and let Composer manage them as dependencies in a way it needs.

Remove the phpstan package from composer.json:

 composer remove phpstan/phpstan

It looks like this removed the package from composer.json, and updated the package to a newer version because phpstan is still a dependency of Drupal-check’s constraint set at ^0.11.9. And 0.11.12 is the latest version in that constraint.

But, it’s still not going to be good enough, because remember Drupal Rector rector-prefixed package needs at least 0.11.19 per the ^0.11.19 constraint.

Step 3

Remove the php-parser package from composer.json:

 composer remove nikic/php-parser

It looks like it removed the php-parser package from composer.json, and updated the package to v4.4.0

 Loading composer repositories with package information  Updating dependencies (including require-dev)  Package operations: 0 installs, 1 update, 0 removals  Gathering patches for root package.  Gathering patches for dependencies. This might take a minute.    - Updating nikic/php-parser (v4.0.2 => v4.4.0): Loading from cache

That’s fine, we’ll just let Composer manage the dependencies itself, but we’ve cleaned up the composer.json of packages that shouldn’t have been there and were conflicting.

Let’s see if we can get Drupal Rector added now that the conflicting packages are removed:

 composer require --dev palantirnet/drupal-rector

Nope, still some of the same issues as in the beginning:

 Loading composer repositories with package information  Updating dependencies (including require-dev)  Your requirements could not be resolved to an installable set of packages.

  Problem 1

     - Installation request for palantirnet/drupal-rector ^0.5.1 -> satisfiable by palantirnet/drupal-rector[0.5.1].      - Conclusion: remove phpstan/phpstan 0.11.12      - Conclusion: don't install phpstan/phpstan 0.11.12      - rector/rector-prefixed v0.3.5 requires phpstan/phpstan ^0.11.19 -> satisfiable by phpstan/phpstan[0.11.19].      - palantirnet/drupal-rector 0.5.1 requires rector/rector-prefixed <0.7.19 -> satisfiable by rector/rector-prefixed[v0.3.5, v0.6.10, v0.6.12, v0.6.13, v0.6.14, v0.6.2, v0.6.4, v0.6.5, v0.6.7, v0.6.8, v0.6.9, v0.7.0, v0.7.1, v0.7.10, v0.7.11, v0.7.12, v0.7.13, v0.7.14, v0.7.15, v0.7.16, v0.7.17, v0.7.18, v0.7.2, v0.7.3, v0.7.4, v0.7.5, v0.7.6, v0.7.7, v0.7.8, v0.7.9].      - Can only install one of: phpstan/phpstan[0.11.19, 0.11.12].      - rector/rector-prefixed v0.6.10 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.6.12 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.6.13 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.6.14 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.6.2 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.6.4 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.6.5 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.6.7 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.6.8 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.6.9 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.0 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.1 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.10 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.11 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.12 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.13 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.14 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.15 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.16 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.17 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.18 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.2 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.3 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.4 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.5 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.6 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.7 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.8 conflicts with phpstan/phpstan[0.11.12].      - rector/rector-prefixed v0.7.9 conflicts with phpstan/phpstan[0.11.12].      - Installation request for phpstan/phpstan (locked at 0.11.12) -> satisfiable by phpstan/phpstan[0.11.12].  Installation failed, reverting ./composer.json to its original content.

Step 4

So let’s dive deeper. Looking at the Drupal Check’s composer.json, we can see phpstan is listed as a dependency, so why are we including phpstan in our own composer.json?

 "phpstan/phpstan": "^0.12"

Well, that’s on the latest (master) version of Drupal check:

https://github.com/mglaman/drupal-check/blob/master/composer.json

Running this command, we can see the version of Drupal check we’re currently running is:
./vendor/bin/drupal-check –version

Drupal Check 1.0.13

So, let’s check this version’s composer.json instead:

https://github.com/mglaman/drupal-check/blob/1.0.13/composer.json

We can see it’s still 

 "phpstan/phpstan": "^0.11.9"
 Update phpstan Loading composer repositories with package information  Updating dependencies (including require-dev)  Package operations: 0 installs, 1 update, 0 removals  Gathering patches for root package.  Gathering patches for dependencies. This might take a minute.    - Updating phpstan/phpstan (0.11.12 => 0.11.19): Loading from cache

Now we have the right version we’re needing for Drupal Rector.

 Loading composer repositories with package information  Updating dependencies (including require-dev)  Package operations: 3 installs, 0 updates, 0 removals  Gathering patches for root package.  Gathering patches for dependencies. This might take a minute.    - Installing rector/rector-prefixed (v0.3.5): Loading from cache    - Installing jawira/case-converter (v1.2.0): Loading from cache    - Installing palantirnet/drupal-rector (0.5.1): Loading from cache

Success!

So that seems fishy — because Drupal Check has a dependency of phpstan ^0.12, but we already have a phpstan 0.11.9 in our composer.json file. Why do we even have phpstan listed in our “require-dev”?

So next, we’re going to try unwinding some things and see if we can get this working.

Step 5

Let’s first remove Drupal Check:

 composer remove phpstan/phpstan

This results in a few updates, most notably phpstan being updated to 0.11.12, which matches to the ^0.11.9 constraint set forth for the version of Drupal check we’re using.

 Updating dependencies (including require-dev)                                                                           Package operations: 0 installs, 13 updates, 0 removals  Gathering patches for root package.  Gathering patches for dependencies. This might take a minute.    - Updating ocramius/package-versions (1.4.0 => 1.4.2): Loading from cache    - Updating symfony/debug (v3.4.39 => v3.4.40): Loading from cache    - Updating symfony/finder (v3.4.39 => v3.4.40): Loading from cache    - Updating symfony/console (v3.4.39 => v3.4.40): Loading from cache    - Updating nette/utils (v3.0.1 => v3.1.1): Loading from cache    - Updating nette/schema (v1.0.0 => v1.0.2): Loading from cache    - Updating nette/finder (v2.5.1 => v2.5.2): Loading from cache    - Updating nette/robot-loader (v3.2.0 => v3.2.3): Loading from cache    - Updating nette/php-generator (v3.2.3 => v3.3.4): Loading from cache    - Updating nette/neon (v3.0.0 => v3.1.2): Loading from cache    - Updating nette/di (v3.0.1 => v3.0.3): Loading from cache    - Updating nette/bootstrap (v3.0.0 => v3.0.1): Loading from cache    - Updating phpstan/phpstan (0.11.9 => 0.11.12): Loading from cache

And we know that this php-parser package was added manually as well, similar to how phpstan was added manually, so we can remove it too. There is no reason to add these dependency packages manually, we can just let Composer manage them.

 composer remove nikic/php-parser
 Running that results in this output: Updating dependencies (including require-dev)                                                                           Package operations: 0 installs, 1 update, 0 removals  Gathering patches for root package.  Gathering patches for dependencies. This might take a minute.    - Updating nikic/php-parser (v4.0.2 => v4.4.0): Loading from cache

Using Composer why nikic/php-parser, we can see why the nikic/php-parser package is needed

phpstan/phpstan                    0.11.12  requires  nikic/php-parser (^4.0.2)

phpstan/phpstan-deprecation-rules  0.11.2   requires  nikic/php-parser (^4.0)

psy/psysh                          v0.9.9   requires  nikic/php-parser (~1.3|~2.0|~3.0|~4.0)

Step 6

Let’s upgrade Drupal check

 composer update mglaman/drupal-check --with-dependencies  Updating dependencies (including require-dev)                                                                           Package operations: 0 installs, 3 updates, 0 removals  Gathering patches for root package.  Gathering patches for dependencies. This might take a minute.    - Updating phpstan/phpstan (0.11.12 => 0.11.19): Loading from cache    - Updating symfony/yaml (v3.4.39 => v3.4.40): Loading from cache    - Updating mglaman/drupal-check (1.0.13 => 1.0.14): Loading from cache

Ah ha! It looks like we’re now on the right version of phpstan 0.11.19 that will support us in adding the Drupal Rector

Let’s try adding Drupal Rector again now:

 composer require --dev palantirnet/drupal-rector  Updating dependencies (including require-dev)                                                                           Package operations: 3 installs, 0 updates, 0 removals  Gathering patches for root package.  Gathering patches for dependencies. This might take a minute.    - Installing rector/rector-prefixed (v0.3.5): Loading from cache    - Installing jawira/case-converter (v1.2.0): Loading from cache    - Installing palantirnet/drupal-rector (0.5.1): Loading from cache

Remember back to the first Composer issue we looked at with the “rector/rector-prefixed” package? We can now see that Rector was successfully able to add it.

 Gathering patches for dependencies. This might take a minute.    - Installing rector/rector-prefixed (v0.7.18): Loading from cache    - Installing jawira/case-converter (v1.2.0): Loading from cache    - Installing palantirnet/drupal-rector (0.5.1): Loading from cache

And there are currently no other Composer issues being thrown at us.

The Final Step for a Clean Solution

We discovered that local dependencies were being locked to a specific version and by removing those, Composer was able to correctly reconcile the dependencies for these packages. This is somewhat dependent on and specific to your own build processes and environments, but you should be set to run Drupal Check and Rector and begin your journey and preparations for Drupal 9.

Final cleanest, best solution in our opinion…

Packages added manually, but should have just been added as dependencies and managed by Composer:

 composer remove phpstan/phpstan  composer remove nikic/php-parser    Updated drupal-finder  composer update webflo/drupal-finder  Loading composer repositories with package information  Updating dependencies (including require-dev)  Package operations: 0 installs, 1 update, 0 removals  Gathering patches for root package.  Gathering patches for dependencies. This might take a minute.    - Updating webflo/drupal-finder (1.1.0 => 1.2.0): Loading from cache    composer update mglaman/drupal-check --with-dependencies  Loading composer repositories with package information  Updating dependencies (including require-dev)  Package operations: 0 installs, 5 updates, 7 removals    - Removing phpstan/phpdoc-parser (0.3.5)    - Removing nette/schema (v1.0.2)    - Removing nette/robot-loader (v3.2.3)    - Removing nette/php-generator (v3.3.4)    - Removing nette/di (v3.0.3)    - Removing nette/bootstrap (v3.0.1)    - Removing mglaman/phpstan-junit (0.11.2)  Gathering patches for root package.  Gathering patches for dependencies. This might take a minute.    - Updating phpstan/phpstan (0.11.12 => 0.12.23): Loading from cache    - Updating phpstan/phpstan-deprecation-rules (0.11.2 => 0.12.2): Loading from cache    - Updating symfony/yaml (v3.4.39 => v3.4.40): Loading from cache    - Updating mglaman/phpstan-drupal (0.11.10 => 0.12.3): Loading from cache    - Updating mglaman/drupal-check (1.0.13 => 1.1.1): Loading from cache    composer require --dev palantirnet/drupal-rector

Still not confident about your preparedness to upgrade, or short on time or team capacity? We can help you get ready for Drupal 9

This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

Mediacurrent: Debugging Composer Dependency Conflicts

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.