- Issue created by @thejimbirch
- πΊπΈUnited States thejimbirch Cape Cod, Massachusetts
Importing all configuration from the
sitemap
module also has this behavior.The configuration 'tour.tour.sitemap' has unmet dependencies
Sitemap module has the following config:
install/sitemap.setting.yml optional/tour.tour.sitemap.yml
This can be remedied in the recipe creation from changing:
config: import: sitemap: '*'
to
config: import: sitemap: - sitemap.setting.yml
But ultimately, shouldn't recipe's config import have the same behavior as installing a module and only import config if all dependencies are met?
- πΊπΈUnited States aangel
I'm seeing the same thing with Redirect on a Standard install:
The configuration 'language.content_settings.redirect.redirect' has unmet dependencies
From Redirect:
dependencies: - drupal:path_alias - drupal:link - drupal:views
- πΊπΈUnited States phenaproxima Massachusetts
My knee-jerk reaction here is to think that, if your recipe has a line like this:
config: import: taxonomy: '*'
...then all of Taxonomy's config should be imported, the same way it would be if you installed it as a regular module (i.e., where optional config is only installed if the dependencies are there).
- π§πͺBelgium wim leers Ghent π§πͺπͺπΊ
Still wondering how this may or may not mess up the deterministic intent β Iβll need to dig in to how optional config works exactly today first though.
Looking at
\Drupal\Core\Config\ConfigInstaller::installDefaultConfig()
, this is the relevant section:// During a drupal installation optional configuration is installed at the // end of the installation process. Once the install profile is installed // optional configuration should be installed as usual. // @see install_install_profile() $profile_installed = in_array($this->drupalGetProfile(), $this->getEnabledExtensions(), TRUE); if (!$this->isSyncing() && (!InstallerKernel::installationAttempted() || $profile_installed)) { $optional_install_path = $extension_path . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY; if (is_dir($optional_install_path)) { // Install any optional config the module provides. $storage = new FileStorage($optional_install_path, StorageInterface::DEFAULT_COLLECTION); $this->installOptionalConfig($storage, ''); } // Install any optional configuration entities whose dependencies can now // be met. This searches all the installed modules config/optional // directories. $storage = new ExtensionInstallStorage($this->getActiveStorages(StorageInterface::DEFAULT_COLLECTION), InstallStorage::CONFIG_OPTIONAL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION, FALSE, $this->installProfile); $this->installOptionalConfig($storage, [$type => $name]); }
AFAICT that:
- installs ALL optional config
- of ALL installed extensions
- after ANY extension is installed
- at ANY time.
I wonder if this still makes sense in a Recipes world π€ Because what if some contrib module that you installed eons ago gains additional optional config in some new version along the way? Then applying a Recipe would install that new optional config too, which AFAICT would be an unwanted side effect? π€
- πΊπΈUnited States phenaproxima Massachusetts
My feeling is that optional config, as we currently understand it, starts breaking down in the context of recipes.
What I'm leaning towards here is "recipes must be absolutely explicit about everything" -- in other words, in the
config:import
section of recipe.yml, they can specify any config from a given extension, regardless of whether it's part of the extension's optional config. If a recipe says something liketaxonomy: '*'
, it does not import optional config.In other words: if you want to bring in an extension's optional config, you need to explicitly ask for it by name.
- Status changed to Needs review
11 months ago 8:01am 22 January 2024 - πΊπΈUnited States konfuzed Atlanta, GA
Having now run into this conflict while testing a new recipe-based installation, there really seem to be 4 types of configuration imports that are targeted and we should help make it explicit what group of configuration will be brought in:
- none -- just activate the module, whether to avoid conflicts or because it's not needed due to nature of the module
- required / basic install config files -- could be handled by a keyword of 'default' or 'required' to just get the files in the config/install directory
- all aka "*" -- that pulls in config/install and config/optional
- explicit selection of files for any reason
I think common usage makes "*" much easier to read as a "yes I really mean everything in all of the module's config directories" easier on the mental processing and expected outcome.
- π¨π¦Canada b_sharpe
@konfuzed I think that's over-complicating it.
NULL
: Import none of the config*
: import all the module's config, exactly like would happen if you installed the module through the UI. (optional if dependencies are met)- Explicitly listed (see note below)
The part in #8 I don't agree with, is installing optional config if asked for by name regardless if dependencies are met or not. There is not a single use-case I can think of to install some config that is dependant on another module without installing the module itself, otherwise it wouldn't have the dependency...
See #3454444: Document the reason why recipes donβt import a moduleβs config entities by default β
- Status changed to Closed: works as designed
2 months ago 2:02pm 14 October 2024 - πΊπΈUnited States thejimbirch Cape Cod, Massachusetts
This has been documented that recipe authors need to be declarative about what config they import. By using
module_name: '*'
, the recipe author needs to include all of the dependencies of that config.Closing as works as designed.