false, 'label' => 'sync', 'runner' => null]) { $global_options = Drush::redispatchOptions() + ['strict' => 0]; // @todo If either call is made interactive, we don't get an $return['object'] back. $backend_options = ['interactive' => false]; if (Drush::simulate()) { $backend_options['backend-simulate'] = true; } $export_options = [ // Use the standard backup directory on Destination. 'destination' => true, 'yes' => null, ]; $this->logger()->notice(dt('Starting to export configuration on Target.')); $return = drush_invoke_process($source, 'config-export', [], $global_options + $export_options, $backend_options); if ($return['error_status']) { throw new \Exception(dt('Config-export failed.')); } else { // Trailing slash assures that we transfer files and not the containing dir. $export_path = $return['object'] . '/'; } $rsync_options = [ '--remove-source-files', '--delete', '--exclude=.htaccess', ]; if (strpos($destination, ':') === false) { $destination .= ':%config-' . $options['label']; } $destinationHostPath = HostPath::create($this->siteAliasManager(), $destination); if (!$runner = $options['runner']) { $sourceRecord = $this->siteAliasManager()->get($source); $destinationRecord = $destinationHostPath->getAliasRecord(); $runner = $sourceRecord->isRemote() && $destinationRecord->isRemote() ? $destinationRecord : '@self'; } $this->logger() ->notice(dt('Starting to rsync configuration files from !source to !dest.', [ '!source' => $source, '!dest' => $destinationHostPath->getOriginal(), ])); // This comment applies similarly to sql-sync's use of core-rsync. // Since core-rsync is a strict-handling command and drush_invoke_process() puts options at end, we can't send along cli options to rsync. // Alternatively, add options like ssh.options to a site alias (usually on the machine that initiates the sql-sync). $return = drush_invoke_process($runner, 'core-rsync', array_merge([ "$source:$export_path", $destinationHostPath->getOriginal(), '--' ], $rsync_options), ['yes' => true], $backend_options); if ($return['error_status']) { throw new \Exception(dt('Config-pull rsync failed.')); } drush_backend_set_result($return['object']); } /** * @hook validate config-pull */ public function validateConfigPull(CommandData $commandData) { if ($commandData->input()->getOption('safe')) { $return = drush_invoke_process($commandData->input() ->getArgument('destination'), 'core-execute', ['git diff --quiet'], ['escape' => 0]); if ($return['error_status']) { throw new \Exception('There are uncommitted changes in your git working copy.'); } } } }