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_rsync Entrypoint for drush rsync.
_drush_rsync_option_exists

File

commands/core/rsync.core.inc
View source
  1. <?php
  2. /**
  3. * Entrypoint for drush rsync.
  4. *
  5. * @param source
  6. * A site alias ("@dev") or site specification ("/path/to/drupal#mysite.com")
  7. * followed by an optional path (":path/to/sync"), or any path
  8. * that could be passed to rsync ("user@server.com:/path/to/dir/").
  9. * @param destination
  10. * Same format as source.
  11. * @param additional_options
  12. * An array of options that overrides whatever was passed in on
  13. * the command line (like the 'process' context, but only for
  14. * the scope of this one call).
  15. */
  16. function drush_core_rsync($source, $destination, $additional_options = array()) {
  17. // Preflight destination in case it defines aliases used by the source
  18. _drush_sitealias_preflight_path($destination);
  19. // After preflight, evaluate file paths
  20. $source_settings = drush_sitealias_evaluate_path($source, $additional_options);
  21. $destination_settings = drush_sitealias_evaluate_path($destination, $additional_options);
  22. $source_path = $source_settings['evaluated-path'];
  23. $destination_path = $destination_settings['evaluated-path'];
  24. if (!isset($source_settings)) {
  25. return drush_set_error('DRUSH_BAD_PATH', dt('Could not evaluate source path !path.', array('!path' => $source)));
  26. }
  27. if (!isset($destination_settings)) {
  28. return drush_set_error('DRUSH_BAD_PATH', dt('Could not evaluate destination path !path.', array('!path' => $destination)));
  29. }
  30. // Check to see if this is an rsync multiple command (multiple sources and multiple destinations)
  31. $is_multiple = drush_do_multiple_command('rsync', $source_settings, $destination_settings, TRUE);
  32. if ($is_multiple === FALSE) {
  33. // If the user path is the same for the source and the destination, then
  34. // always add a slash to the end of the source. If the user path is not
  35. // the same in the source and the destination, then you need to know how
  36. // rsync paths work, and put on the trailing '/' if you want it.
  37. if ($source_settings['user-path'] == $destination_settings['user-path']) {
  38. $source_path .= '/';
  39. }
  40. // Prompt for confirmation. This is destructive.
  41. if (!drush_get_context('DRUSH_SIMULATE')) {
  42. drush_print(dt("You will destroy data from !target and replace with data from !source", array('!source' => $source_path, '!target' => $destination_path)));
  43. if (!drush_confirm(dt('Do you really want to continue?'))) {
  44. // was: return drush_set_error('CORE_SYNC_ABORT', 'Aborting.');
  45. return drush_user_abort();
  46. }
  47. }
  48. // Exclude settings is the default only when both the source and
  49. // the destination are aliases or site names. Therefore, include
  50. // settings will be the default whenever either the source or the
  51. // destination contains a : or a /.
  52. $include_settings_is_default = (strpos($source . $destination, ':') !== FALSE) || (strpos($source . $destination, '/') !== FALSE);
  53. // Go ahead and call rsync with the paths we determined
  54. return drush_core_call_rsync($source_path, $destination_path, $additional_options, $include_settings_is_default);
  55. }
  56. }
  57. /**
  58. * Make a direct call to rsync after the source and destination paths
  59. * have been evaluated.
  60. *
  61. * @param $source
  62. * Any path that can be passed to rsync.
  63. * @param $destination
  64. * Any path that can be passed to rsync.
  65. * @param $additional_options
  66. * An array of options that overrides whatever was passed in on the command
  67. * line (like the 'process' context, but only for the scope of this one
  68. * call).
  69. * @param $include_settings_is_default
  70. * If TRUE, then settings.php will be transferred as part of the rsync unless
  71. * --exclude-conf is specified. If FALSE, then settings.php will be excluded
  72. * from the transfer unless --include-conf is specified.
  73. * @param $live_output
  74. * If TRUE, output goes directly to the terminal using system(). If FALSE,
  75. * rsync is executed with drush_shell_exec() with output in
  76. * drush_shell_exec_output().
  77. *
  78. * @return
  79. * TRUE on success, FALSE on failure.
  80. */
  81. function drush_core_call_rsync($source, $destination, $additional_options = array(), $include_settings_is_default = TRUE, $live_output = TRUE) {
  82. // Exclude vcs reserved files.
  83. $options = '';
  84. if (!_drush_rsync_option_exists('include-vcs', $additional_options)) {
  85. $vcs_files = drush_version_control_reserved_files();
  86. foreach ($vcs_files as $file) {
  87. $options .= ' --exclude="'.$file.'"';
  88. }
  89. }
  90. $mode = '-az';
  91. // Process --include-path and --exclude-path options the same way
  92. foreach (array('include', 'exclude') as $include_exclude) {
  93. // Get the option --include-path or --exclude-path and explode to an array of paths
  94. // that we will translate into an --include or --exclude option to pass to rsync
  95. $inc_ex_path = explode(PATH_SEPARATOR, drush_get_option(array($include_exclude . '-path', $include_exclude . '-paths'), ''));
  96. foreach ($inc_ex_path as $one_path_to_inc_ex) {
  97. if (!empty($one_path_to_inc_ex)) {
  98. $options .= ' --' . $include_exclude . '="' . $one_path_to_inc_ex . '"';
  99. }
  100. }
  101. }
  102. // drush_core_rsync passes in $include_settings_is_default such that
  103. // 'exclude-conf' is the default when syncing from one alias to
  104. // another, and 'include-conf' is the default when a path component
  105. // is included.
  106. if ($include_settings_is_default ? _drush_rsync_option_exists('exclude-conf', $additional_options) : !_drush_rsync_option_exists('include-conf', $additional_options)) {
  107. $options .= ' --exclude="settings.php"';
  108. }
  109. if (_drush_rsync_option_exists('exclude-sites', $additional_options)) {
  110. $options .= ' --include="sites/all" --exclude="sites/*"';
  111. }
  112. if (_drush_rsync_option_exists('mode', $additional_options)) {
  113. $mode = "-" . drush_get_option_override($additional_options, 'mode');
  114. }
  115. if (drush_get_context('DRUSH_VERBOSE')) {
  116. // the drush_op() will be verbose about the command that gets executed.
  117. $mode .= 'v';
  118. $options .= ' --stats --progress';
  119. }
  120. $rsync_available_options = array(
  121. // unary options
  122. 'archive', // -a
  123. 'recursive', // -r
  124. 'relative', // -R
  125. 'backup', // -b
  126. 'update', // -u
  127. 'checksum', // -c
  128. 'dirs', // -d
  129. 'links', // -l
  130. 'copy-links', // -L
  131. 'copy-dirlinks', // -k
  132. 'keep-dirlinks', // -K
  133. 'hard-links', // -H
  134. 'perms', // -p
  135. 'executability', // -E
  136. 'acls', // -A
  137. 'xattrs', // -X
  138. 'owner', // -o
  139. 'group', // -g
  140. 'times', // -t
  141. 'omit-dir-times', // -O
  142. 'sparse', // -S
  143. 'dry-run', // -n
  144. 'whole-file', // -W
  145. 'one-file-system', // -x
  146. 'prune-empty-dirs', // -m
  147. 'ignore-times', // -I
  148. 'fuzzy', // -y
  149. 'cvs-exclude', // -C
  150. 'compress', // -Z
  151. 'protect-args', // -s
  152. '8-bit-output', // -8
  153. 'human-readable', // -h
  154. 'itemize-changes', // -i
  155. 'copy-unsafe-links',
  156. 'safe-links',
  157. 'no-implied-dirs',
  158. 'inplace',
  159. 'append',
  160. 'append-verify',
  161. 'existing',
  162. 'remove-source-files',
  163. 'delete',
  164. 'delete-before',
  165. 'delete-during',
  166. 'delete-delay',
  167. 'delete-after',
  168. 'delete-excluded',
  169. 'ignore-errors',
  170. 'force',
  171. 'ignore-existing',
  172. 'partial',
  173. 'delay-updates',
  174. 'numeric-ids',
  175. 'size-only',
  176. 'blocking-io',
  177. 'stats',
  178. 'progress',
  179. 'list-only',
  180. // options with values
  181. 'block-size',
  182. 'backup-dir',
  183. 'suffix',
  184. 'chmod',
  185. 'rsync-path',
  186. 'modify-window',
  187. 'compare-dest',
  188. 'copy-dest',
  189. 'link-dest',
  190. 'skip-compress',
  191. 'filter',
  192. 'exclude',
  193. 'exclude-from',
  194. 'include',
  195. 'include-from',
  196. 'files-from',
  197. 'address',
  198. 'port',
  199. 'sockopts',
  200. 'out-format',
  201. 'bwlimit',
  202. 'iconv',
  203. 'checksum-seed',
  204. 'max-delete',
  205. 'max-size',
  206. 'min-size',
  207. 'partial-dir',
  208. 'timeout',
  209. 'temp-dir',
  210. 'compress-level',
  211. 'out-format',
  212. 'protocol',
  213. );
  214. // Check if the user has set $options['rsync-version'] to enable rsync legacy version support.
  215. // Drush was written for rsync 2.6.9 or later, so assume that version if nothing was explicitly set.
  216. $rsync_version = drush_get_option(array('rsync-version','source-rsync-version','target-rsync-version'), '2.6.9');
  217. foreach ($rsync_available_options as $test_option) {
  218. $value = drush_get_option_override($additional_options, $test_option);
  219. // Downgrade some options for older versions of rsync
  220. if ($test_option == 'remove-source-files') {
  221. if (version_compare($rsync_version, '2.6.4', '<')) {
  222. $test_option = NULL;
  223. drush_log('Rsync does not support --remove-sent-files prior to version 2.6.4; some temporary files may remain undeleted.', 'warning');
  224. }
  225. elseif (version_compare($rsync_version, '2.6.9', '<')) {
  226. $test_option = 'remove-sent-files';
  227. }
  228. }
  229. if ((isset($test_option)) && (isset($value))) {
  230. if ($value === TRUE) {
  231. $options .= " --$test_option";
  232. }
  233. else {
  234. $options .= " --$test_option=" . escapeshellarg($value);
  235. }
  236. }
  237. }
  238. $ssh_options = drush_get_option_override($additional_options, 'ssh-options', '');
  239. $exec = "rsync -e 'ssh $ssh_options' $mode$options $source $destination";
  240. if ($live_output) {
  241. $exec_result = drush_op_system($exec);
  242. $result = ($exec_result == 0);
  243. }
  244. else {
  245. $result = drush_shell_exec($exec);
  246. }
  247. if (!$result) {
  248. drush_set_error('DRUSH_RSYNC_FAILED', dt("Could not rsync from !source to !dest", array('!source' => $source, '!dest' => $destination)));
  249. }
  250. return $result;
  251. }
  252. function _drush_rsync_option_exists($option, $additional_options) {
  253. if (array_key_exists($option, $additional_options)) {
  254. return TRUE;
  255. }
  256. else {
  257. return drush_get_option($option, FALSE);
  258. }
  259. }