2 namespace Drush\Commands\core;
4 use Consolidation\OutputFormatters\StructuredData\PropertyList;
5 use Drush\Commands\DrushCommands;
7 use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
8 use Drush\SiteAlias\SiteAliasManagerAwareInterface;
9 use Drush\SiteAlias\SiteAliasManagerAwareTrait;
11 class CoreCommands extends DrushCommands implements SiteAliasManagerAwareInterface
14 use SiteAliasManagerAwareTrait;
19 * @command core:global-options
22 * @table-style default
25 * description: Description
26 * @default-fields name,description
27 * @aliases core-global-options
29 * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields
31 public function globalOptions($options = ['format' => 'table'])
33 $application = Drush::getApplication();
34 $def = $application->getDefinition();
35 foreach ($def->getOptions() as $key => $value) {
37 if ($value->getShortcut()) {
38 $name = '-' . $value->getShortcut() . ', ' . $name;
42 'description' => $value->getDescription(),
46 // Also document the keys that are recognized by PreflightArgs. It would be possible to redundantly declare
47 // those as global options. We don't do that for now, to avoid confusion.
48 $ancient = drush_get_global_options();
49 foreach (['config', 'alias-path', 'include', 'local', 'backend', 'strict', 'ssh-options'] as $name) {
51 'name' => '--' . $name,
52 'description' => $ancient[$name]['description'],
55 usort($rows, function ($a, $b) {
56 return strnatcmp($a['name'], $b['name']);
58 return new RowsOfFields($rows);
65 * @table-style compact
68 * drush-version: Drush version
70 * @return \Consolidation\OutputFormatters\StructuredData\PropertyList
73 public function version($options = ['format' => 'table'])
75 return new PropertyList(['drush-version' => Drush::getVersion()]);
79 * Execute a shell command. Usually used with a site alias.
81 * Used by shell aliases that start with !.
83 * @command core:execute
84 * @param $args The shell command to be executed.
85 * @option escape Escape parameters before executing them with the shell. Default is escape; use --no-escape to disable.
86 * @optionset_proc_build
87 * @handle-remote-commands
88 * @usage drush core:execute git pull origin rebase -- --no-ff
89 * Retrieve latest code from git
90 * @aliases exec,execute,core-execute
91 * @topics docs:aliases
93 public function execute(array $args, array $options = ['escape' => true])
96 if ($options['escape']) {
97 for ($x = 0; $x < count($args); $x++) {
98 // escape all args except for command separators.
99 if (!in_array($args[$x], ['&&', '||', ';'])) {
100 $args[$x] = drush_escapeshellarg($args[$x]);
104 $cmd = implode(' ', $args);
105 // If we selected a Drupal site, then cwd to the site root prior to exec
107 if ($selected_root = Drush::bootstrapManager()->getRoot()) {
108 if (is_dir($selected_root)) {
110 drush_op('chdir', $selected_root);
114 $aliasRecord = $this->siteAliasManager()->getSelf();
116 $result = $this->executeCmd($aliasRecord, $cmd);
118 // Must be a local command.
119 $result = (drush_shell_proc_open($cmd) == 0);
122 // Restore the cwd if we changed it
124 drush_op('chdir', $cwd);
128 throw new \Exception(dt("Command !command failed.", ['!command' => $cmd]));
134 * Helper function for drush_core_execute: run one shell command
136 protected function executeCmd($site, $cmd)
138 if ($site->isRemote()) {
139 // Remote, so execute an ssh command with a bash fragment at the end.
140 $exec = drush_shell_proc_build($site, $cmd, true);
141 return (drush_shell_proc_open($exec) == 0);
142 } elseif ($site->hasRoot() && is_dir($site->root())) {
143 return (drush_shell_proc_open('cd ' . drush_escapeshellarg($site->root()) . ' && ' . $cmd) == 0);
145 return (drush_shell_proc_open($cmd) == 0);