Problem/Motivation
Drupal's components (in the namespace Drupal\Component) all have composer.json files for #1826054: [Meta] Expose Drupal Components outside of Drupal.
For example, here's the Annotation component's composer.json:
{
"name": "drupal/core-annotation",
"description": "Annotation discovery and implementation of plugins.",
"keywords": ["drupal"],
"homepage": "https://www.drupal.org/project/drupal",
"license": "GPL-2.0-or-later",
"require": {
"php": ">=7.3.0",
"doctrine/annotations": "^1.4",
"drupal/core-file-cache": "^8.8",
"drupal/core-plugin": "^8.8",
"drupal/core-utility": "^8.8"
},
"autoload": {
"psr-4": {
"Drupal\\Component\\Annotation\\": ""
}
}
}
There are several problems with this:
- The PHP version requirement is wrong. Drupal core requires PHP 8.1, so PHP 8.1 syntax may appear in the core components at any time.
- The constraint for Doctrine is out of date for D10; 10.0.x requires
^1.12. - The specified versions of other components are also wrong and/or broken. Very bad things would certainly happen if you tried to install the 8.8.x version of the Plugin component with parts of Drupal 10. I think the most we could guarantee is that they work with each other within the same major version. (Actually, this means they're all incorrect in Drupal 9 too, because they say
^8.8rather than^8.8 || 9.)
There is also no set of expectations anywhere that I could find about the support, BC, and ugprade path policies of the theoretical standalone packages that would come from these composer.json files. Nor has anyone reported the D9 components' packages being broken with unresolvable dependencies.
Proposed resolution
Either get rid of these files, or come up with a way to make them maintainable.
-
One possibility is to write a script or something that at least updates them automatically for when a new major version is branched.
-
That's still not a complete solution because they also would potentially need to be updated every time core increases a requirement for an external dependency they have a constraint on, which could happen in any minor or patch release.
-
Additionally, the external dependencies would need to be updated between releases. For example,
doctrine/annotationis going bye-bye in Drupal 10. (TBD whether this component will go along with it, or just be rewritten for the PHP attributes implementation, but other for other components it'd be easy to miss that removing a use statement might also mean needing to update thecomposer.jsonfile.)
Remaining tasks
TBD
User interface changes
N/A
API changes
TBD
Data model changes
N/A
Release notes snippet
Drupal's Component packages are now semi-automated from drupal/drupal's update script.
The drupal/drupal dev repo now reconciles components' dependencies with those of drupal/core and drupal/drupal during a Composer update command.
This means that dependency constraints declared in the components will always follow the needs of Drupal core.
This step is taken to ease maintainership of these components.
| Comment | File | Size | Author |
|---|---|---|---|
| #41 | 3272110-41-components-10-1.patch | 52.44 KB | mile23 |
| #41 | 3272110-41-components-10-0.patch | 52.44 KB | mile23 |
Issue fork drupal-3272110
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3272110-component-composer-json
changes, plain diff MR !2238
Comments
Comment #2
xjmComment #3
xjmComment #4
xjmCould we add something to
Drupal\Composer::setCoreVersion()to handle this?A bit of a theoretical question is, are the components inter-compatible with each other within the same major regardless of which release is used? Component A could add API that depends on an API addition to Component B, so the old version missing the added API would not necessarily be compatible. Does it mean the components should specify compatibility with only their own minor, then? If so, that definitely needs to be automated.
Finally, with the dependency requirements, is there any way to add a script that would update the dependency requirements of these packages when we do a composer dependency update? We update core dependencies for a reason, and it wouldn't be great to end up with dependency conflicts between versions of the components that supposedly work together.
It'd be better to handle it like Symfony does and release them all at once, but I guarantee they're not updating 23 files by hand to split out the components.
Comment #5
mile23I was working on automating it 4 years ago, but no one seemed excited to try and bring it to DrupalCI: #2876669: Fix dependency version requirement declarations in components
My little project might be an easier port now that we're normalized on Gitlab CI. https://github.com/paul-m/drupal_component_tester
Happily boggled that travis-ci is keeping test results from 4 years ago... https://travis-ci.org/github/paul-m/drupal_component_tester/builds/54437...
Also, it might be that a component is totally OK with using an older version of PHP, having no code specific to a newer version. Obviously keeping track of all that is an extra layer of annoying, but it could be somewhat automated as above.
It seems like we could generate some dependencies similar to the way way we generate the Composer metapackages. This would be easier if there were a policy that said: "All components inherit environmental dependencies from core, always." :-)
Comment #6
mile23Comment #7
quietone commentedAdding related issue.
Comment #8
mile23Related: #3103918: [policy + docs] Decide on backwards compatibility policy for Composer plugins in Drupal 8
Comment #9
mile23Assuming that the constraints of all components should match whatever core's doing at the time, here's a handy patch to discuss.
Basically this patch emulates the template generators and merges core's dependencies where they exist.
It does this on
composer update.It assumes that if we're in a dev branch, then the components also should have minimum-stability: dev.
We'll see some fails for Render and Utility, because it's a pain to set up a path repo to a dependency when the dependency depends on YOU, within a non-versioned branch. #2958358: Remove Drupal\Component\Utility's dependency on Drupal\Component\Render short-circuits that issue if we fix it.
If this is the right direction, we can devote more time to it.
Comment #10
andypostI recall someone from commiters used to create scripts to bump versions, it could be used too
Comment #11
joachim commentedThis looks like a good start.
Though rather than decoding the composer.json ourselves, couldn't we get the data from generateMetapackages()'s $event parameter?
generateMetapackages() will need a rename as well, as it'll be doing more. Or, better still, we could add a 2nd post-update-cmd event.
I am wondering if it's possible to run a shell `composer` command in the Component folder and issue a 'composer require' in there, with parameters based on the $event.
Comment #12
mile23Thanks, folks.
The scope here is: The components' composer.json files need to be maintainable, and they need to have the same dependencies as core where there's overlap.
@joachim: "Though rather than decoding the composer.json ourselves, couldn't we get the data from generateMetapackages()'s $event parameter?"
That's a good thought, but I'd rather not refactor PackageGenerator for this, because I'd want to it similar to ComponentGenerator. Once we have the general shape set up for maintainers' needs, we can optimize, or use a follow-up.
The other reason is that we analyze both drupal/drupal and drupal/core. We get the lock file for drupal/drupal, and the package file for drupal/core.
So this is a demo of the fact that we can automate this. Now we have to say what the BC policy is for components. #3103918: [policy + docs] Decide on backwards compatibility policy for Composer plugins in Drupal 8 does not address Components, and it might be a shame to rescope after it's essentially done.
Comment #13
mile23Woop found another one: #3179197: Drupal components depend on ^8.8 even in their Drupal 9 version
Also in #3179197-15: Drupal components depend on ^8.8 even in their Drupal 9 version @xjm links to the release script. In particular this bit looks like it's supported here: https://github.com/xjm/drupal_core_release/blob/main/tag.sh#L76
Comment #14
xjmPatch needs a couple PHPCS fixes in order to run tests:
Comment #15
mile23CS issues addressed.
Some stuff from #11 addressed.
Here's what it looks like when you run it:
Adding 'needs change record,' if for no other reason than the composer.json files generated here tell the user that they're automatically generated, and we need a document to reference.
Comment #16
mile23No one but myself to blame, I suppose. :-) One line interdiff omitted.
I really need to learn to do the MR style contribution with d.o.
Comment #18
mile23Updated IS with proposed change record info.
This script will apply the following changes to components' composer.json file during
composer update:^major.minoris used, such as^9.5for other component dependencies.\Drupal::VERSION, following the example of the metapackage generator.minimum-stability, this key is not added to components. The exception is any component which requires another component, in a non-stable release. This allows us to test that the components can require each other in non-stable releases.We also have two tests.
One crawls through the components and does
composer installfor each one, in order to make sure it works.The other ensures that the version set in
\Drupal::VERSIONis the same version that ends up in the component dependencies. Similar to the metapackage generator, this supports the tagged deploy script at https://github.com/xjm/drupal_core_release/blob/main/tag.shTo see it in action, check out the issue fork and issue these commands:
Still to do:
Comment #19
andypostOne more usage of finder but still as -dev dependency
Hiding patches as MR used, overall looks great 👍
Adding as @xjm.is the best person to deal with tagging process
Comment #20
mile23Hmm. I was curious if this would break when we don't install dev, after the comment above.
So it seems that we can break the process with this:
Note the
--no-dev.So this exists because drupal/drupal says this:
And during the no-dev update, we see errors like this:
This comes from #3076234: Relocate Scaffold plugin outside of 'core' directory to try and isolate the scaffold plugin.
What's odd is if I merge the autoload-dev into autoload and regenerate the autoloader, I can use the component generator with the proper outcome, even though symfony/finder is not present. Nothing else depends on it.
Anyway, overall, we might decide this matters or we might decide it does not. If it matters, we can merge autoload-dev into autoload, or some other solution, even in a follow-up.
Comment #21
mile23Adding needs followup for @xjm's comment above and #20 as well.
Adding a whole component just for one regex seems like a lot, so maybe that's a followup too, to find other tricky semver use-cases and consolidate them.
Comment #22
mile23Follow-up #1: #3280399: Mark drupal/core-bridge 9.5.x as abandoned
It turns out that the Laminas deprecation mentioned by @xjm supports a class which is deprecated for removal in D10 anyway, and it's the only class in the drupal/core-bridge component.
Comment #23
mile23Follow-up #2: #3280402: Consolidate SemVer-Related Functions To One Place
Comment #24
mile23Updated the MR so that if a component has a require that's not in the drupal/drupal lock file, it gives you a handy red line of text about it.
Like this:
Comment #25
mile23Followup #3: #3280415: Metapackage Generator Breaks Under Composer --no-dev
Comment #26
mile23Comment #27
xjmComment #28
mile23In Slack, @xjm mentions the MR doesn't apply to 10.x, so it needs a reroll for that, probably as a patch.
Still to do: Add CR, link to CR from generated composer.json files. I don't think we need a doc page for that at this point.
Comment #29
mile23Draft change record: https://www.drupal.org/node/3293830
Comment #30
mile23Patches for 10.0.x and 10.1.x.
Comment #31
spokjeNice work and long overdue IMHO.
The only nit I can find is (on all patches/MR):
I think the age of IRC has passed and the line
"irc": "irc://irc.freenode.net/drupal-contribute",can be removed from all four occurrences.Comment #32
mile23Removes IRC links. Probably fair. :-)
Patches attached.
Comment #33
spokjeThanks @Mile23, and bonus kudos for noticing that
drupal/core-bridgeis heading The Way Of The Dodo.Comment #34
spokjeCome to think if it, that (the marking abandoned and removing of
drupal/core-bridge) might be worthy of its own, separate CR?Comment #35
mile23I didn't notice, the script did. :-) That CR is here: https://www.drupal.org/node/3258656 but it's not pertinent to this.
Comment #36
spokjeOutwitted by scripts and already existing documentation, story of my life... ;)
Comment #37
spokjeGreat work @Mile23!
Added (a few?) suggestions on type-hinting, line-length and a (feeble) attempt at DRY-ness.
Besides all these nits, the functionality looks fine to me.
Comment #39
ravi.shankar commentedHere I have tried to resolved the threads of MR, please review.
Comment #40
spokjeThanks @ravi.shankar, but the changes should also be made in the
10.0.xand10.1.xpatchesComment #41
mile23Updated the MR branch with current 9.5.x, generated patches for 10.0.x and 10.1.x.
Comment #42
spokjeLet's see what Core Committers and Framework managers think.
Comment #43
megachrizI created a related issue that is targetting 9.4.x-dev specifically, because this bug prevents me to update some sites to Drupal 9.4.4 now.
#3301254: Not be able to update to Drupal 9.4.4 because some Drupal 9 components require Drupal 8 components
Comment #44
catchUntagging for needs framework manager review because I just reviewed it. I feel a bit like we've created lots of problems for ourselves without any benefit for ourselves (at least not yet) by having components set up the way they are in the first place, but this patch overall improves things.
Committed/pushed the respective patches to 10.1.x and 10.0.x, but this needs a re-roll for 9.5.x
Comment #45
andypost9.5 looks ready
Comment #47
catchThank you, committed/pushed the 9.5 MR too.
Comment #50
xjmCR published.