Reverting blocks and other pseudo-exportables in an install hook We have a medium-sized Drupal 7 site whose configuration is almost entirely stored in code, in a single Features module.  In order to permit automated testing and a cleaner development workflow, I'd like to make it possible to install a new instance of the site from scratch without cloning the database.  To that end, I've created a simple install profile (based on the standard profile) which enables our themes and configuration module.  This mostly seems to work, but I've found that some feature components are not immediately reverted on the newly-installed site: specifically, blocks exported with fe_block_settings, user permissions, and variables.  All these are applied if I run drush fra -y from the command line after installing the new site, but I would like to do everything programmatically to make writing tests easier.

There is some discussion of the problem with blocks at https://www.drupal.org/node/1901116, but I've tried the fix given there (calling module_install in the hook_install implementation instead of listing a dependency in the .info file), without successs so far.  That page also doesn't address the issues I'm seeing with variables and user permissions.

Is it possible to successfully apply all of these exported feature components from an install hook, or do I need some other mechanism?
In short: the workaround is to call drupal_flush_all_caches() and drupal_static_reset() before reverting the module containing exported features again from an install task.

In detail: The main symptom observed was that blocks (exported as fe_block_settings components), were not correctly applied on the new site when they depended on a Views block display defined in the same features module.  This remained true even after adding an additional call to features_revert_module() in an installation task.  (There were also problems at one point with variables and permissions, but these were cleared up more easily by the addition of the call to features_revert_module()).

The problem with settings for views blocks is that Views caches all views loaded from the database in a static variable, making any views loaded or enabled for the first time during a single request or drush command invisible to later calls to views_block_info().  One possible (tested) workaround is the following:

views_get_all_views(TRUE);
drupal_flush_all_caches();
features_revert_module('xyz');


Supplying TRUE for the $reset parameter to views_get_all_views() forces the module to discard its static cache and re-compute the list of blocks from scratch.  This allows the revert of block settings to go through correctly.

Because I suspect this will not be the only problem caused by invalid static variable caches, I am trying the more drastic approach of resetting all static variables and clearing all caches before reverting the module:

drupal_static_reset();
drupal_flush_all_caches();
features_revert_module('xyz');


(Resetting all static variables does produce a few extra PHP warnings, which hopefully are spurious.)

The above lines are run as an installation task, and are combined with the approach described in https://www.drupal.org/node/1901116: i.e., remove the module with exported blocks from the dependencies[] list, and enable it manually in hook_install() after enabling themes for the site.  The complete implementation in the profile .install file then looks more like this, where the installation profile is named foo, the features module is named xyz and the site theme quux:

/**
 * Implements hook_install().
 */
function foo_install() {

  // ... other setup code here ...

  // Enable themes
  theme_enable(array('seven', 'quux'));
  variable_set('admin_theme', 'seven');
  variable_set('node_admin_theme', '1');
  variable_set('theme_default', 'quux');

  // Enable module containing features-exported block settings
  module_enable(array('xyz'));
}

/**
 * Implements hook_install_tasks().
 */
function foo_install_tasks(&amp;$install_state) {
  $tasks = array(
    'foo_revert_xyz' =&gt; array(
      'display_name' =&gt; st('Apply all settings in "xyz" module'),
      'type' =&gt; 'normal',
    ),
  );
  return $tasks;
}

function foo_revert_xyz() {
  drupal_flush_all_caches();
  drupal_static_reset();
  features_revert_module('xyz');
}


Tracking this down was a real headache, so I hope the solution is useful to someone else.