Last active
December 18, 2017 21:20
-
-
Save gapple/d802b86295ffe62c78c6 to your computer and use it in GitHub Desktop.
Drush command to sync files directories between aliases https://gapple.github.io/drush-plugins/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @file | |
* Provide a file-sync command to sync files directories between environments. | |
*/ | |
/** | |
* Implements hook_drush_command(). | |
*/ | |
function file_sync_drush_command() { | |
$commands = array(); | |
$commands['file-sync'] = array( | |
'description' => 'Sync files directories between sites', | |
'aliases' => array('fsync'), | |
'arguments' => array( | |
'source' => 'Source alias', | |
'destination' => 'Destination alias', // TODO make this optional and default to @self | |
), | |
'options' => array( | |
'only-public' => 'Only sync the public files directory', | |
'only-private' => 'Only sync the private files directory', | |
), | |
'required-arguments' => TRUE, | |
'bootstrap' => DRUSH_BOOTSTRAP_DRUSH, | |
'examples' => array( | |
'drush fsync @source @destination' => 'Sync both the public and private files directories', | |
'drush fsync --only-public @source @destination' => 'Only sync the public files directory', | |
), | |
); | |
return $commands; | |
} | |
/** | |
* Implements hook_drush_help_alter(). | |
*/ | |
function file_sync_drush_help_alter(&$command) { | |
$commands = drush_get_commands(); | |
// Append all of core-rsync's options to file-sync. | |
// This is needed to prevent drush_core_rsync() from sending the additional | |
// options for core-rsync through to rsync as well. | |
if ($command['command'] === 'file-sync' && isset($commands['core-rsync'])) { | |
$command['options'] += $commands['core-rsync']['options']; | |
} | |
} | |
/** | |
* File sync command callback. | |
*/ | |
function drush_file_sync($source, $destination) { | |
$only_public = drush_get_option('only-public', FALSE); | |
$only_private = drush_get_option('only-private', FALSE); | |
if ($only_public && $only_private) { | |
drush_log(dt('Only one of --only-public or --only-private can be set'), 'error'); | |
return false; | |
} | |
// drush_unset_option() is needed to prevent the options for file-sync getting | |
// passed through to core-rsync. | |
// core-rync loads the original command line options to pass to rsync, so some | |
// additional context-hacking is needed. | |
// see drush_core_rsync() and drush_get_original_cli_args_and_options(). | |
$args = &drush_get_context('DRUSH_COMMAND_ARGS', array()); | |
$original_args = $args; | |
$command = drush_get_command(); | |
foreach (array_keys($command['options']) as $option) { | |
drush_unset_option($option, 'cli'); | |
$arg_index = array_search('--' . $option, $args); | |
if ($arg_index !== FALSE) { | |
unset($args[$arg_index]); | |
} | |
} | |
$args = array_values($args); | |
$public_result = FALSE; | |
if (!$only_private) { | |
drush_log(dt('Syncing public files'), 'status'); | |
$public_result = _drush_file_sync_path_alias($source, $destination, '%files'); | |
} | |
$private_result = FALSE; | |
if (!$only_public) { | |
drush_log(dt('Syncing private files'), 'status'); | |
$private_result = _drush_file_sync_path_alias($source, $destination, '%private', $only_private? 'error': 'warning'); | |
} | |
// Restore the original arguments just to be safe. | |
$args = $original_args; | |
if ( | |
(!$only_private && !$public_result) | |
|| | |
($only_private && !$private_result) | |
) { | |
// If public transfer is attempted but fails, it's always an error. | |
// If private transfer is attempted but fails, it's an error if only | |
// transferring private files was attempted. | |
drush_log(dt('Sync could not complete successfully'), 'error'); | |
} | |
else if (!$only_public && !$only_private && !$private_result) { | |
// A private file path may not be defined, so it's only a warning if the | |
// private transfer could not be completed while attempting to transfer all | |
// files. | |
drush_log(dt('Sync partially completed'), 'warning'); | |
} | |
else { | |
drush_log(dt('Sync completed successfully'), 'success'); | |
} | |
} | |
/** | |
* Helper function to sync a single path between two environments. | |
* | |
* @param $source | |
* @param $destination | |
* @param $path_alias | |
* @param $error_level | |
* If sync fails, what error level should be used. | |
* @return bool | |
*/ | |
function _drush_file_sync_path_alias($source, $destination, $path_alias, $error_level = 'error') { | |
$additional_options = array(); | |
// Check that the path alias can be resolved properly before starting the transfer. | |
$source_path = $source . ':'. $path_alias; | |
$source_alias_info = drush_sitealias_evaluate_path($source_path, $additional_options); | |
if (empty($source_alias_info['path-aliases'][$path_alias])) { | |
drush_log(dt('Could not evaluate source path !path.', array('!path' => $source_path)), $error_level); | |
return FALSE; | |
} | |
$destination_path = $destination . ':' . $path_alias; | |
$destination_alias_info = drush_sitealias_evaluate_path($destination_path, $additional_options); | |
if (empty($destination_alias_info['path-aliases'][$path_alias])) { | |
drush_log(dt('Could not evaluate destination path !path.', array('!path' => $destination_path)), $error_level); | |
return FALSE; | |
} | |
drush_invoke('rsync', array($source_path, $destination_path)); | |
// drush_command() doesn't pass along the return value from rsync for | |
// drush_invoke() to make use of, so it's necessary to check the error log. | |
return drush_get_error() === DRUSH_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Now available in its own repository: https://github.com/gapple/drush-filesync