Problem/Motivation
while uninstalling themes during a config import (drush cim) I get the error message:
"The base theme $key cannot be uninstalled, because theme $sub_key depends on it."
but in the same config import I would also uninstall the sub theme.
on config import all the uninstalled themes should be in the same uninstall call, so that the test about
"Base themes cannot be uninstalled if sub themes are installed, and if they are not uninstalled at the same time." is possible.
/core/lib/Drupal/Core/Extension/ThemeInstaller.php Line 232:
// Base themes cannot be uninstalled if sub themes are installed, and if
// they are not uninstalled at the same time.
// @todo https://www.drupal.org/node/474684 and
// https://www.drupal.org/node/1297856 themes should leverage the module
// dependency system.
if (!empty($list[$key]->sub_themes)) {
foreach ($list[$key]->sub_themes as $sub_key => $sub_label) {
if (isset($list[$sub_key]) && !in_array($sub_key, $theme_list, TRUE)) {
throw new \InvalidArgumentException("The base theme $key cannot be uninstalled, because theme $sub_key depends on it.");
}
}
}
as a temporary solution I replaced
throw new \InvalidArgumentException("The base theme $key cannot be uninstalled, because theme $sub_key depends on it.");
with a recursive call
$this->uninstall([$sub_key]);
Steps to reproduce
- Install minimal and enable test themes to be installed.
- Export your configuration
- Install test_basetheme, test_subtheme and test_subsubtheme
- Try to import the configuration again - you won't be able to because it can't uninstall the themes
Proposed resolution
Fix \Drupal\Core\Config\ConfigImporter::createExtensionChangelist() to use the theme's sort information to ensure dependencies are processed in the correct order on install and uninstall.
Remaining tasks
User interface changes
None
API changes
The constructor of the following classes:
\Drupal\Core\Config\ConfigImporter\Drupal\config\Form\ConfigSync\Drupal\config\Form\ConfigSingleImportForm
now require an argument of extension.list.theme service implementing \Drupal\Core\Extension\ThemeExtensionList.
\Drupal\config\Form\ConfigSync and \Drupal\config\Form\ConfigSingleImportForm are forms and are consider to be internal.
Data model changes
None
Release notes snippet
N/a
| Comment | File | Size | Author |
|---|---|---|---|
| #24 | 3001430-24.patch | 22.61 KB | _utsavsharma |
| #24 | interdiff_21-24.txt | 3.2 KB | _utsavsharma |
| #21 | 3001430-21.patch | 22.61 KB | lauriii |
| #20 | 3001430-20.patch | 23.42 KB | alexpott |
| #16 | 3001430-16.patch | 23.46 KB | alexpott |
Comments
Comment #2
cilefen commented8.4.x is unsupported.
Comment #4
pameeela commentedI can still reproduce this. If you try to import config that uninstalls a base theme and sub theme at the same time, it throws an error.
But I'm not sure whether it's something to be fixed/supported or just need to update that comment to say they can't be uninstalled at the same time?
Comment #5
Oscaner commentedComment #6
mlncn commentedJust ran into this exact same problem that config sync cannot uninstall base theme and theme at same time, and looked to make sure an issue was already filed. This is clearly a pretty important cleanup of the configuration management system which is usually pretty solid, or at least works if you run it twice (that doesn't fix anything here).
Comment #7
iyyappan.govindHi, Did you run drush updb or/update.php first? then try the drush cim or configuration import via UI.
Comment #8
codebymikey commentedThe patch on #5 works for me, all it needs is a test for it to get merged in.
@iyyappan.govind, I think this isn't related to the cache and something fundamental in the implementation where it uninstalls the themes in alphabetical order rather than based on their dependency tree.
Comment #9
deviantintegral commentedThis also comes up for sites upgrading from Drupal 8 to Drupal 9 due to #3115223: Remove Stable as a base theme of core themes.
Comment #10
deviantintegral commentedI wrote the following update hook to handle a site using Claro in Drupal 8, which had dependencies on Stable and Classy.
Comment #12
alexpottThe theme list actually has weights assigned by dependency - see \Drupal\Core\Extension\ThemeExtensionList::doList() - it calls into \Drupal\Core\Extension\ModuleHandlerInterface::buildModuleDependencies() and creates a graph ... so we can do the same as modules. I'm going to add a test to prove that we install and uninstall themes with base themes via config sync correctly.
Comment #13
alexpottHere's a test and a proper patch. #12 was the same as #5 oops...
So we now using the theme's sort property to sort them for installing and uninstalling. Plus I've got a test that proves the fix and the fact we have a problem.
The last 9.3.x bugfix release has gone out so moving to 9.4.x
Comment #16
alexpottFixing the tests and injecting the theme extension list into the config importer.
Comment #17
alexpottComment #18
alexpottUpdating the issue summary.
Comment #19
alexpottComment #20
alexpottRerolled after #2392815: Module uninstall validators are not used to validate a config import
Comment #21
lauriiiI removed the changes to
\Drupal\Tests\config\Functional\ConfigImportUITestbecause they are no longer needed since the test is now using Olivero instead of Bartik.Comment #23
smustgrave commentedActually noticed this bug while prepping a site for D10
1. Should be updated for 10.1.x and 11 now I think.
Testing out the functionality by editing a contrib theme I'm using to base theme off stark.
Before installing I exported my config
Installed theme which installed stark
Ran config import and got the error
Applied fix
Ran config import and both uninstalled.
So this looks good just needs that 1 update.
Comment #24
_utsavsharma commentedAddressed the pointer in #23.
Please review.
Comment #25
markdorisonComment #26
smustgrave commentedIssue has been addressed
Comment #27
catchShould this say theme weights?
Also is there no API method for that anywhere?
Comment #28
alexpottYes it should say theme weights... it's about setting them in the array we're creating to do the ordering... so it's not setting the theme weights in the system... will fix this to be clearer. It's a copy/pasta so fixing it above too.
Leaving at RTBC as this is only fixing a comment as @catch requested.
Comment #29
catch@alexpott found #2241855: Provide canonical extension sorting by dependencies in the extension system which covers my remaining concern here, which was apparently a remaining concern on a similar issue 9 years ago.
Committed/pushed to 10.1.x, cherry-picked to 10.0.x and 9.5.x, thanks!
Comment #33
catchComment #35
alexpottI agree that we should fix this in 9.5 and 10.0 so here's a patch to remove the deprecation message as we should only be adding them in 10.1
Comment #38
catchHmm fair enough, this is the tricky thing about best effort bc vs. backporting bugfixes with internal API changes. Committed/pushed to 10.0.x and 9.5.x, thanks! I don't think anyone's going to be overriding either class so hopefully this is moot.
Comment #39
larowlanJust a couple of micronits
Let's add a property type-hint here for the D10 version.
%s/module/theme
%s/base themes/base theme
micronit: is it worth putting the theme_handler service into a local variable ?
would probably need to assign it twice to allow for any container rebuild as a result of updating core.extension
Comment #40
larowlanAh crosspost
Comment #42
quietone commentedPublished the change record.