
Deciding to Accept Composer
Published: 8/1/2019
When it comes to Composer adoption, I admit, I’ve been procrastinating. And by procrastinating, I mean completely ignoring my composer.json file and all that it stands for. Until now.
Why the change of heart? For me, using Composer has been analogous to washing the windows in my house. I know I need to do it, but maybe not today. And truthfully, I might have languished in my cozy, outdated ways, had it not been for a job interview packed with Composer questions I simply couldn’t answer. (Try talking intelligently about a tool you’ve pretended doesn’t exist for the past several years. It’s humbling.)
But admitting I needed Composer in my life was only the first, tiny step.
The Situation
I had a Drupal 8 site that was installed with Composer in its development environment days but was later maintained the old-fashioned, tarball way. And the site’s CLI tools were all problematic. Drupal Console threw “Invalid command name” errors, Drush couldn’t find “Config\Environment,” and Composer itself was perpetually “not autoloadable.”
The Plan
- Use a tool like one of these to auto-generate a composer.json file from my existing project:
https://www.drupal.org/project/composerize (opens in new tab)
https://github.com/grasmash/composerize-drupal (opens in new tab) - Fix the CLI tools by researching the errors and following the trails.
Why the Plan Failed
I had 48 browser tabs open, 10 of them were on the same article, and I was seriously considering a career change.
The problem with my plan was #1 – not knowing where to start, and #2 – treating my CLI tool errors as separate, unrelated issues.
Starting with one of the above composerize-tools seemed like a quick and easy solution, but neither tool worked for me.
The Composerize Module promised to provide a composer.json file under admin/reports, but the report never worked; it just complained that the LDAP module didn’t exist. (LDAP most certainly did exist and was configured and working, along with twenty-some other contributed modules. Why balk about LDAP only?)
The Comperserize Plugin couldn’t detect my Drupal core version, despite providing it with the full path to Drupal. And besides, needing to use Composer in order to fix Composer is… well, ironic.
It was beginning to look like it would take more time to troubleshoot these ‘quick start’ tools than it would to actually write a composer.json file by hand. So, I determined a manual file was the way to go, and I switched gears to begin investigating the CLI tool errors.
However, error chasing led me down a rabbit hole of endless depth. At some point, I realized I’d made too many changes to backtrack, and still, nothing was working the way it should. I had 48 browser tabs open, 10 of them were on the same article, and I was seriously considering a career change.
The Actual Plan
There was one theme that kept emerging throughout the Drupal/Composer forums: Drupal had only half-heartedly accepted Composer, and there were repos out there – like the core tarball on Drupal.org - that didn’t truly support Composer. There was also a consensus that the standard for Composer-based Drupal sites was the drupal-composer/drupal-project repo (opens in new tab).
My base project was drupal/drupal (opens in new tab), which I read was a deprecated repo that could not be used with Composer. Additionally, my project structure was confusing, with two sets of core files, one set that was used and updated when core received a patch, and another that… did nothing?? If Drush and Drupal Console weren't working, perhaps it was because my entire project was a non-standard mess.
I had to start over.
Thanks to an incredibly helpful and informative article by Jeff Geerling, the process wasn’t as bad as I thought. https://www.jeffgeerling.com/blog/2018/converting-non-composer-drupal-codebase-use-composer (opens in new tab)
Additionally, I removed any previously-downloaded composer installation files, and looked to this article to start over with installation at the server level: https://getcomposer.org/download/ (opens in new tab)
I deviated from the author’s instructions in that I created a new project in a new directory, while leaving my original project intact for reference. Later, after I was satisfied that everything was copied, I deleted the original project directory and renamed my new directory to mimic the old one.
During the process, I manually typed my ‘require’ statements for contributed modules and confirmed that Composer was writing them to composer.json. I copied all custom modules and themes from my original project to the new one. There wasn’t any information in the article about settings.php or the sites/default/files directory. But since I already had a database, and files/images I wanted to keep, I manually copied those to my new project folder.
I navigated to my new site in a browser, and… Server 500 error.
There some weird module-related errors that I was able to get around by removing the modules (composer remove), clearing the cache (Drush now worked!), and then again requiring the modules (composer require).
After that, I needed to apply any core and module patches (diff patches like this one - https://www.drupal.org/files/issues/2019-06-25/1699378-188.patch (opens in new tab)). Using these instructions (opens in new tab), I manually added the patch requirements to composer.json. Perhaps there’s a CLI way to do this, but at the time, I wasn’t aware of any.
Unlike composer require, which both updates composer.json and downloads/moves module code to the appropriate directory, manually typing something into composer.json doesn’t execute or change anything. Changes are activated when composer update (or composer install) is run against a site.
Similarly, executing the composer update/install command doesn’t do the Drupal stuff, like enabling the modules, or running update.php. These steps still must be done separately. And that’s where I ran into another gotcha…
My project already had a database. It was connected to my newly-composerized site when I copied settings.php. Within that database, all the modules I “required” through Composer were already enabled/installed. Great! That was a time saver – I didn’t have to manually enable things and run update.php.
Except that when I ran composer update, newer versions of the Webforms and Business Rules modules were downloaded. But composer update did so many things, it wasn’t super-obvious to me that there were module updates – and here’s the key – with database changes. So, when my site blew up again with Webform-related errors, I was initially stumped. Following the error trail, I discovered a missing database table, and on a hunch, I ran update.php. Problem solved.
This process made me realize that doing things the Composer Way is a paradigm shift for many of us. Years of downloading module tarballs, FTPing to a server, enabling through the UI, and running update.php in browser can teach one’s brain to think in a certain way, to follow a narrow path, and to want to stay on that path. But going forward, the nuances of Composer and the changes to my workflow are something I must accept and embrace.
Maybe I’ll go home and wash those windows.
