X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fdrush%2Fdrush%2Fsrc%2FCommands%2Fcore%2FRsyncCommands.php;fp=vendor%2Fdrush%2Fdrush%2Fsrc%2FCommands%2Fcore%2FRsyncCommands.php;h=96bf9c437981de4ddd9c742c1cc0d86e8420cb03;hp=0000000000000000000000000000000000000000;hb=af6d1fb995500ae68849458ee10d66abbdcfb252;hpb=680c79a86e3ed402f263faeac92e89fb6d9edcc0 diff --git a/vendor/drush/drush/src/Commands/core/RsyncCommands.php b/vendor/drush/drush/src/Commands/core/RsyncCommands.php new file mode 100644 index 000000000..96bf9c437 --- /dev/null +++ b/vendor/drush/drush/src/Commands/core/RsyncCommands.php @@ -0,0 +1,167 @@ +pathEvaluator = new BackendPathEvaluator(); + } + + /** + * Rsync Drupal code or files to/from another server using ssh. + * + * @command core:rsync + * @param $source A site alias and optional path. See rsync documentation and example.site.yml. + * @param $target A site alias and optional path. See rsync documentation and example.site.yml.', + * @param $extra Additional parameters after the ssh statement. + * @optionset_ssh + * @option exclude-paths List of paths to exclude, seperated by : (Unix-based systems) or ; (Windows). + * @option include-paths List of paths to include, seperated by : (Unix-based systems) or ; (Windows). + * @option mode The unary flags to pass to rsync; --mode=rultz implies rsync -rultz. Default is -akz. + * @usage drush rsync @dev @stage + * Rsync Drupal root from Drush alias dev to the alias stage. + * @usage drush rsync ./ @stage:%files/img + * Rsync all files in the current directory to the 'img' directory in the file storage folder on the Drush alias stage. + * @usage drush rsync @dev @stage -- --exclude=*.sql --delete + * Rsync Drupal root from the Drush alias dev to the alias stage, excluding all .sql files and delete all files on the destination that are no longer on the source. + * @usage drush rsync @dev @stage --ssh-options="-o StrictHostKeyChecking=no" -- --delete + * Customize how rsync connects with remote host via SSH. rsync options like --delete are placed after a --. + * @aliases rsync,core-rsync + * @topics docs:aliases + */ + public function rsync($source, $target, array $extra, $options = ['exclude-paths' => self::REQ, 'include-paths' => self::REQ, 'mode' => 'akz']) + { + // Prompt for confirmation. This is destructive. + if (!\Drush\Drush::simulate()) { + $this->output()->writeln(dt("You will delete files in !target and replace with data from !source", ['!source' => $this->sourceEvaluatedPath->fullyQualifiedPathPreservingTrailingSlash(), '!target' => $this->targetEvaluatedPath->fullyQualifiedPath()])); + if (!$this->io()->confirm(dt('Do you want to continue?'))) { + throw new UserAbortException(); + } + } + + $rsync_options = $this->rsyncOptions($options); + $parameters = array_merge([$rsync_options], $extra); + $parameters[] = $this->sourceEvaluatedPath->fullyQualifiedPathPreservingTrailingSlash(); + $parameters[] = $this->targetEvaluatedPath->fullyQualifiedPath(); + + $ssh_options = Drush::config()->get('ssh.options', ''); + $exec = "rsync -e 'ssh $ssh_options'". ' '. implode(' ', array_filter($parameters)); + $exec_result = drush_op_system($exec); + + if ($exec_result == 0) { + drush_backend_set_result($this->targetEvaluatedPath->fullyQualifiedPath()); + } else { + throw new \Exception(dt("Could not rsync from !source to !dest", ['!source' => $this->sourceEvaluatedPath->fullyQualifiedPathPreservingTrailingSlash(), '!dest' => $this->targetEvaluatedPath->fullyQualifiedPath()])); + } + } + + public function rsyncOptions($options) + { + $verbose = $paths = ''; + // Process --include-paths and --exclude-paths options the same way + foreach (['include', 'exclude'] as $include_exclude) { + // Get the option --include-paths or --exclude-paths and explode to an array of paths + // that we will translate into an --include or --exclude option to pass to rsync + $inc_ex_path = explode(PATH_SEPARATOR, @$options[$include_exclude . '-paths']); + foreach ($inc_ex_path as $one_path_to_inc_ex) { + if (!empty($one_path_to_inc_ex)) { + $paths .= ' --' . $include_exclude . '="' . $one_path_to_inc_ex . '"'; + } + } + } + + $mode = '-'. $options['mode']; + if ($this->output()->isVerbose()) { + $mode .= 'v'; + $verbose = ' --stats --progress'; + } + + return implode(' ', array_filter([$mode, $verbose, $paths])); + } + + /** + * Evaluate the path aliases in the source and destination + * parameters. We do this in the pre-command-event so that + * we can set up the configuration object to include options + * from the source and target aliases, if any, so that these + * values may participate in configuration injection. + * + * @hook command-event core:rsync + * @param ConsoleCommandEvent $event + * @throws \Exception + * @return void + */ + public function preCommandEvent(ConsoleCommandEvent $event) + { + $input = $event->getInput(); + $this->sourceEvaluatedPath = $this->injectAliasPathParameterOptions($input, 'source'); + $this->targetEvaluatedPath = $this->injectAliasPathParameterOptions($input, 'target'); + } + + protected function injectAliasPathParameterOptions($input, $parameterName) + { + // The Drush configuration object is a ConfigOverlay; fetch the alias + // context, that already has the options et. al. from the + // site-selection alias ('drush @site rsync ...'), @self. + $aliasConfigContext = $this->getConfig()->getContext(ConfigLocator::ALIAS_CONTEXT); + $manager = $this->siteAliasManager(); + + $aliasName = $input->getArgument($parameterName); + $evaluatedPath = HostPath::create($manager, $aliasName); + $this->pathEvaluator->evaluate($evaluatedPath); + + $aliasRecord = $evaluatedPath->getAliasRecord(); + + // If the path is remote, then we will also inject the global + // options into the alias config context so that we pick up + // things like ssh-options. + if ($aliasRecord->isRemote()) { + $aliasConfigContext->combine($aliasRecord->export()); + } + + return $evaluatedPath; + } + + /** + * Validate that passed aliases are valid. + * + * @hook validate core-rsync + * @param \Consolidation\AnnotatedCommand\CommandData $commandData + * @throws \Exception + * @return void + */ + public function validate(CommandData $commandData) + { + if ($this->sourceEvaluatedPath->isRemote() && $this->targetEvaluatedPath->isRemote()) { + $msg = dt("Cannot specify two remote aliases. Instead, use one of the following alternate options:\n\n `drush {source} rsync @self {target}`\n `drush {source} rsync @self {fulltarget}\n\nUse the second form if the site alias definitions are not available at {source}.", ['source' => $source, 'target' => $target, 'fulltarget' => $this->targetEvaluatedPath->fullyQualifiedPath()]); + throw new \Exception($msg); + } + } +}