Permalink
Browse files

Pass variable args to functions that declare a parameter of type 'arr…

…ay' (#2606)

* Pass variable args to functions that declare a parameter of type 'array'.

* Remove strict option handling; instead, use '--' to separate passthru-args from options interpreted by Drush.

* Fix drush_invoke_process calls to core-rsync. Remove documentation on strict option handling.

* Tag additional options in site install 'array'.

* Add Usage examples
  • Loading branch information...
1 parent 11c9bed commit d4d08b0b610e8cc067ee24c0827d06e02a0aab5a @greg-1-anderson greg-1-anderson committed with weitzman Feb 12, 2017
@@ -79,10 +79,6 @@ function drush_print_help($command) {
$help = array($command['description']);
}
- if ($command['strict-option-handling']) {
- $command['topics'][] = 'docs-strict-options';
- }
-
// Give commandfiles an opportunity to add examples and options to the command.
drush_bootstrap_max(DRUSH_BOOTSTRAP_DRUPAL_SITE);
drush_engine_add_help_topics($command);
@@ -1,15 +0,0 @@
-Strict Option Handling
-======================
-
-Some Drush commands use strict option handling; these commands require that all Drush global option appear on the command line before the Drush command name.
-
-One example of this is the core-rsync command:
-
- drush --simulate core-rsync -v @site1 @site2
-
-The --simulate option is a Drush global option that causes Drush to print out what it would do if the command is executed, without actually taking any action. Commands such as core-rsync that use strict option handling require that --simulate, if used, must appear before the command name. Most Drush commands allow the --simulate to be placed anywhere, such as at the end of the command line.
-
-The -v option above is an rsync option. In this usage, it will cause the rsync command to run in verbose mode. It will not cause Drush to run in verbose mode, though, because it appears after the core-rsync command name. Most Drush commands would be run in verbose mode if a -v option appeared in the same location.
-
-The advantage of strict option handling is that it allows Drush to pass options and arguments through to a shell command. Some shell commands, such as rsync and ssh, either have options that cannot be represented in Drush. For example, rsync allows the --exclude option to appear multiple times on the command line, but Drush only allows one instance of an option at a time for most Drush commands. Strict option handling overcomes this limitation, plus possible conflict between Drush options and shell command options with the same name, at the cost of greater restriction on where global options can be placed.
-
@@ -122,7 +122,7 @@
*
* $ drush site-alias @self
*
- * TIP: If you would like to have drush include a 'databases' record
+ * TIP: If you would like to have Drush include a 'databases' record
* in the output, include the options --with-db and --show-passwords:
*
* $ drush site-alias @self --with-db --show-passwords
@@ -260,7 +260,7 @@
* // the inner ''.
* 'filter' => "'exclude *.sql'",
*
- * // if you need multple filter options, see rsync merge-file options
+ * // if you need multiple filter options, see rsync merge-file options
* 'filter' => "'merge /etc/rsync/default.rules'",
* ),
* ),
@@ -203,14 +203,8 @@ function annotationcommand_adapter_process_command() {
$commandprocessor = annotationcommand_adapter_get_processor();
$command = drush_get_command();
annotationcommand_adapter_add_hook_options($command);
- $args = [];
- foreach ($command['consolidation-arg-defaults'] as $key => $default) {
- $value = array_shift($userArgs);
- if (!isset($value)) {
- $value = $default;
- }
- $args[$key] = $value;
- }
+
+ $args = annotationcommand_adapter_process_args($userArgs, $command['consolidation-arg-defaults']);
// TODO: Need to determine if $input is interactive, and ensure that $input->isInteractive() returns the correct result.
$input = new DrushInputAdapter($args, annotationcommand_adapter_get_options($command), $command['command']);
@@ -244,6 +238,22 @@ function annotationcommand_adapter_process_command() {
return $result;
}
+function annotationcommand_adapter_process_args($userArgs, $defaults) {
+ $args = [];
+ foreach ($defaults as $key => $default) {
+ if (is_array($default)) {
+ $args[$key] = $userArgs;
+ return $args;
+ }
+ $value = array_shift($userArgs);
+ if (!isset($value)) {
+ $value = $default;
+ }
+ $args[$key] = $value;
+ }
+ return $args;
+}
+
/**
* Internal function called by annotationcommand_adapter_commands, which
* is called by drush_get_commands().
View
@@ -828,6 +828,7 @@ function drush_redispatch_get_options() {
* Parse console arguments.
*/
function drush_parse_args() {
+ $sawDashDash = false;
$args = drush_get_context('argv');
$command_args = NULL;
$global_options = array();
@@ -855,8 +856,11 @@ function drush_parse_args() {
if (is_array($command_args)) {
$command_args[] = $opt;
}
+ if ($opt == '--') {
+ $sawDashDash = true;
+ }
// Is the arg an option (starting with '-')?
- if (!empty($opt) && $opt{0} == "-" && strlen($opt) != 1) {
+ elseif (!$sawDashDash && !empty($opt) && $opt{0} == "-" && strlen($opt) != 1) {
// Do we have multiple options behind one '-'?
if (strlen($opt) > 2 && $opt{1} != "-") {
// Each char becomes a key of its own.
@@ -1254,7 +1258,6 @@ function drush_command_defaults($key, $commandfile, $path) {
'drush dependencies' => array(),
'handle-remote-commands' => FALSE,
'remote-tty' => FALSE,
- 'strict-option-handling' => FALSE,
'tilde-expansion' => TRUE,
'bootstrap_errors' => array(),
'topics' => array(),
@@ -1353,18 +1356,6 @@ function _drush_command_translate($source) {
* - remote-tty: set to TRUE if Drush should force ssh to allocate a pseudo-tty
* when this command is being called remotely. Important for interactive commands.
* Remote commands that allocate a psedo-tty always print "Connection closed..." when done.
- * - strict-option-handling: set to TRUE if drush should strictly separate local command
- * cli options from the global options. Usually, drush allows global cli options and
- * command cli options to be interspersed freely on the commandline. For commands where
- * this flag is set, options are separated, with global options comming before the
- * command names, and command options coming after, like so:
- * drush --global-options command --command-options
- * In this mode, the command options are no longer available via drush_get_option();
- * instead, they can be retrieved via:
- * $args = drush_get_original_cli_args_and_options();
- * $args = drush_get_context('DRUSH_COMMAND_ARGS', array());
- * In this case, $args will contain the command args and options literally, exactly as they
- * were entered on the command line, and in the same order as they appeared.
* - 'outputformat': declares the data format to be used to render the
* command result. In addition to the output format engine options
* listed below, each output format type can take additional metadata
@@ -1747,23 +1738,6 @@ function drush_command_set_command_specific($command_default_options, $command =
if (!empty($options_were_set)) {
_drush_preflight_global_options();
}
- // If the command uses strict option handling, back out any global
- // options that were set.
- if ($command['strict-option-handling']) {
- $global_options = drush_get_global_options();
- foreach ($options_were_set as $key) {
- if (array_key_exists($key, $global_options)) {
- if (!array_key_exists('context', $global_options[$key])) {
- $strict_options_warning =& drush_get_context('DRUSH_STRICT_OPTIONS_WARNING', array());
- if (!array_key_exists($key, $strict_options_warning)) {
- drush_log(dt("Global option --!option not supported in command-specific options for command !command due to a limitation in strict option handling.", array('!option' => $key, '!command' => $command['command'])), LogLevel::WARNING);
- $strict_options_warning[$key] = TRUE;
- }
- }
- drush_unset_option($key, 'specific');
- }
- }
- }
}
}
View
@@ -1170,16 +1170,6 @@ function drush_do_command_redispatch($command, $args = array(), $remote_host = N
$command_options = $aditional_options + $command_options;
if (is_array($command)) {
$command_name = $command['command'];
- // If we are executing a remote command that uses strict option handling,
- // then mark all of the options in the alias context as global, so that they
- // will appear before the command name.
- if (!empty($command['strict-option-handling'])) {
- foreach(drush_get_context('alias') as $alias_key => $alias_value) {
- if (array_key_exists($alias_key, $command_options) && !array_key_exists($alias_key, $command['options'])) {
- $additional_global_options[$alias_key] = $alias_value;
- }
- }
- }
}
else {
$command_name = $command;
@@ -809,38 +809,6 @@ function drush_preflight_command_dispatch() {
$command = drush_parse_command();
drush_command_default_options($command);
- // If the command sets the 'strict-option-handling' flag, then we will remove
- // any cli options that appear after the command name from the 'cli' context.
- // The cli options that appear before the command name are stored in the
- // 'DRUSH_GLOBAL_CLI_OPTIONS' context, so we will just overwrite the cli context
- // with this, after doing the neccessary fixup from short-form to long-form options.
- // After we do that, we put back any local drush options identified by $command['options'].
- if (is_array($command) && !empty($command['strict-option-handling'])) {
- $cli_options = drush_get_context('DRUSH_GLOBAL_CLI_OPTIONS', array());
- // Now we are going to sort out any options that exist in $command['options'];
- // we will remove these from DRUSH_COMMAND_ARGS and put them back into the
- // cli options.
- $cli_context = drush_get_context('cli');
- $remove_from_command_args = array();
- foreach ($command['options'] as $option => $info) {
- if (array_key_exists($option, $cli_context)) {
- $cli_options[$option] = $cli_context[$option];
- $remove_from_command_args[$option] = $option;
- }
- }
- if (!empty($remove_from_command_args)) {
- $drush_command_args = array();
- foreach (drush_get_context('DRUSH_COMMAND_ARGS') as $arg) {
- if (!_drush_should_remove_command_arg($arg, $remove_from_command_args)) {
- $drush_command_args[] = $arg;
- }
- }
- drush_set_context('DRUSH_COMMAND_ARGS', $drush_command_args);
- }
- drush_expand_short_form_options($cli_options);
- drush_set_context('cli', $cli_options);
- _drush_preflight_global_options();
- }
$args = drush_get_arguments();
$command_name = array_shift($args);
$root = \Drush::bootstrapManager()->getRoot();
@@ -243,7 +243,7 @@ function pull($source, $destination, $options = ['safe' => FALSE, 'label' => 'sy
// 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("$source:$export_path", "$destination:%config-$label"), $rsync_options);
+ $return = drush_invoke_process($runner, 'core-rsync', array("$source:$export_path", "$destination:%config-$label", '--', $rsync_options));
if ($return['error_status']) {
throw new \Exception(dt('Config-pull rsync failed.'));
}
@@ -262,25 +262,18 @@ public function version($options = ['format' => 'table']) {
*
* Used by shell aliases that start with !.
*
- * @todo Handle variable number of arguments.
- *
* @command core-execute
- * @param $command The shell command to be executed.
+ * @param $args The shell command to be executed.
* @option escape Escape parameters before executing them with the shell. Default is escape; use --no-escape to disable.
* @optionset_proc_build
- * @allow-additional-options
* @handle-remote-commands
- * @strict-option-handling
- * @usage drush core-execute git pull origin rebase
+ * @usage drush core-execute git pull origin rebase -- --no-ff
* Retrieve latest code from git
* @aliases exec,execute
* @topics docs-aliases
- * @bootstrap DRUSH_BOOTSTRAP_NONE
*/
- public function execute($options = ['escape' => TRUE]) {
+ public function execute(array $args, array $options = ['escape' => TRUE]) {
$result = TRUE;
- // Get all of the args and options that appear after the command name.
- $args = drush_get_original_cli_args_and_options();
if ($options['escape']) {
for ($x = 0; $x < count($args); $x++) {
// escape all args except for command separators.
@@ -343,4 +336,4 @@ protected function executeCmd($site, $cmd) {
}
-}
+}
@@ -231,15 +231,4 @@ public function syncHttp() {
public function policy() {
self::printFile(DRUSH_BASE_PATH. '/examples/policy.drush.inc');
}
-
- /**
- * Strict option handling, and how commands that use it differ from regular Drush commands.
- *
- * @command docs-strict-options
- * @hidden
- * @topic
- */
- public function strictOptions() {
- self::printFile(DRUSH_BASE_PATH. '/docs/strict-options.md');
- }
-}
+}
@@ -24,20 +24,19 @@ class RsyncCommands extends DrushCommands {
* @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.
- * @strict-option-handling
* @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
+ * @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"
- * Customize how rsync connects with remote host via SSH.
+ * @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
* @topics docs-aliases
* @complete \Drush\Commands\CompletionCommands::completeSiteAliases
*/
- public function rsync($source, $destination, $extra = NULL, $options = ['exclude-paths' => NULL, 'include-paths' => NULL, 'mode' => 'akz']) {
+ public function rsync($source, $destination, array $extra, $options = ['exclude-paths' => NULL, 'include-paths' => NULL, 'mode' => 'akz']) {
// Prompt for confirmation. This is destructive.
if (!drush_get_context('DRUSH_SIMULATE')) {
drush_print(dt("You will delete files in !target and replace with data from !source", array('!source' => $this->source_evaluated_path, '!target' => $this->destination_evaluated_path)));
@@ -47,9 +46,12 @@ public function rsync($source, $destination, $extra = NULL, $options = ['exclude
}
$rsync_options = $this->rsyncOptions($options);
+ $parameters = array_merge([$rsync_options], $extra);
+ $parameters[] = $this->source_evaluated_path;
+ $parameters[] = $this->destination_evaluated_path;
$ssh_options = $options['ssh-options'];
- $exec = "rsync -e 'ssh $ssh_options'". ' '. implode(' ', array_filter([$rsync_options, $extra, $this->source_evaluated_path, $this->destination_evaluated_path]));
+ $exec = "rsync -e 'ssh $ssh_options'". ' '. implode(' ', array_filter($parameters));
$exec_result = drush_op_system($exec);
if ($exec_result == 0) {
@@ -42,9 +42,8 @@ class SiteInstallCommands extends DrushCommands {
* @bootstrap DRUSH_BOOTSTRAP_DRUPAL_ROOT
* @aliases si
*
- * @todo cast $additional to an array to get variable argument handling
*/
- public function install($profile, $additional = NULL, $options = ['db-url' => NULL, 'db-prefix' => NULL, 'db-su' => NULL, 'db-su-pw' => NULL, 'account-name' => 'admin', 'account-mail' => 'admin@example.com', 'account-pass' => NULL, 'locale' => 'en', 'site-name' => 'Drush Site-Install', 'site-pass' => NULL, 'sites-subdir' => NULL, 'config-dir' => NULL]) {
+ public function install($profile, array $additional, $options = ['db-url' => NULL, 'db-prefix' => NULL, 'db-su' => NULL, 'db-su-pw' => NULL, 'account-name' => 'admin', 'account-mail' => 'admin@example.com', 'account-pass' => NULL, 'locale' => 'en', 'site-name' => 'Drush Site-Install', 'site-pass' => NULL, 'sites-subdir' => NULL, 'config-dir' => NULL]) {
$form_options = [];
foreach ((array)$additional as $arg) {
list($key, $value) = explode('=', $arg, 2);
@@ -271,4 +270,4 @@ public function pre(CommandData $commandData) {
throw new \Exception(dt('Failed to create database: @error', array('@error' => implode(drush_shell_exec_output()))));
}
}
-}
+}
@@ -10,11 +10,9 @@ class SshCommands extends DrushCommands {
* Connect to a Drupal site's server via SSH for an interactive session or to run a shell command.
*
* @command site-ssh
- * @param string $bash Bash to execute on target. Optional, except when site-alias is a list.
* @option cd Directory to change to if Drupal root is not desired (the default). Value should be a full path, or --no-cd for the ssh default (usually the remote user's home directory).
* @optionset_proc_build
* @handle-remote-commands
- * @strict-option-handling
* @usage drush @mysite ssh
* Open an interactive shell on @mysite's server.
* @usage drush @prod ssh ls /tmp
@@ -25,9 +23,7 @@ class SshCommands extends DrushCommands {
* @bootstrap DRUSH_BOOTSTRAP_NONE
* @topics docs-aliases
*/
- public function ssh($bash = '', $options = ['cd' => TRUE]) {
- // Get all of the args and options that appear after the command name.
- $args = drush_get_original_cli_args_and_options();
+ public function ssh(array $args, $options = ['cd' => TRUE]) {
// n.b. we do not escape the first (0th) arg to allow `drush ssh 'ls /path'`
// to work in addition to the preferred form of `drush ssh ls /path`.
// Supporting the legacy form means that we cannot give the full path to an
@@ -57,7 +53,7 @@ public function ssh($bash = '', $options = ['cd' => TRUE]) {
if (!drush_sitealias_is_remote_site($alias)) {
// Local sites run their bash without SSH.
- $return = drush_invoke_process('@self', 'core-execute', array($bash), array('escape' => FALSE));
+ $return = drush_invoke_process('@self', 'core-execute', array($command), array('escape' => FALSE));
return $return['object'];
}
@@ -74,4 +70,4 @@ public function ssh($bash = '', $options = ['cd' => TRUE]) {
throw new \Exception(dt('An error @code occurred while running the command `@command`', array('@command' => $cmd, '@code' => $status)));
}
}
-}
+}
@@ -113,7 +113,7 @@ public function sqlsync($source, $destination, $options = ['no-dump' => NULL, 'n
$runner = drush_get_runner($source_record, $destination_record, $options['runner']);
// 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("$source:$source_dump_path", "$destination:$destination_dump_path"), $rsync_options);
+ $return = drush_invoke_process($runner, 'core-rsync', array("$source:$source_dump_path", "$destination:$destination_dump_path", '--', $rsync_options));
$this->logger()->notice(dt('Copying dump file from Source to Destination.'));
if ($return['error_status']) {
throw new \Exception(dt('core-rsync failed.'));
Oops, something went wrong.

0 comments on commit d4d08b0

Please sign in to comment.