Problem/Motivation
#2296423: Implement layout plugin type in core and #2779647: Add a workflow component, ui module, and implement it in content moderation are both adding experimental code to core/lib. There have been a number of concerns raised about this on the issues. For example, #2296423-150: Implement layout plugin type in core and #2296423-158: Implement layout plugin type in core
One of the main concerns is that code in core/lib is always available and modules that use it might not necessarily have the same level of warnings to the user as an experimental module. Another important concern is that experiments have to be uninstallable and not break sites. Once code is in core/lib it is tricky to guarantee this.
On the other hand, moving code from an experimental module to core/lib once it is mature means all the contrib / other modules that experimented with it have to be updated.
This is a major task because being able to add experimental APIs to core is a key task to ensure that Drupal 8 can experiment and look to provide as continuous an upgrade path to D9 as possible.
Proposed resolution
Whilst discussing this issue with @catch, @xjm, @dries, @effulgentsia, @cilefen and @webchick I realised that we could use the autoloader to fix this for us. The namespaces of the code would still be \Drupal\Core\NewThing but the location of the files would be core/experimental. In order to enable autoloading of the files you would need to install an experimental module that adds the ability for Drupal to autoload this code.
Remaining tasks
User interface changes
None
API changes
An API for experimental modules to add classes in core/experimental to the autoloader.
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#17 | interdiff.txt | 1.69 KB | claudiu.cristea |
#17 | 2833347-17-.8.3.x.patch | 3.58 KB | claudiu.cristea |
#17 | 2833347-17-.8.2.x.patch | 3.56 KB | claudiu.cristea |
#14 | 2833347-14.patch | 3.48 KB | effulgentsia |
#12 | 2833347-12.patch | 13.29 KB | alexpott |
Comments
Comment #2
alexpottComment #3
alexpottComment #4
xjmWe also need an issue to discuss @internal vs. @version (should be a separate issue per @alexpott).
Comment #5
alexpottHere's a first cut at this. Unfortunately we can't get away without storing the experimental namespaces somewhere that is available to the container super super early. I think the nature of the changes makes this 8.3.x only :( - that said I don't think we need an upgrade path here because whether or not core.extension has an empty list of experimental namespaces or just doesn't have the key should not matter.
Comment #7
alexpottComment #8
alexpottComment #10
alexpottComment #12
alexpottComment #13
alexpottGiven #2779647-142: Add a workflow component, ui module, and implement it in content moderation I don't think this idea flies. Basically there's quite a few things that depend on directories like plugin discovery so this is not as simple as it seems.
Comment #14
effulgentsia CreditAttribution: effulgentsia at Acquia commentedOh, I understood our call differently. I thought the location would be somewhere within the module's directory. Here's a patch for what I had in mind. No interdiff, since it's a different approach.
Hm, I haven't looked into that complication yet. Can you add a failing test to demonstrate one or several of those problems?
Comment #16
claudiu.cristeaNit: We can save
dirname($filename)
into a variable as it can be used twice.Nit: Should be one line, I think.
We need a different patch for 8.3.x because there should be
protected static $modules
.Comment #17
claudiu.cristeaRerolled, 8.3.x patch and fixed my own comments.
Comment #18
Fabianx CreditAttribution: Fabianx as a volunteer commented+1 to #14, this is much easier and a nicer way to do it. (and the other code approach was not really that nice)
FWIW, it is also possible to keep BC later by having the modules stick around and just have the classes in the module extend the ones from the core/lib later.
Or it is also possible to have core/lib as empty classes that extend from the experimental module classes - though that would fail really hard if you tried to use it without the module being enabled.
--
To the discovery:
Yes, plugin discovery works based on the namespaces registered (which several of us disputed back then), however as long as the namespace in core/lib/foo is similar to core/[foo] this should work correctly as there is no special code to handle modules vs. core.
So I imagine #14 could just work (tm).
Given that its also in module/lib/Drupal/Core also should not interfere with the normal autoloader, which only checks and registers src/.
Comment #19
tim.plunkettThis should handle trimming \ and / off.
For example, this should also work:
'\Drupal\Core\Test': '/lib/Drupal/Core/Test/'
Okay maybe not the trailing slash, but definitely the leading one on each
I think this needs a more specific name
Otherwise, this is pretty ingenious.
Comment #20
alexpottI don't think discovery works for configuration entities :( - Let's think about...
Using the workflow patch example. We have an new config entity type of "workflow" - which it was proposed that we should add to core. This means thats the config object name should start with core.workflow.... The core comes from the provider. Let's say we add a module called "workflows" to contain the experimental code that we want to add to core/lib. Using the patch in #19 we can make Drupal\Core\Workflow look in core/modules/workflows/src... which will allow us to have an entity directory containing a file Workflow.php with the namespace \Drupal\Core\Workflow\Entity. So far so good. The good thing is that the provider will be set to "core" because we use \Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery::getProviderFromNamespace() to determine this. Therefore the config entity will have the correct name - core.workflow. The next problem is that the entity will not be removed when the workflows module is uninstalled. This is fixable too we can add code to the entity's calculateDependencies() method to add an enforced dependency on the "workflows" module. This code would need to be removed and the dependencies fixed once the experimental code is moved to core as stable.
So tldr; I think it would work - but we'd just need extra code in calculateDependencies() - not too bad afaics.
This will happen on every request that builds the classloader. We don't read the info files on every request so we shouldn't do this here. Hence me putting this in core.extension earlier. I don't think we can make this change like this.
Comment #21
effulgentsia CreditAttribution: effulgentsia at Acquia commentedTrying a more detailed title. I don't want the title to unduly bias implementation details though. While I prefer #17 to #12, #12 might also be an ok approach, so please interpret "come with" loosely. Further improvements to the issue title are welcome.
Comment #22
effulgentsia CreditAttribution: effulgentsia at Acquia commentedI think "rely on" captures it better than "come with" :)