rsync.core.inc

  1. 8.0.x commands/core/rsync.core.inc
  2. 6.x commands/core/rsync.core.inc
  3. 7.x commands/core/rsync.core.inc
  4. 3.x commands/core/rsync.core.inc
  5. 4.x commands/core/rsync.core.inc
  6. 5.x commands/core/rsync.core.inc
  7. master commands/core/rsync.core.inc

Functions

Namesort descending Description
drush_core_call_rsync Make a direct call to rsync after the source and destination paths have been evaluated.
drush_core_exec_rsync
drush_core_rsync A command callback.
drush_core_rsync_init
_drush_build_rsync_options
_drush_rsync_option_exists

File

commands/core/rsync.core.inc
View source
  1. <?php
  2. use Drush\Log\LogLevel;
  3. /*
  4. * Implements COMMAND hook init.
  5. */
  6. function drush_core_rsync_init() {
  7. // Try to get @self defined when --uri was not provided.
  8. drush_bootstrap_max(DRUSH_BOOTSTRAP_DRUPAL_SITE);
  9. }
  10. /**
  11. * A command callback.
  12. *
  13. * @param source
  14. * A site alias ("@dev") or site specification ("/path/to/drupal#mysite.com")
  15. * followed by an optional path (":path/to/sync"), or any path
  16. * that could be passed to rsync ("user@server.com:/path/to/dir/").
  17. * @param destination
  18. * Same format as source.
  19. * @param additional_options
  20. * An array of options that overrides whatever was passed in on
  21. * the command line (like the 'process' context, but only for
  22. * the scope of this one call).
  23. */
  24. function drush_core_rsync($source, $destination, $additional_options = array()) {
  25. // Preflight source in case it defines aliases used by the destination
  26. _drush_sitealias_preflight_path($source);
  27. // After preflight, evaluate file paths. We evaluate destination paths first, because
  28. // there is a first-one-wins policy with --exclude-paths, and we want --target-command-specific
  29. // to take precedence over --source-command-specific.
  30. $destination_settings = drush_sitealias_evaluate_path($destination, $additional_options, FALSE, "rsync", 'target-');
  31. $source_settings = drush_sitealias_evaluate_path($source, $additional_options, FALSE, "rsync", 'source-');
  32. $source_path = $source_settings['evaluated-path'];
  33. $destination_path = $destination_settings['evaluated-path'];
  34. if (!isset($source_settings)) {
  35. return drush_set_error('DRUSH_BAD_PATH', dt('Could not evaluate source path !path.', array('!path' => $source)));
  36. }
  37. if (!isset($destination_settings)) {
  38. return drush_set_error('DRUSH_BAD_PATH', dt('Could not evaluate destination path !path.', array('!path' => $destination)));
  39. }
  40. // If the user path is the same for the source and the destination, then
  41. // always add a slash to the end of the source. If the user path is not
  42. // the same in the source and the destination, then you need to know how
  43. // rsync paths work, and put on the trailing '/' if you want it.
  44. if ($source_settings['user-path'] == $destination_settings['user-path']) {
  45. $source_path .= '/';
  46. }
  47. // Prompt for confirmation. This is destructive.
  48. if (!drush_get_context('DRUSH_SIMULATE')) {
  49. drush_print(dt("You will destroy data from !target and replace with data from !source", array('!source' => $source_path, '!target' => $destination_path)));
  50. if (!drush_confirm(dt('Do you really want to continue?'))) {
  51. // was: return drush_set_error('CORE_SYNC_ABORT', 'Aborting.');
  52. return drush_user_abort();
  53. }
  54. }
  55. // Exclude settings is the default only when both the source and
  56. // the destination are aliases or site names. Therefore, include
  57. // settings will be the default whenever either the source or the
  58. // destination contains a : or a /.
  59. $include_settings_is_default = (strpos($source . $destination, ':') !== FALSE) || (strpos($source . $destination, '/') !== FALSE);
  60. $options = _drush_build_rsync_options($additional_options, $include_settings_is_default);
  61. // Get all of the args and options that appear after the command name.
  62. $original_args = drush_get_original_cli_args_and_options();
  63. foreach ($original_args as $original_option) {
  64. if ($original_option{0} == '-') {
  65. $options .= ' ' . $original_option;
  66. }
  67. }
  68. drush_backend_set_result($destination_path);
  69. // Go ahead and call rsync with the paths we determined
  70. return drush_core_exec_rsync($source_path, $destination_path, $options);
  71. }
  72. /**
  73. * Make a direct call to rsync after the source and destination paths
  74. * have been evaluated.
  75. *
  76. * @param $source
  77. * Any path that can be passed to rsync.
  78. * @param $destination
  79. * Any path that can be passed to rsync.
  80. * @param $additional_options
  81. * An array of options that overrides whatever was passed in on the command
  82. * line (like the 'process' context, but only for the scope of this one
  83. * call).
  84. * @param $include_settings_is_default
  85. * If TRUE, then settings.php will be transferred as part of the rsync unless
  86. * --exclude-conf is specified. If FALSE, then settings.php will be excluded
  87. * from the transfer unless --include-conf is specified.
  88. * @param $live_output
  89. * If TRUE, output goes directly to the terminal using system(). If FALSE,
  90. * rsync is executed with drush_shell_exec() with output in
  91. * drush_shell_exec_output().
  92. *
  93. * @return
  94. * TRUE on success, FALSE on failure.
  95. */
  96. function drush_core_call_rsync($source, $destination, $additional_options = array(), $include_settings_is_default = TRUE, $live_output = TRUE) {
  97. $options = _drush_build_rsync_options($additional_options, $include_settings_is_default);
  98. return drush_core_exec_rsync($source, $destination, $options, $additional_options, $live_output);
  99. }
  100. function drush_core_exec_rsync($source, $destination, $options, $additional_options = array(), $live_output = TRUE) {
  101. $ssh_options = drush_get_option_override($additional_options, 'ssh-options', '');
  102. $exec = "rsync -e 'ssh $ssh_options' $options $source $destination";
  103. if ($live_output) {
  104. $exec_result = drush_op_system($exec);
  105. $result = ($exec_result == 0);
  106. }
  107. else {
  108. $result = drush_shell_exec($exec);
  109. }
  110. if (!$result) {
  111. drush_set_error('DRUSH_RSYNC_FAILED', dt("Could not rsync from !source to !dest", array('!source' => $source, '!dest' => $destination)));
  112. }
  113. return $result;
  114. }
  115. function _drush_build_rsync_options($additional_options, $include_settings_is_default = TRUE) {
  116. $options = '';
  117. // Exclude vcs reserved files.
  118. if (!_drush_rsync_option_exists('include-vcs', $additional_options)) {
  119. $vcs_files = drush_version_control_reserved_files();
  120. foreach ($vcs_files as $file) {
  121. $options .= ' --exclude="'.$file.'"';
  122. }
  123. }
  124. else {
  125. unset($additional_options['include-vcs']);
  126. }
  127. $mode = '-akz';
  128. // Process --include-paths and --exclude-paths options the same way
  129. foreach (array('include', 'exclude') as $include_exclude) {
  130. // Get the option --include-paths or --exclude-paths and explode to an array of paths
  131. // that we will translate into an --include or --exclude option to pass to rsync
  132. $inc_ex_path = explode(PATH_SEPARATOR, drush_get_option($include_exclude . '-paths', ''));
  133. foreach ($inc_ex_path as $one_path_to_inc_ex) {
  134. if (!empty($one_path_to_inc_ex)) {
  135. $options .= ' --' . $include_exclude . '="' . $one_path_to_inc_ex . '"';
  136. }
  137. }
  138. // Remove stuff inserted by evaluate path
  139. unset($additional_options[$include_exclude . '-paths']);
  140. unset($additional_options[$include_exclude . '-files-processed']);
  141. }
  142. // drush_core_rsync passes in $include_settings_is_default such that
  143. // 'exclude-conf' is the default when syncing from one alias to
  144. // another, and 'include-conf' is the default when a path component
  145. // is included.
  146. if ($include_settings_is_default ? _drush_rsync_option_exists('exclude-conf', $additional_options) : !_drush_rsync_option_exists('include-conf', $additional_options)) {
  147. $options .= ' --exclude="settings.php"';
  148. unset($additional_options['exclude-conf']);
  149. }
  150. if (_drush_rsync_option_exists('exclude-sites', $additional_options)) {
  151. $options .= ' --include="sites/all" --exclude="sites/*"';
  152. unset($additional_options['exclude-sites']);
  153. }
  154. if (_drush_rsync_option_exists('mode', $additional_options)) {
  155. $mode = "-" . drush_get_option_override($additional_options, 'mode');
  156. unset($additional_options['mode']);
  157. }
  158. if (drush_get_context('DRUSH_VERBOSE')) {
  159. // the drush_op() will be verbose about the command that gets executed.
  160. $mode .= 'v';
  161. $options .= ' --stats --progress';
  162. }
  163. // Check if the user has set $options['rsync-version'] to enable rsync legacy version support.
  164. // Drush was written for rsync 2.6.9 or later, so assume that version if nothing was explicitly set.
  165. $rsync_version = drush_get_option(array('rsync-version','source-rsync-version','target-rsync-version'), '2.6.9');
  166. $options_to_exclude = array('ssh-options');
  167. foreach ($additional_options as $test_option => $value) {
  168. // Downgrade some options for older versions of rsync
  169. if ($test_option == 'remove-source-files') {
  170. if (version_compare($rsync_version, '2.6.4', '<')) {
  171. $test_option = NULL;
  172. drush_log('Rsync does not support --remove-sent-files prior to version 2.6.4; some temporary files may remain undeleted.', LogLevel::WARNING);
  173. }
  174. elseif (version_compare($rsync_version, '2.6.9', '<')) {
  175. $test_option = 'remove-sent-files';
  176. }
  177. }
  178. if ((isset($test_option)) && !in_array($test_option, $options_to_exclude) && (isset($value) && !is_array($value))) {
  179. if (($value === TRUE) || (!isset($value))) {
  180. $options .= " --$test_option";
  181. }
  182. else {
  183. $options .= " --$test_option=" . escapeshellarg($value);
  184. }
  185. }
  186. }
  187. return $mode . $options;
  188. }
  189. function _drush_rsync_option_exists($option, $additional_options) {
  190. if (array_key_exists($option, $additional_options)) {
  191. return TRUE;
  192. }
  193. else {
  194. return drush_get_option($option, FALSE);
  195. }
  196. }