Problem/Motivation
Inspired by #3355485: Dependencies should be 'unpacked' to the root composer.json and merged/resolved but I think there might be other situations that can cause a problem.
I did not do an extensive review of the codebase, but issue queue search didn't show up anything.
Steps to reproduce
Scenario A:
Let's assume a fictional module, drupal/module_a
module_a depends on drupal/module_b
A site owner, who hasn't already installed module_b, installs module_a.
At this point, project browser/package_manager will do composer require drupal/module_a adding it to the site's composer.json. drupal/module_b will be added to composer.lock because it's an implicit dependency.
Later on, the module maintainer drops the dependency on module_b because the functionality has been moved into core, or they've made the integration optional, or whatever other reason. They can't add an update to uninstall module_b first because it can still be used in its own right.
When the site owner updates, module_b will be removed by composer, even though it's installed on the site.
Scenario B:
There is another issue, which probably would need similar underlying infrastructure but is in the opposite direction:
Let's say the owner doesn't like module_a and uninstalls it, at this point module_b will still be installed.
Then later they want to update to Drupal 12, but module_a doesn't have a 12.x compatible release.
In this situation with cli composer, I would just run composer remove drupal/module_a and be done - as long as I'd verified it was uninstalled. If you only maintain your site with project browser + automatic updates, this isn't yet an option. It suggests the need for a 'remove' page, where you can actually remove dependencies from composer, when they're not in use.
Proposed resolution
Either of the above cases would require being able to match Drupal modules to projects, which Drupal core doesn't have any support for outside of update status - possibly the update status metadata would be the way.
When a module is installed, we could check which composer project it's in, and whether that composer project is in the root composer.json, and if it's not composer require it at that point to make it an explicit dependency of the site.
Conversely, if we have that logic, we can also show which uninstalled modules are eligible for composer removal (e.g. no modules from a project are installed).
Comments
Comment #2
catchComment #3
penyaskito> Later on, pathauto_extras gets marked obsolete because its features were merged into pathauto, the maintainer empties out the module except for absolute minimum, removing the pathauto dependency in the meantime.
For the first case: A responsible maintainer wouldn't remove the pathauto dependency in the meantime. That's a bug in pathauto_extras, and they need to create a new release with the dependency back.
If in that frame of time someone upgraded, that would remove the pathauto dependency, which would cause a WSOD if I'm right? We might want to check if a module is uninstalled before removing it with composer.
> There is another issue, which probably would need similar underlying infrastructure but is in the opposite direction
The second case is a very good valid point.
The Proposed resolution would fix both cases IMHO.
Comment #4
penyaskitoThere are some edge cases (drupal module + composer packages having different name, composer packages with several modules) that we might need to cover. Not sure how we can track which packages provide which modules.
Comment #5
catch@penyaskito I think the first case could be simplified to 'any release of any module that removes a composer dependency on another Drupal project'. Not at computer but can update later.
Comment #6
catchUpdated the issue summary to be a bit more generic, I think that shows that both examples can be valid.
Comment #7
catchThis is closely related to #3503472: Handle updates for uninstalled extensions.
If a module is uninstalled, automatic updates can't update it, and also project browser can't yet remove it, so there is no way to either remove or update the uninstalled project except via the CLI.