Disclaimer: I haven't been living and breathing Composer for the last few years. I took some much needed time off from Drupal to get an album out and to reestablish some balance in my life. But I'm back in it again, and discovering all the joys and sorrows of our evolving Composer support. I'm not philosophically opposed, and I'm all in favor of the Get Off The Island(tm) movement.
However, either I'm missing something (entirely possible), or the folks who want us to believe Composer solves more problems than it creates love manually fixing merge conflicts in composer.lock and vendor/composer/installed.json.
Assuming I'm not sufficiently Composer-compliant and that I'm doing something stupid, I've just spent the better part of two "work" days reading through nearly every word of each of these posts and issues to understand why things are the way they are and how we're expected to use these tools:
- Using Composer with Drupal (handbook)
- Using Composer to manage Drupal site dependencies (handbook)
- #1975220: Allow a Composer user to manage Drupal, modules, and PHP dependencies with a custom root composer.json
- #2380389: Use a single vendor directory in the root
- #2551607: [meta] Path forward for Composer support
- Using Drupal 8 and Composer (Pantheon.io docs)
- And others...
No where that I can find has anyone brought up a fundamental pain point of trying to use Composer for Drupal sites. While we now have a "root" composer.json that we're supposed to be welcome to modify without being branded as "kitten-killing core hackers", and now that the only way to install certain contribs I need to use is:
composer require "drupal/address ~1.0" (which modifies composer.lock for me, as it should) I'm apparently hereby doomed to a lifetime of merge conflicts in composer.lock.
For example, here's exactly what happened to me...
- Create a new Drupal 8 Pantheon dev site back when 8.2.6 was the latest stable core release
- git clone the site repo to my local dev environment
composer require "drupal/address ~1.0"to get address.module and its dependencies (required)
- git add composer.* vendor modules/address; git commit -m "address (8.x-1.0-rc3)" (I've automated this part with a simple script to parse modules/x/x.info.yml to get the version string). Pantheon requires me to commit everything (including vendor) to git since that's how the platform deploys the code.
composer require "drupal/inline_entity_form ~1.0"(cuz hey, this is the "best practice" now, why not?), run my git commit script, etc.
- ... repeat for the other contribs I need. My composer.json has diverged from core in small and obvious ways. However, composer.lock has diverged in huge ways./li>
- Watch Drupal 8.3.0 come out
- Try to merge the new version of core into my Pantheon git repo
Boom, the last step leaves me with ~60 impossible-to-untangle merge conflicts in composer.lock, since core has touched composer.json, regenerated composer.lock, and pushed the commit as part of the 8.3.0 release. There appears to be no way to recover from this conflict.
Possible (failed) approaches:
A) use git pull/merge -ours when trying to do the merge. Sure, I ignored core's changes to composer.lock and composer.json, but that's obviously not right and will break any code in core that is relying on the latest versions of the dependencies.
B) Use git pull/merge -theirs when trying to do the merge. Sure, I've got core's changes, but I ignored all of mine, and now I have to manually re-run all of those
composer require commands (each of which takes 2-6 minutes to run on my totally decked out new Macbook Pro with 16 gigs of RAM, SSD, and the fastest CPU I could buy), and watch composer re-do a metric crap-ton of work. Then I have to re-commit all that crap.
C) According to various blogs that claim to know, "It's okay, just remove composer.lock and run
composer update", but that totally defeats the purpose of having composer.lock in the first place! Now I've lost all the data about the specific versions of dependencies that 8.3.0 was released with, and (after 10 minutes pass) I watch various core dependencies get updates that I definitely don't want to have to review and verify myself (changes to zendframework, twig, symfony, etc).
D) Painstakingly and manually try to resolve the merge conflicts in an auto-generated file. The diff is around 2500 lines on my project. I refuse to have to do this kind of BS manual conflict resolution every time a new version of core comes out.
I understand that dependency management is hard, and that we want to re-use libraries instead of stuffing duplicate code directly into our modules. But surely there must be a real solution here that I'm missing and hasn't been documented anywhere.
I've been a computer scientist for 20+ years, have worked with Drupal for over 11, and I've been intimately involved with Drupal packaging and release management for most of that time. If I can't figure out how to get a relatively simple D8 site deployed to Pantheon and be able to update the code, it seems to me that Drupal is doomed. :/