Problem/Motivation
We're still following through on #1826054: [Meta] Expose Drupal Components outside of Drupal
And we need to be able to test our components independent of Drupal core.
As a very small first step, we need to allow each component to specify it's PSR-4 autoload and autoload-dev sections per composer.json file.
We want each component to define its own namespace.
Since we're merging all of the components' composer.json files during composer install time, their autoload and autoload-dev sections can be used to generate the PSR-4 mappings for each individual component.
Currently, core/composer.json forces all components to be PSR-4 namespaces, which disallows moving source files into subdirectories.
This will open the door to moving the source files of those components into a src/ directory, and also moving the components' test files into a tests/ directory.
We don't actually need to move source files into src/ directories.
Proposed resolution
- Remove the Drupal\Components\ namespace from drupal/core's autoload section.
- Directly require each component in drupal/core.
- Add path repos in drupal/drupal for each component, similar to the way we allow for Composer plugins now.
- Eventually modify build tests so they account for these path repos. #3086644: LegacyProject composer templates wrongly reference 8.x + fix test coverage
Remaining tasks
None
User interface changes
None
API changes
None
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#72 | 2943842_72.patch | 131.55 KB | Mile23 |
Comments
Comment #2
Mile23Here's a POC. It only moves Annotation to a src/ directory, but illustrates that autoloading already works because each component already specifies autoload. :-)
I hadn't remembered that for some reason, so this issue could probably use some re-scoping.
Comment #3
Mile23Comment #4
Mile23Added #2943856: [meta] Reorganize Components so they are testable in isolation, mostly so I could note that we need to move Transliteration/src/data to tests/data when the time comes, and change the tests to use it.
This is all the components moved to src/ with updated composer.json. Also updating core/composer.json to reflect the components' new-found self-naming agency.
Comment #6
Mile23Let's hurry up and get rid of PHP 5 please. :-)
Comment #7
Mile23Comment #8
alexpottI'm not sure this is truly necessary... it's not what Symfony does. They do
One problem is that the regular runtime autoloader should not be able to autoload tests so each composer.json is going to need something like
The one bit of fun is that our test infra is rather bizarre in that it autoloads tests.... however I think I have a solution for that. See https://www.drupal.org/project/drupal/issues/2943856
Comment #9
alexpottI actually think we could merge this issue into the https://www.drupal.org/project/drupal/issues/2943856 rather than do it in two separate steps if we don't have to move all the code into src.
Comment #10
alexpottHmmm... but actually maybe the test move issue should be a meta and we should move each component separately as we should add a PHPUnit.xml.dist to each component and change or maybe removing the TESTING.txt since it is probably overkill once the phpunit.xml.dist is in place.
So let's sort out the autoloader / component composer.json's here. Slightly different tack so no interdiff. It is basically #6 without the file moves and adding ignoring of any Tests folders (which are yet to exist but that does not matter).
Comment #11
Mile23Correct. :-)
When we remove the Drupal\Components\ namespace from core/composer.json's PSR-4 section, that lets the components define their own PSR-4 namespace.
Try it: Apply the patch in #6 (or really #10, either way). Remove an autoload section from one of the component's composer.json. Do a
composer dumpautoload
. Then run the tests:./vendor/bin/phpunit -c core/ core/tests/Drupal/Tests/Component/
You'll see that the autoloading for that component isn't available.I think we want the tests to remain where they are so we can be consistent with the move here, and then move the tests as a separate step.
Given that each component can define its own PSR-4, we can leave the classes at the top level directory, or put the source in a src/ directory. If we put it in a src/ directory, we don't have to exclude-from-classmap for tests later on.
Comment #12
alexpott@Mile23 but we're already inside core's lib directory. Let's follow Symfony's lead and not add extra unnecessary subdirectories. Also not moving the code is just less change (that is not necessary).
Comment #13
Mile23We are inside core/lib, but core/composer.json says this:
So the only PSR-4 autoloading for core is lib/Drupal/Core/ after we remove the entry for lib/Drupal/Component.
Either way is fine, just less hassle later with src/ if we're going to move tests around, since we'll be able to rely on the tests in this issue.
Comment #14
Mile23If we're not going to use src/ then we don't really need to add an exclude for a non-existent directory. In that case we don't really need to change any of the composer.json files other than core.
The only change we might need to a component compser.json would be to add Timer and Unicode to the classmap in Utility's composer.json if we think that's worth the performance improvement.
Comment #15
alexpottFair enough we can add the tests to the exclude when we move them. The files were first hard coded to the class loader in #2253593: Stop classloader searching filesystem for classes before drupal_classloader() is called - i'm not sure we even need to change that here. So this patch becomes a 1 liner :)
Comment #16
alexpottComment #17
Mile23I'd give a little pushback on removing the classmap lines from core and putting them in Utility, but it's not a problem until it becomes one at some point. :-)
Comment #18
alexpottUpdated the issue summary to be inline with current patch.
Comment #20
alexpottTestbot had a hiccup re-rtbcing
Comment #22
Mile23Testbot 'fail' due to Nightwatch problems: https://dispatcher.drupalci.org/job/drupal_patches/58895/artifact/jenkin...
#2973992: Permission issue in Nightwatch step marks all full testruns as unstable
Comment #23
Mile23Re-setting RTBC now that the permission issue is fixed.
Comment #24
Anonymous (not verified) CreditAttribution: Anonymous commented(Edit: not that tab, sorry)
Comment #25
neclimdulI don't see any comment on why the patch actually works. Is is because of the merge-plugin entries in core's composer.json?
I'm curious how this will affect composer install projects like https://github.com/drupal-composer but I'm not sure how to give it a solid test without committing so assuming the answer to the above question is yes I agree this is a solid improvement.
Comment #26
alexpottYep it's because of the merge-plugin entries in core's composer.json - all of this:
But @neclimdul I think you raise a good point because with this change maybe we need to add
"wikimedia/composer-merge-plugin": "^1.4"
to core/composer.json.Comment #27
Mile23How about core/composer.json has components in both
require
andreplace
?I just did this and then did
composer run-script drupal-phpunit-upgrade
(which rebuilds the autoloader).Then vendor/composer/autoload_psr4.php contains this:
And I can run tests:
Comment #28
alexpott@Mile23 yeah but you've still got the merge plugin installed.
Comment #29
Mile23Well it didn't break anything is what I'm saying. And then when someone tries to use it in drupal-project etc, it will require the thing it replaces, without merging.
Comment #30
MixologicComment #31
MixologicIdeally we alter the subtree splits such that we split out /core *without* the components nestled inside, and the components get split out separately, and core composer.json merely 'requires' them. But Im not sure we can do this yet, without either modifying the subtree tool to exclude the components subdir, or by moving the components out of /core/lib/ and into something above /core, which Is also the part I dont think we can do (yet)
Comment #32
Mile23We were having a conversation about whether to move the stuff around a bunch or leave components in place here: #2943856: [meta] Reorganize Components so they are testable in isolation
Agreed that somehow we should quit doing the
replace
part, other than maybe for the benefit of dev. In which case we mightreplace
the components in drupal/drupal. But that's getting way ahead on the composer initiative, and not the scope of this issue.Comment #33
alexpott@Mile23 I think if we don't add the merge plugin into core/composer.json then drupal-project from https://github.com/drupal-composer will put the components in vendor/drupal/component which whilst is probably desirable in the long term I'm not sure we should do that here.
Comment #34
Mile23OK.
Re-upping #16, originally from @alexpott, so not mine.
I RTBCd in #23, so I'm re-RTBCing here.
Comment #35
webflo CreditAttribution: webflo at UEBERBIT GmbH commented#34 will break the usage of "drupal/core". It won't be usable without the merge plugin. I think we should get rid of the merge plugin in the long-run. This is a step in the wrong direction imo.
Comment #36
alexpott@webflo what about #27? Super tricky...
Comment #37
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedThis should work without the merge plugin.
Comment #38
Mile23Moving away from the merge plugin is the goal. But we can't even test the validity of the components' composer.json files until we allow them to define their own autoloading and version constraints. The easiest way to make that work without breaking everything else seems to be merging them.
When we have a way to test them, we can then remove the merge plugin.
The patch in #37 basically reverts #2867960: Merge Component composer.json files to account for them during build which was a previous step along this path. It also does not allow for the components to define their own autoloading.
We can test the validity of the version constraints using TravisCI in #2876669: Fix dependency version requirement declarations in components but we need to be able to prove it using DrupalCI, so we can prevent regressions.
Also re: #32: Using
replace
in drupal/drupal for dev is kind of the plan now: #2958021: Proposal: Composer Support in Core initiative (We had even talked about renaming drupal/drupal to drupal/drupal-dev.) But yah, that's out of scope here.Comment #39
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedI think we should move the test from core/tests/Drupal/Tests/Component to their components. And test them individually in Drupal CI (pseudocode: for each component => composer install && ./vendor/bin/phpunit). We could still run them in our normal testsuite as well.
It takes on 12 seconds on my machine. It should be possible from infrastructure perspective. Maybe @Mixologic could comment on this?
Comment #40
alexpottIF we do #39 we need to put stuff into out composer.json to make sure that component tests are not autoloadable during regular runtime. As an aside imo we should also move completely away from autoloadable tests as well as the merge plugin. Changing the autoloader for testing is not our best idea.
Comment #41
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedThe composer.json in our components does not follow our conding standards. We could fix this is a separate before moving the test classes.
Comment #43
Mile23See #10 and #11.
Also we can rescope #2876669-55: Fix dependency version requirement declarations in components to be about changing DrupalCI once we've done this and #2943856: [meta] Reorganize Components so they are testable in isolation
We should make the components test a separate testsuite rather than changing bootstrap.php.
But that's out of scope here... We should only set up autoloading via composer.json in this issue, for consistency against the existing test setup.
Comment #44
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedComment #46
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedThis one could apply, my local repo was outdated. It does not address the review from @Mile23 yet.
Comment #47
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedLets fix the code-style in #2983304: Apply code style to all component composer.json first
Comment #48
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedI tried to use the merge plugin in an test to verify we have no conflicts between component constraints and drupal/core.
Comment #49
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedLets move the new composer.json to a different location to avoid autoloading of tests.
Comment #51
Mile23Getting a bit out of scope here.
Will #27 work for drupal-project?
When we have either #27 or #34 (really #16) working without changing tests, we can then change the tests around and work on DrupalCI in #2943856: [meta] Reorganize Components so they are testable in isolation which is postponed on the narrow scope of this issue.
Comment #52
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedI guess #27 would work for drupal-project. #34 definitely not.
But #27 makes the composer.json for drupal/core more complex. I tried to optimize it for distribution, hence i remove the merge-plugin from drupal/core which only purpose it is to test the the components in combination with drupal/core.
Comment #53
MixologicCan we leave the merge in there, except move it all the way to the top level drupal/drupal composer.json?
Comment #56
Mile23Rescoping here a tiny bit in order to support #1826054: [Meta] Expose Drupal Components outside of Drupal and #2982674: [meta] Composer Initiative Phase 1: Add composer build support to core and #2912387: Stop using wikimedia/composer-merge-plugin
Let's use
path
repositories to allow drupal/drupal to install the components locally.Then we don't
merge
/replace
the components in drupal/core, and require them instead.This removes this usage of the merge plugin for this purpose, while still allowing us to exercise the component composer.json files.
Here's the composer update command to save you some typing:
Comment #57
Mile23Comment #58
Mile23The error in #56 was this:
Source path "core/lib/Drupal/Component/DateTime" is not found for package drupal/core-datetime
That's because the testbot uses a case-sensitive filesystem, and the directory is actually named Datetime.
Interestingly, if you say
composer update
on a branch other than 8.8.x, Composer will be unable to resolve the components due to weird version inconsistencies with error reports that look like this:- Installation request for drupal/core-utility 2943842.9999999.9999999.9999999-dev -> satisfiable by drupal/core-utility[2943842.x-dev].
Furthermore, if you were to get them to resolve, the lock file would lock to version
2943842.x-dev
, which would not install if you're on branch 8.8.x becauseself.version
resolves to version8.8.x-dev
.I also discovered that there is a dependency between
"post-autoload-dump": "Drupal\\Core\\Composer\\Composer::ensureHtaccess",
and one of the components. This means that there are plenty of error conditions where Composer dumps the autoloader before running the plugins, such as the merge plugin that we're still using for drupal/core. That leads to a nice dependency trainwreck. This event script will go away in #2982684: Add a composer scaffolding plugin to core (see: #2990257: Determine how to handle composer scripts in drupal/drupal) We'll need to commit that before we cut the Gordian knot here.Comment #59
greg.1.anderson CreditAttribution: greg.1.anderson at Pantheon commentedI think that #2912387: Stop using wikimedia/composer-merge-plugin has advanced to the point where this patch is no longer necessary.
Comment #60
greg.1.anderson CreditAttribution: greg.1.anderson at Pantheon commentedOr maybe I am wrong about that. I am not sure we can move the Component sources into a src directory.
Comment #61
greg.1.anderson CreditAttribution: greg.1.anderson at Pantheon commentedWe should still be able to isolate and test the components separately, if desired, as long as we are content to do without the
src
directory. Note that this is the technique that Symfony uses, and as a result, Symfony forgoes thesrc
directory in each component tree.Comment #63
Mile23This is the same strategy as #58: Path repos for components in drupal/drupal, and direct require in drupal/core.
Handy composer command for anyone who wishes to copy/paste:
#3086644: LegacyProject composer templates wrongly reference 8.x + fix test coverage is RTBC, so it's likely that it will make it in first. That means we'll have to change that test here, to include more path repos in our build tests.
Comment #69
Mile23Tried to re-roll this but I ran into dependency issues based on #3272110: Drupal 9 and 10's Drupal\Component composer.json files are totally out of date, so I'm marking this as postponed on that one.
Comment #72
Mile23#3272110: Drupal 9 and 10's Drupal\Component composer.json files are totally out of date is in, so here’s this.
This patch changes the drupal/drupal root composer.json to require drupal/core 11.x-dev, but it’s the only way I could get it to work. This might imply that we need to specify the major/minor dev branch for each branch, which could be a drag.
Comment #73
smustgrave CreditAttribution: smustgrave at Mobomo commentedHave not tested but seems to have caused some test failures.