Recently I’ve made several remarks on Twitter about the pain of using the Features module for install profiles. Since they weren’t universally understood, I’ve decided to blog a bit about what is one of my pet topics: the problem of default configuration.
- An install profile / distribution needs to be able to export and provide default configuration (content types, fields, variables, etc).
- The user needs to be able to revert to default configuration when desired.
- The user needs to be able to “untrack” any piece of configuration, allowing it to be deleted.
- The user needs to be able to export and version his own export of the configuration, maintaining his changes across distribution upgrades.
The last two requirements are not satisfiable with Features, because Features has no concept of “default configuration” over regular configuration.
Using Commerce Kickstart as an example, if a user installs the demo store, he will get content types, product types, fields, and other configuration for shirts, hats, shoes, and other kinds of products.
The user then expects to be able to delete anything he doesn’t want (hats and shoes, for instance), make changes to the parts he cares about (extending shirts), then export that (for versioning with git, deploying across environments etc).
However, the user soon realizes that any configuration versioned through Features can’t be deleted, since it is owned by the exporting Feature.
Any changes he makes to the configuration cause the Feature to be marked as “overridden”, but can’t be exported separately.
When the distribution issues an update, reverting the Feature will cause all changes to be lost.
The user then comes into the Commerce Kickstart issue queue and gives me a hard time :)
This lack of flexibility presents one of the main criticisms against today’s distributions.
The Features ecosystem provides two solutions for these problems:
This module allows configuration to be exported as “default configuration”, potentially satisfying requirement #3.
It is currently unmaintained (7.x-1.0-alpha9 from November 5th 2012) and of questionable compatibility with Features 2.x
Used by Panopoly.
- Features Override
This module allows all changes to a feature to be exported as another Feature, satisfying requirement #4.
The fact that those requirements are handled by external modules tells me that Features was never designed for the use cases for which we are trying to use it for. That’s the cause of our pain.
Of course, we are just using the best tool we have. CMI on Drupal 8 will give us an opportunity to re-evaluate our needs and build new solutions on a solid foundation (since Drupal 8 provides true exportables, unlike Drupal 7 where Features needs to hack around anything that’s not provided by ctools or entity api exportables).
An interesting possible solution I recently came across is Configuration, a project that aims to backport the CMI approach to configuration into D7.
This means that there’s a staging directory on disk used for importing / exporting into the active store (the database, in this case). Any piece of configuration can be untracked at any time.
Modules can also provide their own configuration that’s then copied into the staging directory (allowing us to build “revert to default configuration” functionality).
Like Features, it has no solution for deleted configuration (a field that’s deleted from configuration is never deleted on the actual site).
It needs more work, and I’ve already posted my first patch, but I would be willing to experiment with a Features-free, Configuration based, PHP 5.3 only (Configuration uses namespaces) distribution.
If nothing else, it would give us the opportunity to tackle CMI-like problems in production environments.