My Drupal Makefile

As promised, a scrubbed version of my Drupal Makefile.

I customize it for different testing or production environments with .mk files (ex: qa.mk) that contain the variables from the top part of the Makefile. These files are automatically included in this Makefile. Benefits: I don’t have to commit my database password to the source code tree, and I don’t have to think about which environment I’m in.

I use “make cycle” and “make mysql” a lot. “make cycle” depends on Drush being set up properly, and patched to allow you to update all the modules from the command-line.

I think this works for the Drush update command:

function drush_tools_update($command = '') {
  global $user;
  ob_start();
  require_once 'includes/install.inc';
  include_once('update.php');
  $ret = ob_get_contents();
  drupal_load_updates();
  ob_end_clean();
  $user = user_load(array('uid' => 1));
  $list = module_list();
  $update_list = array();
  foreach ($list as $module) {
    $updates = drupal_get_schema_versions($module);
    if ($updates !== FALSE) {
      $latest = 0;
      $base = drupal_get_installed_schema_version($module);
      foreach ($updates as $update) {
        if ($update > $base) {
          if ($update > $latest) { $latest = $update; }
          $update_list[$module][] = $update;
        }
      }
      if ($latest) {
        sort($update_list[$module]);
        printf("%-30s %5d -> %5d (%s)\n", $module, $base, $latest, join(', ', $update_list[$module]));
      } else {
        printf("%-30s %5d\n", $module, $base);
      }
    }     
  }
  if (count($update_list) == 0) return;
  if ($command != 'force' && !drush_confirm(t('Do you really want to continue?'))) {
    drush_die('Aborting.');
  }
  ob_start();
  foreach ($update_list as $module => $versions) {
    foreach ($versions as $v) {
      print "Running " . $module . "_update_" . $v . "\n";
      update_data($module, $v);
    }
  }
  $updates = ob_get_contents();
  cache_clear_all('*', 'cache', TRUE);
  cache_clear_all('*', 'cache_page', TRUE);
  cache_clear_all('*', 'cache_menu', TRUE);
  cache_clear_all('*', 'cache_filter', TRUE);
  drupal_clear_css_cache();
  ob_end_clean();
  print $updates;
  $output = '';

  print $updates;
  if (!empty($_SESSION['update_results'])) {
    $output .= "The following queries were executed:\n";
    foreach ($_SESSION['update_results'] as $module => $updates) {
      $output .= "\n" . $module . "\n--------------------------\n";
      foreach ($updates as $number => $queries) {
        $output .= 'Update #'. $number . ":\n";
        foreach ($queries as $query) {
          if ($query['success']) {
            $output .= "SUCCESS: " . $query['query'] . "\n";
          }
          else {
            $output .= "FAILURE: " . $query['query'] . "\n";
          }
        }
        if (!count($queries)) {
          $output .= "No queries\n";
        }
      }
    }
    $output .= "\n";
    print $output;
    unset($_SESSION['update_results']);
  }
}

(and you’ll need to define it in drush_tools_drush_command also).

  • http://www.robloach.net Rob Loach

    Looking at this makes me think that you’d really enjoy Drush…. http://drupal.org/project/drush .

  • http://sachachua.com Sacha Chua

    Yes, I use Drush extensively, particularly the hacks I’ve added to make it easy to run lots of tests from the command-line. =)

  • http://www.developmentseed.org adrian

    Hey sascha,

    Thought I should mention that we’ve been making great progress on the road to Aegir 0.2

    Something of special interest to you should be that we’ve decided to move the drupal install and update commands, for Drupal 5 through 7, upstream into Drush 2.x in the near future. This includes support for both minor and major version upgrades (some more information on how this is used in aegir)

    The commands make full use of several of the new Drush 2.x api features, that allow you to re-use any command either from within the same PHP process, or spawn a new php process for the command, so they are re-usable and scriptable.

    For instance, after downloading a module with the pm toolchain, it will be able to automatically call the update.php script for all the affected sites.

    It’s built to be super flexible and extendable, so you could easily whip up your own scripts to do things such as automated patch testing frameworks, which you could then hook into your svn or cvs trigger scripts, for instance.

    I’ve also broke some ground on a Proper freebsd ports / macports / portage like package management solution for Drush that will allow you to manage multiple sources, and keep your sites up to date far more easily.

  • http://Drupalsightings.com Jim
  • http://mc-kenna.com/ Damien McKenna

    Adrian, I’ll be very interested to hear how your ports-alike goes, am getting into a project that will involve lots of horizontal growth once the core is built.