Problem/Motivation

The inclusion of generic or reusable components in features raises barriers to interoperability by creating conflicting dependencies.

What are "generic" components?

Generic or reusable components are ones that are not specific to a given feature, or its sub-features. For example, an 'administrator' user role is generic in that it may be used for permissions by practically any feature. A contrasting, non-generic role might be a 'blogger' role included in a blog feature. While it's conceivable that other features might include permissions assigned to a blogger role, those other features typically would need to require the blog feature. They would themselves be blogging sub-features.

How do generic components affect interoperability?

Take the example of a 'field_tags' field, referencing a Tags vocabulary. Many features may include an instance of the field. If, in a given set of features, the tags vocabulary is added to a myfeature_core (or myfeature_tagging, or whatever) feature, all other features in the set with a field_tags instance will require myfeature_core. If the same is done in a second set of features, features in the two sets will have conflicting dependencies, breaking interoperability.

What are some of the main component types that may be generic?

Why can't we simply drop dependencies?

Since dependencies are the issue here, wouldn't it be possible to just drop them? Unfortunately, no. For e.g. a permission referencing a role to work, that role must be present before the permission is registered.

Proposed resolution

Several different approaches are possible.

Exclude generic components from features

Variants of this approach:

  • Use custom handling. E.g., create a user role in hook_install().
  • Use the Apps compatible module to handle generic components.
  • Use the Default config module to remove default components from features.

Put generic components into a base distribution that other distros depend on

E.g., use Panopoly for generic components.

Rework dependency handling in Features to allow pluggable dependencies

An approach that might facilitate interoperable handling of generic components:

  • Remove dependency assignment from given component types. E.g., when a menu link is added to a feature, that feature is not dependent on a feature that provides that link's menu.
  • Instead, Features implements hook_system_info_alter() to dynamically assign dependency for all features (enabled or not). So myfeature_blog, which includes a menu link for the mymenu menu, becomes dependent on the first feature present that includes the mymenu menu.

Remaining tasks

Comments

wizonesolutions’s picture

I'm having this problem in Cash Flow. I created a Cash Flow Deluxe feature that adds a few specific terms to the tags vocabulary using UUID Features. However, Features thinks that the module is dependent on that vocabulary (even though I added an explicit dependency on the module that actually defines the vocabulary).

Things work alright, but I can't get out of Overridden status due to that. I am going to give Apps Compatible a shot and see it that helps.

wizonesolutions’s picture

Actually, I just had to remove a rogue modulename.features.taxonomy.inc file, and I was good to go. So I don't have a use for this quite yet (and I couldn't wrap my head around how to implement Apps Compatible or what I should have expected to "see", although I'm a bit braindead today).