Problem/Motivation
Currently when a recipe is reapplied, config as provided is compared against existing config in the active config storage and an exception raised if there's a difference.
As determined in #3283900: Define recipe runtime configuration update requirements, when the recipe has been previously run, this comparison will fail when any of three commonly occurring situations apply:
- The config has been altered by a config action. Example: Recipe A provided a user role and Recipe B added a permission to the user role.
- The config has been customized by a site administrator. Example: Recipe A provided a user role and a site administrator added a permission to the role.
- The config as provided has changed. Example: Recipe A provided a view when it was last installed and now provides the same view in a slightly different form, such as a field added to a display.
The first of these issues may be mitigated through #3304910: Compare against a config snapshot when (re)applying a recipe. Still, taken together, it's expected these common sources of differences will frequently prevent reapplication of recipes, significantly weakening the applicability and benefits of recipes.
Proposed resolution
When there are differences between config as provided and config in the active storage, determine what changes are available and merge them in.
As well as solving the problem of ensuring recipes can be reapplied, this will essentially make recipes and extension-provided config updatable, achieving a longstanding aim currently met in contrib by workarounds like Configuration Synchronizer and Update Helper.
Doing so will require:
- #2960870: Snapshot configuration as installed and updated from recipes and extensions
- #2960867: Add a ::normalize() method to config entities to support comparing extension- and recipe-provided to installed configuration
- #2960874: Support 3-way configuration merging