b94e02bd944a79dbe494f3656fb6883167877a42
[yaffs-website] / vendor / drush / drush / src / Commands / config / ConfigPullCommands.php
1 <?php
2 namespace Drush\Commands\config;
3
4 use Consolidation\AnnotatedCommand\CommandData;
5 use Drush\Commands\DrushCommands;
6 use Drush\Drush;
7 use Drush\SiteAlias\HostPath;
8 use Drush\SiteAlias\SiteAliasManagerAwareInterface;
9 use Drush\SiteAlias\SiteAliasManagerAwareTrait;
10
11 class ConfigPullCommands extends DrushCommands implements SiteAliasManagerAwareInterface
12 {
13     use SiteAliasManagerAwareTrait;
14
15     /**
16      * Export and transfer config from one environment to another.
17      *
18      * @command config:pull
19      * @param string $source A site-alias or the name of a subdirectory within /sites whose config you want to copy from.
20      * @param string $destination A site-alias or the name of a subdirectory within /sites whose config you want to replace.
21      * @option safe Validate that there are no git uncommitted changes before proceeding
22      * @option label A config directory label (i.e. a key in \$config_directories array in settings.php). Defaults to 'sync'
23      * @option runner Where to run the rsync command; defaults to the local site. Can also be 'source' or 'destination'
24      * @usage drush config:pull @prod @stage
25      *   Export config from @prod and transfer to @stage.
26      * @usage drush config:pull @prod @self --label=vcs
27      *   Export config from @prod and transfer to the 'vcs' config directory of current site.
28      * @usage drush config:pull @prod @self:../config/sync
29      *   Export config to a custom directory. Relative paths are calculated from Drupal root.
30      * @aliases cpull,config-pull
31      * @topics docs:aliases,docs:config-exporting
32      *
33      */
34     public function pull($source, $destination, $options = ['safe' => false, 'label' => 'sync', 'runner' => null])
35     {
36         $global_options = Drush::redispatchOptions()  + ['strict' => 0];
37
38         // @todo If either call is made interactive, we don't get an $return['object'] back.
39         $backend_options = ['interactive' => false];
40         if (Drush::simulate()) {
41             $backend_options['backend-simulate'] = true;
42         }
43
44         $export_options = [
45             // Use the standard backup directory on Destination.
46             'destination' => true,
47             'yes' => null,
48         ];
49         $this->logger()->notice(dt('Starting to export configuration on Target.'));
50         $return = drush_invoke_process($source, 'config-export', [], $global_options + $export_options, $backend_options);
51         if ($return['error_status']) {
52               throw new \Exception(dt('Config-export failed.'));
53         } else {
54               // Trailing slash assures that we transfer files and not the containing dir.
55               $export_path = $return['object'] . '/';
56         }
57
58         $rsync_options = [
59             '--remove-source-files',
60             '--delete',
61             '--exclude=.htaccess',
62         ];
63         if (strpos($destination, ':') === false) {
64             $destination .= ':%config-' . $options['label'];
65         }
66         $destinationHostPath = HostPath::create($this->siteAliasManager(), $destination);
67
68         if (!$runner = $options['runner']) {
69             $sourceRecord = $this->siteAliasManager()->get($source);
70             $destinationRecord = $destinationHostPath->getAliasRecord();
71             $runner = $sourceRecord->isRemote() && $destinationRecord->isRemote() ? $destinationRecord : '@self';
72         }
73         $this->logger()
74           ->notice(dt('Starting to rsync configuration files from !source to !dest.', [
75           '!source' => $source,
76           '!dest' => $destinationHostPath->getOriginal(),
77           ]));
78         // This comment applies similarly to sql-sync's use of core-rsync.
79         // 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.
80         // Alternatively, add options like ssh.options to a site alias (usually on the machine that initiates the sql-sync).
81         $return = drush_invoke_process($runner, 'core-rsync', array_merge([
82             "$source:$export_path",
83             $destinationHostPath->getOriginal(),
84             '--'
85         ], $rsync_options), ['yes' => true], $backend_options);
86         if ($return['error_status']) {
87             throw new \Exception(dt('Config-pull rsync failed.'));
88         }
89
90         drush_backend_set_result($return['object']);
91     }
92
93     /**
94      * @hook validate config-pull
95      */
96     public function validateConfigPull(CommandData $commandData)
97     {
98         if ($commandData->input()->getOption('safe')) {
99             $return = drush_invoke_process($commandData->input()
100             ->getArgument('destination'), 'core-execute', ['git diff --quiet'], ['escape' => 0]);
101             if ($return['error_status']) {
102                   throw new \Exception('There are uncommitted changes in your git working copy.');
103             }
104         }
105     }
106 }