diff --git a/src/Commands/config/ConfigPullCommands.php b/src/Commands/config/ConfigPullCommands.php index 58f7062fc1..b94e02bd94 100644 --- a/src/Commands/config/ConfigPullCommands.php +++ b/src/Commands/config/ConfigPullCommands.php @@ -4,6 +4,7 @@ use Consolidation\AnnotatedCommand\CommandData; use Drush\Commands\DrushCommands; use Drush\Drush; +use Drush\SiteAlias\HostPath; use Drush\SiteAlias\SiteAliasManagerAwareInterface; use Drush\SiteAlias\SiteAliasManagerAwareTrait; @@ -24,6 +25,8 @@ class ConfigPullCommands extends DrushCommands implements SiteAliasManagerAwareI * Export config from @prod and transfer to @stage. * @usage drush config:pull @prod @self --label=vcs * Export config from @prod and transfer to the 'vcs' config directory of current site. + * @usage drush config:pull @prod @self:../config/sync + * Export config to a custom directory. Relative paths are calculated from Drupal root. * @aliases cpull,config-pull * @topics docs:aliases,docs:config-exporting * @@ -57,23 +60,27 @@ public function pull($source, $destination, $options = ['safe' => false, 'label' '--delete', '--exclude=.htaccess', ]; - $label = $options['label']; + if (strpos($destination, ':') === false) { + $destination .= ':%config-' . $options['label']; + } + $destinationHostPath = HostPath::create($this->siteAliasManager(), $destination); + if (!$runner = $options['runner']) { $sourceRecord = $this->siteAliasManager()->get($source); - $destinationRecord = $this->siteAliasManager()->get($destination); - $runner = $sourceRecord->isRemote() && $destinationRecord->isRemote() ? $destination : '@self'; + $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' => $destination + '!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", - "$destination:%config-$label", + $destinationHostPath->getOriginal(), '--' ], $rsync_options), ['yes' => true], $backend_options); if ($return['error_status']) { diff --git a/src/SiteAlias/HostPath.php b/src/SiteAlias/HostPath.php index f6d88662cb..48831e7279 100644 --- a/src/SiteAlias/HostPath.php +++ b/src/SiteAlias/HostPath.php @@ -125,7 +125,17 @@ public function getOriginal() } /** - * Return just the path portion of the host path + * Return just the path portion, without considering the alias root. + * + * @return string + */ + public function getOriginalPath() + { + return $this->path; + } + + /** + * Return the original path * * @return string */ diff --git a/tests/ConfigPullTest.php b/tests/ConfigPullTest.php index e6db01853b..c068f18da6 100644 --- a/tests/ConfigPullTest.php +++ b/tests/ConfigPullTest.php @@ -1,7 +1,8 @@ drush('config-set', ['system.site', 'uuid', $uuid], ['yes' => null], $destination); $this->drush('config-set', ['system.site', 'name', 'testConfigPull'], ['yes' => null], $source); - $this->drush('config-pull', [$source, $destination], []); + $this->drush('config-pull', [$source, $destination]); $this->drush('config-import', [], ['yes' => null], $destination); $this->drush('config-get', ['system.site', 'name'], [], $source); $this->assertEquals("'system.site:name': testConfigPull", $this->getOutput(), 'Config was successfully pulled.'); + + // Test that custom target dir works + $target = Path::join($this->getSandbox(), __CLASS__); + $this->mkdir($target); + $this->drush('config-pull', [$source, "$destination:$target"]); + $this->assertFileExists(Path::join($target, 'system.site.yml')); } }