This is a child issue of #2982674: [meta] Composer Initiative Phase 1: Add composer build support to core
Problem/Motivation
Given a normalization to Composer-based site building, we need a tool to convert non-Composer-based sites into Composer-based ones.
We're targeting 'tarball' style installs, which have downloaded Drupal from the download page of drupal.org, and have then installed in place.
We want a core-native tool which can be easily used to reliably make a composer.json file, ideally without much user intervention.
Proposed resolution
Since Drupal tarball downloads will be Composer-ready out of the box, and updating a Drupal site via drush pm-update essentially involves swapping out (parts of) your current code with the latest tarball download, so for folks who do not have any contrib modules, converting to Composer-managed will be a simple matter of running "composer update". Folks who do have contrib modules will need their composer.json adjusted post-update.
There are three stages:
- Validate: The site must be using
drupal/core-composer-scaffold, and must have contrib modules on disk that are not listed in the composer.json file. (If either of these things is not true, then the tool does nothing.) - Prompt: In a Composer pre-update script (or perhaps post-update), conspicuously warn the user that: a) they cannot go back and use `drush pm-update` any longer, and b) their existing contrib modules will be added to their composer.json file (if available on Packagist).
- Convert: If the user confirms, run a version of composerize-drupal ported into drupal/drupal project. If they decline, print a warning that `composer update` is not updating their contrib modules.
composerize-drupal is already a Composer plugin, so it probably will not need a lot of work to convert it to this workflow. If we add it to the composer/Plugins directory, then it will be subtree split into a separate component, and can be added to drupal/legacy-project, where it will also become part of the tarball downloads. (Alternately, we could consider adding it during the tarball bundling process, since this tool is not necessary for sites created via composer create-project drupal/legacy-project.)
Remaining tasks
- [ ] Port grasmash/composerize-drupal to composer/Plugins directory.
- [ ] Remove functionality of composerize-drupal' that is no longer necessary (replacement of root composer.json with a template version, relocation of files to "web" directory, etc., where such things have already been provided by the Composer-ready download).
- [ ] Warn the user at `composer update` time that they've started out on a one-way trip.
- [ ] List contrib modules converted, add them to composer.json, remove them from repository in their old location,
- [ ] Optional. Remove the conversion plugin after it has converted the contrib modules.
Follow-on tasks
There are other things that folks might wish to do that could be handled in follow-on work.
- Convert from older Composer-managed template projects (e.g. drupal-composer/drupal-project sites still using drupal-composer/drupal-scaffold).
- Convert from drupal/legacy-project layout to drupal/recommended-project layout.
- Add a rational .gitignore file, perhaps assuming vendor is committed, or perhaps assuming it is not. Remove any ignored files that are currently committed to the repository.
- Convert a non-Composer-managed site to a Composer-managed site without updating the version of Drupal Core or contrib modules used (perhaps even for pre-8.8.0 versions, although most likely only Composer-ready sites will be supported at first).
User interface changes
None.
API changes
None.
Data model changes
None.
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #48 | 3047468_48.patch | 130.03 KB | mile23 |
| #43 | interdiff.txt | 9.61 KB | mile23 |
| #43 | 3047468_43.patch | 107.73 KB | mile23 |
| #40 | interdiff.txt | 5.28 KB | mile23 |
| #40 | 3047468_40.patch | 105.29 KB | mile23 |
Comments
Comment #2
tormiMy current workflow is `drush generate-makefile example.make` > `drush make-convert example.make --format=composer > composer.json` > copy component's from generated composer.json to list into drupal-project's composer.json + adjustments.
Comment #3
imclean commentedSee also: https://github.com/grasmash/composerize-drupal
Comment #4
mile23Thanks for the links.
This issue is postponed on #2982680: Add composer-ready project templates to Drupal core, which is where we'll make the target template this tool will convert to.
Comment #5
aaronmchaleAgree with @Mike23 in #4
Comment #6
grasmash commentedOf course, I'm partial to https://github.com/grasmash/composerize-drupal. I believe that it works for most use cases. It has 94% test coverage and I consider it stable.
Comment #7
MixologicComment #8
greg.1.anderson commentedAdded a proposed resolution and a list of remaining tasks to the issue summary.
As follow-on work, we could consider dropping a Drush 8 policy file into the site to protect it from future pm-update shenanigans. If the user has not converted their contrib modules, they could continue to update them with Drush. In this scenario, after the user has run `composer update` at least once, the policy file could protect the site by forcing the `--no-core` option to be set. Once the user has converted their contrib modules, the policy file could simply prevent `pm-update` and related commands from running on the site at all.
The policy file could either be added by the conversion tool, or we could make it a persistent part of Drupal, and have it decide what action to take at runtime by inspecting the site and seeing if it has been converted.
Comment #9
greg.1.anderson commentedNote that there are a few features of Composerize Drupal that will no longer be necessary when working with Comoser-ready Drupal sites.
Comment #10
MixologicAh. I had forgotten about the situation where somebody starts with the composer ready tarball, and then installs modules manually, and then needs to become a composer based site.
We'll still need a composerize mechanism to 'convert' those sites for people.
Comment #11
naheemsays commentedWill the plugin be able to "fix" the situation where a composer based drupal has had a module manually updated?
If that is the case, the plugin will remain useful after initial use.
Comment #12
greg.1.anderson commentedI am wary as to the safety/reliability of fixing a manually updated module. Are we sure the module was manually updated, or was it patched with cweagans/composer-patches?
I think the "repair" operation is to have the user manually remove the tainted modules, and then run
composer install. I don't think we should do this automatically.Comment #13
mile23#2982680: Add composer-ready project templates to Drupal core is in, so unpostponing here.
Comment #14
grasmash commentedCurrently, https://github.com/grasmash/composerize-drupal will scan for contrib modules and populate the composer.json require array. It will also scan for patches and populate the patches array.
To answer your question:
We could easily add an additional command to https://github.com/grasmash/composerize-drupal that *only* scans for contrib modules and updates the require array. The command could be manually run even after an application has been "composerized."
Comment #15
naheemsays commentedThat would be a useful option because I expect us non experts (or sites with multiple levels of contributors) to make such mistakes, so a way to repair the damage would be useful.
Comment #16
mile23Just want to draw attention to this use case: #3082958-36: Add gitignore(s) to Composer-ready project templates
Comment #18
mile23Based on Slack chat, some specs:
We def want to warn people that they're using drupal/drupal.
We also want to warn people who are using drupal-composer/drupal-scaffold, webflo/drupal-core-strict, webflo/drupal-core-require-dev. They should switch over to drupal/core-composer-scaffold and drupal/core-recommended.
Comment #19
aaronmchaleThat sounds like it might covers something I was wondering, because many people (myself included) typically setup sites using
drupal-composer/drupal-project, so it sounds like this tool would make it simple to convert a site which started with that to usingdrupal/core-recommended, or at the very least provide documentation to accomplish that?Comment #20
greg.1.anderson commentedYes, switching to the new Composer plugins should be pretty easy. See https://g1a.io/cic, which contains an overview.
We could warn users on old components by submitting a PR to drupal-composer/drupal-scaffold, and just start printing a big warning message every time it runs.
Comment #21
aaronmchaleThat's a handy presentation and overview, thanks.
Sounds like a good idea.
Comment #22
mile23This is *not* a tool to convert your composer.json file.
This is a status tool which ends up saying things like this:
The reason this patch is being offered is so that you, whoever you are, can review the code and develop an opinion about which things it checks for and what it tells you to do about them.
You could try modifying the composer.json file in your root to various edge cases you think I didn't consider, and then running the tool, and then having an opinion about the result.
Once you have that opinion, your review can say what should be added, or what's wrong here, and then we can update the list.
Then, eventually, we can transform the list of to-dos into things the machine does.
Yes, I know this inadvertently promotes symfony/finder out of the dev requirements. This is a prototype. :-)
Important other specs to contemplate:
composer global require drupal/core-composerizer-tool-whatever-we-end-up-naming-itand then saycomposer drupal-composerize --working-dir /arbitrary/directoryComment #23
grasmash commentedThis seems so similar to composer validate that I wonder if we can extend that command with Drupal specific inspections.
Comment #24
mile23For a status type readout yah, it's very similar to validate.
Asking for edge cases, please. :-)
Comment #25
webchickI am probably a subset of the target audience for this feature since I've been using tarballs since the 90s :P ... for me, I would need more information on each of these points, for it to be really useful to me and for me not to feel blocked/stuck.
Comment #26
greg.1.anderson commentedI think that #22 is useful as a step on the road toward implementing the use-case described in the issue summary. As such, I think that its target audience is developers working on this issue.
I think that the best way to address the questions in #25 is to continue the implementation to automate the conversion process.
Comment #27
webchickAh, ok, fair enough. :) Carry on, then!
Comment #28
mile23Here's another patch.
This one *does* add the tool to core. :-)
It is highly development-centric, and has opinions about how to dev this plugin. IOW: Do not RTBC. :-) I'm not even wasting the resources to run DrupalCI on it.
If you want to see what it does, then you can use it globally from the mirror I made: https://github.com/paul-m/core-composer-converter
The way you do that is as follows:
Now you can navigate to a Drupal installation somewhere and perform the conversion. As always: Make backups and/or use git.
Note that it will discover extensions you add.
Don't want all those modules listed individually? Let's require them by d.o project (so that we'll require drupal/examples instead of all the individual modules):
And finally, let's reconcile extensions which don't have a d.o project.
Much remains to be done, but please try it out and see if it breaks or doesn't, and whether it irks you in some way.
Comment #29
mile23This is a little more together than #28. It still does things like remove the vendor hardening plugin from drupal/drupal, so that I could set up an automatic build script that relies on ./vendor/bin/composer running.
As in #28, it's also mirrored through packagist, so you can do this:
It will behave mostly the same as in #28, but you'll also see this when you do
composer installorcomposer update:And then you can run that command:
Currently it does not actually remove the existing extensions from the file system.
Any code or conceptual review would be helpful.
Comment #30
mile23Also related from the patch in #29: #3095809: Add a factory method for BuildTestBase's copyCodebase() Finder object.
Comment #31
greg.1.anderson commentedWhy do you have Composer as a dependency of the site in this scenario? This is unusual.
I'll try to give this a spin pretty soon.
Comment #33
mile23Re #31: In netbeans you have to have a full path to a script in order to run it when you click on 'run,' and that was the easiest way. I mentioned it because it's unusual and is one reason this is still WIP.
Comment #34
mile23Updates, refinements, cleanups, etc.
You can test drive with:
Navigate to your Drupal site with a bunch of non-Composer-managed extensions and do this:
The current issue I'm finding is that my reference site uses the date module. The date module has an .info file instead of an .info.yml file. So therefore, I have to add that as a way to discover extensions.
Comment #35
mile23Elevating to major based on critical status for #3101968: composer update removes core
Comment #36
mile23The latest updates and stuff. :-)
Comment #37
mile23Bad patch in #36.
Comment #38
mile23Reverts composer.lock file to 8.9.x from #37.
Marking everything @internal because Composer plugins should not fall under the Drupal core API rules.
If you try to use a Composer plugin package as a base class for your changes, you'll discover that you automatically inherit their events and behaviors before your subclass can do anything. Basically: Composer plugins must be forked if you want to change them.
Comment #40
mile23Oh yeah, I added a src/ directory for... reasons. And that should go away for consistency with other plugins and stuff. Also some metapackage cleanup and so forth.
Comment #42
dwwHaven't tested or closely reviewed anything in here. Just flagging that #40 needs work not just for the failing test, but also for CS warnings:
Comment #43
mile23Thanks, @dww.
Fixed failing tests, and a good thing too. Also fixed CS.
Build tests are the best. :-)
Comment #44
dwwRe: #43: sweet, thanks. I see in the interdiff that the "CS" violations were actually commented-out code. Good move removing it entirely. However, I think we want a follow-up issue for the @todo comment, and add a @see pointing to it.
Hope to get a chance to give this a spin and a more careful review in the coming days...
Cheers,
-Derek
Comment #45
hotwebmatter commented+1 for
mile23/core-composer-converter, which just helped me to convert a client site from a tarball into a standalone git repo, with all its dependencies managed by Composer and all its tooling encapsulated by Lando.There was a lot more to that than just running this tool (and the documentation out there offers many different options!) but this tool provided a valuable service.
I just pulled the repo on a different laptop, unzipped a tarball with the contents of
web/sites/default/filesfrom production, ranlando startandlando db-import, and practically jumped for joy when the local copy started up.Now that I’ve beaten the
landoandcomposerlevel bosses, the next step is figuring out a Continuous Integration strategy that does not require subscription fees for private repos. (I'm leaning toward GitLab-CI, but open to suggestions.)Note: once you've got your
composer.jsonthe way you want it, you can probably remove this from core since it serves no other function.Comment #46
imclean commented#45,
Bitbucket has Pipelines for CI/CD and has unlimited private repos. We haven't used it as we use a different service but it might work for you.
Comment #47
greg.1.anderson commentedUpdating issue summary per discussion with @mile23 on slack. My update didn't go quite as discussed, but I did follow the general goal of rewriting the goals of this issue to do only one thing, and make that one thing the MVP for the Composer conversion tool.
Comment #48
mile23Ok, we're trying to narrow the scope here so the patch can be reviewable. :-)
We have a number of things going on...
It's clear that we want a tool that can look for non-Composer-y extensions and then add them. This is not terribly difficult for extensions on the Drupal Composer facade.
When we do that, we also have to make sure that the Drupal Composer facade is also a repository in composer.json.
And also when we do that, we have to make sure that composer/installers is present, so it can place the extensions in a reasonable default place.
Then we also delete the user's copy of those extensions that we replaced.
Then we can optionally perform the install/update phase.
Keep in mind this is the *limited scope* version of this plugin. :-)
So I present a patch that is still WIP, and which is required in drupal/drupal, just so we can see it in action. This is not the final patch, but you can see it work like this:
composer installdrush dl examplescomposer installcomposer drupal:reconcile-extensions --dry-run --prefer-projectsUp in the IS we see this requirement (which I disagree with, but more on that later):
So let's see that in action. Given that you've performed the above steps, do this:
composer remove drupal/core-composer-scaffoldcomposer drupal:reconcile-extensions --dry-runYou should see this message:
Since we also need the Drupal Composer facade, we can do this to remove the facade from our composer.json:
composer config --unset repositories.0composer drupal:reconcile-extensions --dry-runWhich results in this message:
So, as to the requirement for drupal/core-composer-scaffold in the first place... I think it's good to limit our use-cases as much as we can so we're not chasing our tail here. But it's also true that a pre-8.8.0 tarball won't have that package in it, and there's no benefit in only adding the scaffolding plugin. If our scope is limited only to picking up stray non-Composer extensions, then we shouldn't care if the project is scaffolded or not.
Nevertheless... Here's the patch. It might have extra cruft that I didn't delete after this narrowing of scope, and it has plenty of @todos left. But it's late on Sunday.
Comment #49
mile23Comment #51
ressaIs it possible to go the other way, from Composer-based Drupal 8.8.2 to tarball?
I ask because I want to migrate a site from Drupal 7 to Drupal 8, which is probably easiest done with Composer, but I want to use Automatic Updates, which only works with non-Composer ("tarball") installations ...
Will it require a tool to convert a Composer-based Drupal 8.8.2 installation (assuming no Composer-requiring modules like Solr are used) to a non-Composer-based one, or can it be done by simply downloading the tarball-based file structure (no "web") copy the contrib modules over and run
drush cache:rebuild?Comment #52
greg.1.anderson commented#51: Out of scope for this issue. I'd say the biggest challenge here is that it's more difficult to go back to tarballs if any of your contrib modules have Composer dependencies (at least not easily). There are a number of solutions for managing Composer dependencies without Composer (Ludwig et. al.), so it might be possible to detect-and-repair this.
My motivation for adding the requirement for drupal/core-composer scaffold to be present was so that we could remove the need to have a template composer.json file, and instead just do minor fixups of the composer.json already present in the site. Another way to restate this is that the site must already be on Drupal 8.8.0+ (or perhaps 8.9.0+) before using this extension. While we could consider converting Drupal 8.7.x and even older, there is the additional complication that we have to give the user instructions on adding this tool, etc.
If we instead require the user to `drush pm-update` (or autoupdate) their site to the latest version of Drupal core first, then we know that drupal/core-composer-scaffold is present, composer/installers is present, etc., and anything that is always going to be present is one less thing that we need to do in the patch.
I also think that it would be easiest to have this operate just by running `composer update` (with a prompt before doing anything), although keeping the message-plus-conversion-command is perhaps safer (as we know, running code in a Composer update hook can be dangerous).
Haven't had a chance to look at the actual patch yet. Thanks for pushing this forward.
Comment #53
ressaI agree, and like I stated, going from Composer-based to tarball should ideally only be tried with none-Composer requiring modules.
I just had a go at it, and it went fine. Just copy over modules and settings.php, import the database, run
drush cache:rebuildand you're good to go. I don't want to side track this issue, but insert the steps below (using Lando with Drush 8.2.3) for others who are interested in this:Create Drupal installation with Composer, and export database
Create Drupal installation with Drush ("tarball") and import modules and database
Comment #54
hotwebmatter commentedRe #52:
Based on my recent experience, I agree. I was unable to composerize 8.7.8 tarball until I used
drush pm-updateto upgarde core to 8.8.x version, no matter what tool I used. (I also tried to just do it manually by starting with adrupal/recommended-projectand usingcomposer requireto add my dependencies.)The only way that worked for me was to update the tarball site to the latest version and then use Mile23's core tool.
As ever, your mileage may vary.
Comment #55
greg.1.anderson commentedFor the record, if anyone did have a strong desire to composerize an 8.7.x version of Drupal, what I would recommend is:
1. `drush pm-updatecode` to get to 8.8.0+ (n.b. do not run updatedb)
2. Composerize the site
3. Downgrade `drupal/core-recommended` to 8.7.8 or desired version (and likewise with any pinned module versions)
4. Run updatedb if needed
5. Undo any pins in composer.json from step 3 if necessary
I can imagine a tool to do that, but I think that's out of scope for this issue.
Comment #56
greg.1.anderson commentedSo, I am reviewing this more (still not all the way through), and I'm noticing that this patch is doing a lot of complex things with Composer internals in order to get a good list of modules to `require`. All of this code is hard to review, and furthermore introduces technical debt in that it would require more work to support Composer 2 in Drupal if we had all of this in core.
I am wondering if it would be reasonable to just scan he filesystem for `modulename.info.yml`, and if there is a `project:` entry injected by d.o infrastructure, then we may presume that `drupal/modulename` exists. We could also build a version constraint from the `version:` entry in the same yml file.
For extensions that do not have injected project information (e.g. see the lightning distro), we could check to see whether the project identified in the composer.json file was registered in Packagist. (This is probably a bad example, as Lightning already requires Composer. I'm not sure if there is anything for us to find in Packagist that doesn't require Composer already, so this particular optimization might not even be necessary.)
Anything that didn't meet one of these two criteria could simply be left in the filesystem / repo as an item to fix by hand.
Does that sound like a viable strategy? We could simplify this code quite a bit if we went this route, and put off the more rigorous attempts at discovery for either the contrib tool, or a least a later version of the patch
Comment #57
greg.1.anderson commentedA few more review notes (still incomplete):
If we tighten down our validation (require Drupal 8.9.x+), then we can reduce the number of checks here; composer/installers, for example, will always be present.
I don't think we need to rely on a template. If we validate that we are converting Drupal 8.9.x+, then the project being converted will already have a composer.json that follows this structure. We should read the site's existing composer.json file, validate that it matches our expectations, and then inject the "require" section that we want.
Comment #58
mile23If we're speccing a conversion tool which declares that it only converts core which doesn't need conversion, then I'm not sure why this is even a thing we're doing.
Comment #59
greg.1.anderson commentedMy proposal is that we start with a tool that only does conversion of non-Composer contrib modules into Composer-managed contrib modules for sites that are already Composer-ready. That seems like the right increment of work, and gives most folks a `drush pm-update` -> `composer update` upgrade path. More complicated use-cases can be handled in contrib.
Comment #60
hotwebmatter commentedRe #55:
I wonder if my current problem is caused by running
updatedbtoo soon. I might have to do the whole thing again.Comment #61
mile23We devoted a composer in core initiative meeting to trying to scope this topic: #3115344: Composer in Core Meeting: 02-19-2020
Comment #62
mile23I spent a little time digesting #3115344: Composer in Core Meeting: 02-19-2020
I think the big picture plan here is as follows:
🐮If your site is pre-8.8.0 and you’ve never touched Composer, then you’ll use
drush pm-update(or equivalent set of manual instructions) to get to 8.8.0+. Once you’ve downloaded that tarball, you can now Composer all you want.🍒If you used an earlier community-supplied Composer template, or rolled your own and you want to convert to drupal/recommended-project (or legacy-project), then we have some instructions for you to use. Core can’t promise that your community or bespoke project template will continue to work, but we will have some docs you can follow to get it all working again per core best practices if it breaks.
🐳If you have a Composer-managed site (using a core template or otherwise), you run the risk of having unmanaged contrib extensions in your filesystem. The ‘risk’ here is that you’ll install using Composer and end up without that extension, and then have to figure out what happened. This is the use-case we're covering in this issue.
In that case, we can add a plugin that tells you there are unmanaged extensions. This allows you to reconcile the extensions listed in your composer.json file with extensions in the file system which could be managed by composer.
So now we get to an issue of scope. In addition to discovering this for Drupal core ^8.8, we could also just do this for any Drupal file system.
In this scenario, the user could reconcile extensions for any Drupal site, and get a useful report of what extensions are present. They would
composer require drupal/core-extension-reconcilerif their version of core does not supply it.When I was working on some of the earlier patches, I even discovered a bug in the plugin because I accidentally had D7 extensions in my own personal site. Ewps.
So I propose that the extension reconcile tool be able to do the following:
Comment #63
MixologicNice. Thanks for capturing all that.
So, I think there was one thing lost in translation, but I think it might be immaterial, and only relevant in the documentation side of things:
The main use case I see for this tool is that loose contract we've had with the community where "You do not have to use composer to manage your site unless you require an extension that requires it."
So, theres a large number of folks who are in the category of 🐮above, they've never used composer, they've used drush to manage their site and they're doing fine that way. And then... they need to install a module that does require composer.
So those users are on a 'composer ready tarball' maybe even 8.9.? when they find they need to "Convert"
In any case, all of the proposed solutions above also solve for this use case, so I dont think this alters any of the proposals. But I *do* think the tool should be geared towards a novice to composer, with super clear 'next steps' etc.
Comment #64
MixologicAs a bonus, if this tool exists, we can point to it when/if we ever solve: https://www.drupal.org/project/drupal/issues/2494073 -> tell users hey, you have to use composer now. Sorry. Use this tool to get up to speed.
Comment #65
mile23Comment #66
greg.1.anderson commentedI am kind of -1 on having an "exotic extension registry". The main use-case for keeping this tool installed is to catch mistakes from users who do not fully understand who make a mistake after conversion (e.g. keep using drush dl / drush pm-update). To benefit from this protection, a naive user must:
1. Leave the plugin installed (need to decide how to phrase the "how to remove" documentation, so folks know whether to keep it or not)
2. Understand how to configure the exotic extension registry
3. Bother to configure the exotic extension registry
I think we should simplify further, and only notify about exotic extensions once.
Definitions:
1. Drupal site is not "Composer ready" - drupal/core-composer-scaffold not in composer.json
2. Drupal site is "Composer ready" but not "Composer managed" - using drupal/core-composer-scaffold, but no "drupal/*" contrib extensions in composer.json
3. Drupal site is "Composer managed" - at least one "drupal/*" contrib extension in composer.json.
Definition of a contrib extension:
1. Starts with "drupal/"
2. Is not "drupal/core"
3. Does not start with "drupal/core-"
With those definitions, then, we could:
1. Only warn about exotic extensions when doing the first conversion from "Composer ready" to "Composer managed".
2. Offer to convert sites from "Composer ready" to "Composer managed" on "composer update" / "composer require" (Probably as a follow-on issue, maybe Drupal 9+ only)
As an independent effort, we (ahem, I) could also make Drush dl / pm-update detect "Composer managed" sites and refuse to operate. This would only protect folks who upgrade their Drush, but it would be something.
Comment #67
mile23There is no such thing as the exotic extension registry.
'Exotic' means it doesn't have a project: key in the info file or otherwise can't be found by the composer facade. That's how you figure out if it's contrib or not.
Plenty of sites have lots of 'exotic' extensions, such as custom modules and themes.
The list of ones we've already found will be added to the extra when we do the conversion. Then the user has a handy list of extensions in addition to not having us warn about them.
So you want an interaction like this:
I want an interaction like this:
For
requireI also want to step out of the way unless summoned. If you require drupal/some-contrib-project, you get the same message: Run the thing to reconcile your other modules if you want to.If they require contrib, then they get a warning saying they have both types and it's not great to have both types. But we should let them do that anyway.
I don't want to have to try to explain to a Drupal developer why Composer won't let a developer ad hoc require a contrib module if there are non-composer-managed extensions. If we place that restriction, the solution is to remove the plugin because it's annoying.
If they remove the plugin, then we've failed because they have both composer-managed extension and non-composer-managed extensions *and* no nag to tell them what's about to break.
Comment #68
greg.1.anderson commentedI don't want Composer to stop people with Drush-managed extensions from using
composer require. I might like to go the other way, and breakdrush dlfor sites that have Composer-managed extensions.We could actually do that without changing Drush 8. We'd just have to write a policy file to the site when we convert extensions to be Composer managed (or maybe even when we detect the use of
composer requirewith a contrib module). This is probably not a good idea, though, as it is unnecessary (and therefore annoying) to folks who don't use Drush 8, and is perhaps too aggressive even for those who would benefit.Maybe I'll just update Drush to warn the user whenever using dl / pm-update with a module whose composer.json has a non-empty require section.
This is what I'm calling the exotic extension registry, after the terminology used in #62. I suppose it would work fine to do the interaction steps described in #67, and perhaps warn about exotic extensions the first time they are encountered only (and add them to a list in "extra" after the user is presented with their options).
Comment #69
aaronmchaleRe @greg.1.anderson in #66:
Custom extensions might also define a composer.json where the namespace is "drupal" ("drupal/custom-module"), there's nothing which guarantees they won't. Honestly I've done that myself simply because every extension on D.o does so it kind of subconsciously sets a precedent that a Drupal extension has the namespace starting with Drupal, and because the class path would start with Drupal\custom-extension. Whether it's right or wrong is a different discussion, but my point is "drupal/" doesn't guarentee that a contrib project exists for that extension.
Comment #70
greg.1.anderson commentedMaybe it's pointless to try and make assumptions about the status of an extension based on its name or org. We could get a pretty good notion of which projects are contrib extensions by looking for
# Information added by Drupal.org packaging scriptin the info.yml site. Of course, there's no guarantee that a custom module might have copied that comment from a contrib module and just left it there.It is still my thought that I'd rather make such heavy use of Composer APIs just to determine if an extension is contrib or not. Maybe we could do three checks:
1. Name starts with "drupal/"
2. .info.yml contains information from Drupal.org packaging
3. The url https://dropa.org/project/foo exists, where "foo" is the part of the name afer "drupal/"
No Composer APIs, relatively quick, determines whether the module is a contrib extension. Maybe this is good enough, for less code?
Comment #71
imclean commented@AaronMcHale,
I'm not sure how this would work. Can you update a custom module with
composer update drupal/custom-module?Comment #72
greg.1.anderson commented@imclean The point here is that custom modules should remain in the repository, whereas contrib modules are removed and added to composer.json. So, for example, if a site had only two modules, drupal/ctools and drupal/my-custom-module, both in the modules directory, then ideally we would add drupal/ctools to composer.json (configured to install to modules/contrib) and move my-custom-module to modules/custom.
Comment #73
imclean commented@greg.1.anderson, I understand, I'm just wondering why custom modules would define a composer.json file at all. Could it be used to manage dependencies even if it can't be installed via composer?
One option could be to provide some interactivity. For example, provide a list of discovered modules and ask to confirm any custom modules which couldn't be automatically detected.
Comment #74
aaronmchaleWell, yeah a custom module could define a composer.json if it had specific dependencies, that might be an architectural decision, the custom module might be added to the root composer.json by defining it as a path repository. This also applies (and is probably more useful) when using a custom developed Drupal profile.
Additionally, there might be cases where Drupal modules come from a remote repository that isn't Drupal.org, you can easily define Git repositories, or there might be a private Composer server in use.
All of these are technically valid use cases that probably exist in the wild, some of these I've worked with before.
Comment #77
tedbowadding "Automatic Updates Initiative" tag because we will probably need something like this for some site to use the new Automatic Updates because it will be composer based.