diff --git a/commands/core/archive.drush.inc b/commands/core/archive.drush.inc index 6df13c2..bb8cf7b 100644 --- a/commands/core/archive.drush.inc +++ b/commands/core/archive.drush.inc @@ -21,6 +21,7 @@ function archive_drush_command() { 'generatorversion' => 'The generator version number to store in the MANIFEST file. The default is ' . DRUSH_VERSION . '.', 'pipe' => 'Only print the destination of the archive. Useful for scripts that don\'t pass --destination.', 'preserve-symlinks' => 'Preserve symbolic links.', + 'no-core' => 'Exclude Drupal core, so include just site specific stuff.', ), 'examples' => array( 'drush archive-dump default,example.com,foo.com' => 'Write an archive containing 3 sites in it.', @@ -65,6 +66,12 @@ function drush_archive_dump($sites_subdirs = '@self') { $tar = drush_get_tar_executable(); $sites = array(); $aliases = drush_sitealias_resolve_sitespecs(explode(',', $sites_subdirs)); + + $include_platform = TRUE; + if (drush_get_option('no-core', FALSE)) { + $include_platform = FALSE; + } + foreach ($aliases as $key => $alias) { $sites[$key] = $alias; if (($db_record = sitealias_get_databases_from_record($alias))) { @@ -163,14 +170,17 @@ function drush_archive_dump($sites_subdirs = '@self') { $docroot_path = realpath(drush_get_context('DRUSH_DRUPAL_ROOT')); $docroot = basename($docroot_path); $workdir = dirname($docroot_path); - $dereference = (drush_get_option('preserve-symlinks', FALSE)) ? '' : '--dereference '; - // Archive Drupal core, excluding sites dir. - drush_shell_cd_and_exec($workdir, "$tar --exclude \"{$docroot}/sites\" {$dereference}-cf %s %s", $destination, $docroot); - // Add sites/all to the same archive. - drush_shell_cd_and_exec($workdir, "$tar {$dereference}-rf %s %s", $destination, "{$docroot}/sites/all"); - // Add sites/sites.php to the same archive. - if (file_exists("{$docroot}/sites/sites.php")) { - drush_shell_cd_and_exec($workdir, "$tar {$dereference}-rf %s %s", $destination, "{$docroot}/sites/sites.php"); + + if ($include_platform) { + $dereference = (drush_get_option('preserve-symlinks', FALSE)) ? '' : '--dereference '; + // Archive Drupal core, excluding sites dir. + drush_shell_cd_and_exec($workdir, "$tar --exclude \"{$docroot}/sites\" {$dereference}-cf %s %s", $destination, $docroot); + // Add sites/all to the same archive. + drush_shell_cd_and_exec($workdir, "$tar {$dereference}-rf %s %s", $destination, "{$docroot}/sites/all"); + // Add sites/sites.php to the same archive. + if (file_exists("{$docroot}/sites/sites.php")) { + drush_shell_cd_and_exec($workdir, "$tar {$dereference}-rf %s %s", $destination, "{$docroot}/sites/sites.php"); + } } $tmp = drush_tempdir(); @@ -205,6 +215,7 @@ function drush_archive_dump($sites_subdirs = '@self') { 'generatorversion' => drush_get_option('generatorversion', DRUSH_VERSION), 'description' => drush_get_option('description', ''), 'tags' => drush_get_option('tags', ''), + 'archive_format' => ($include_platform ? 'platform' : 'site'), ); $contents = drush_export_ini(array('Global' => $platform)); @@ -285,25 +296,7 @@ function drush_archive_restore($file, $site_id = NULL) { return drush_set_error('DRUSH_ARCHIVE_UNABLE_TO_EXTRACT', dt('Unable to extract site archive tarball to !tmp.', array('!tmp' => $tmp))); } - $manifest = $tmp . '/MANIFEST.ini'; - if (file_exists($manifest)) { - if (!$ini = parse_ini_file($manifest, TRUE)) { - return drush_set_error('DRUSH_ARCHIVE_UNABLE_TO_PARSE_MANIFEST', dt('Unable to parse MANIFEST.ini in the archive.')); - } - } - else { - // No manifest. Try to find docroot and DB dump file. - $db_file = drush_scan_directory($tmp, '/\.sql$/', array('.', '..', 'CVS'), 0, 0); - $directories = glob($tmp . '/*' , GLOB_ONLYDIR); - $ini = array( - 'Global' => array(), - 'default' => array( - 'docroot' => reset($directories), - 'sitedir' => 'sites/default', - 'database-default-file' => key($db_file), - ), - ); - } + $ini = drush_archive_read_manifest($tmp); // Grab the first site in the Manifest and move docroot to destination. $ini_tmp = $ini; @@ -311,13 +304,27 @@ function drush_archive_restore($file, $site_id = NULL) { $first = array_shift($ini_tmp); $docroot = basename($first['docroot']); $destination = drush_get_option('destination', realpath('.') . "/$docroot"); - if (!drush_move_dir("$tmp/$docroot", $destination, drush_get_option('overwrite'))) { - return drush_set_error('DRUSH_ARCHIVE_UNABLE _RESTORE_FILES', dt('Unable to restore files to !dest', array('!dest' => $destination))); + + if ($ini['Global']['archive_format'] == 'platform') { + // Move the whole platform inplace at once. + if (!drush_move_dir("$tmp/$docroot", $destination, drush_get_option('overwrite'))) { + return drush_set_error('DRUSH_ARCHIVE_UNABLE _RESTORE_FILES', dt('Unable to restore platform to !dest', array('!dest' => $destination))); + } + } else { + // When no platform is included we do this on a per-site basis + } // Loop over sites and restore databases and append to settings.php. foreach ($ini as $section => $site) { if ($section != 'Global' && (is_null($site_id) || $section == $site_id) && !empty($site['database-default-file'])) { + $site_destination = $destination . '/' . $site['sitedir']; + // Restore site, incase not already done above + if ($ini['Global']['archive_format'] == 'site') { + if (!drush_move_dir("$tmp/$docroot/" . $site['sitedir'], $site_destination, drush_get_option('overwrite'))) { + return drush_set_error('DRUSH_ARCHIVE_UNABLE _RESTORE_FILES', dt('Unable to restore site to !dest', array('!dest' => $site_destination))); + } + } // Restore database $sql_file = $tmp . '/' . $site['database-default-file']; @@ -343,7 +350,7 @@ function drush_archive_restore($file, $site_id = NULL) { // Append new DB info to settings.php. if ($db_url) { - $settingsfile = $destination . '/' . $site['sitedir'] . '/settings.php'; + $settingsfile = $site_destination . '/settings.php'; chmod($settingsfile, 0755); // Need to do something here or else we can't write. file_put_contents($settingsfile, "\n// Appended by drush archive-restore command.\n", FILE_APPEND); if (drush_drupal_major_version($destination) >= 7) { @@ -380,3 +387,49 @@ function archive_archive_restore_complete() { ), ); } + +/** + * Read and parse the MANIFEST from an extracted archive + * + * @param string $path The location of theextracted archive + * @return array The manifest data + */ +function drush_archive_read_manifest($path) { + $manifest = $path . '/MANIFEST.ini'; + if (file_exists($manifest)) { + if (!$ini = parse_ini_file($manifest, TRUE)) { + return drush_set_error('DRUSH_ARCHIVE_UNABLE_TO_PARSE_MANIFEST', dt('Unable to parse MANIFEST.ini in the archive.')); + } + } + else { + // No manifest. Try to find docroot and DB dump file. + $db_file = drush_scan_directory($path, '/\.sql$/', array('.', '..', 'CVS'), 0, 0); + + if (file_exists($path . '/index.php')) { + $docroot = './'; + } + else { + $directories = glob($path . '/*' , GLOB_ONLYDIR); + $docroot = reset($directories); + } + + $ini = array( + 'Global' => array( + // Very crude detection of a platform... + 'archive_format' => (file_exists($directories . '/modules') ? 'platform' : 'site'), + ), + 'default' => array( + 'docroot' => $docroot, + 'sitedir' => 'sites/default', + 'database-default-file' => key($db_file), + ), + ); + } + + // Format compatibility, for 1.0 this option initially did not exist. + if (!isset( $ini['Global']['archive_format'])) { + $ini['Global']['archive_format'] = 'platform'; + } + + return $ini; +} diff --git a/docs/site-archive-format.html b/docs/site-archive-format.html new file mode 100644 index 0000000..31d8517 --- /dev/null +++ b/docs/site-archive-format.html @@ -0,0 +1,81 @@ +
Drush has the commands archive-dump and archive-restore to store a site in an archive file.
+Discussion: http://groups.drupal.org/site-archive-format
+ ++[Global] +datestamp = "1317033628" +formatversion = "1.0" +generator = "Drush archive-dump" +generatorversion = "5.0-dev" +archive_format = "platform" + +[dev] +docroot = "/tmp/drush-sandbox/web" +sitedir = "sites/dev" +files-public = "sites/dev/files" +database-default-file = "./unish_dev.sql" +database-default-driver = "mysql" ++@TODO: List possible properties and their possible values, are there any missing? +