Skip to content

Commit

Permalink
Merge pull request #3128 from wp-cli/1222-strict-args
Browse files Browse the repository at this point in the history
Introduce `WP_CLI_STRICT_ARGS_MODE` for dealing with arg ambiguity
  • Loading branch information
danielbachhuber committed Jul 8, 2016
2 parents e5e79a9 + 0ab8115 commit 42cf7fb
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 23 deletions.
46 changes: 46 additions & 0 deletions features/flags.feature
Expand Up @@ -212,3 +212,49 @@ Feature: Global flags
"""
<file>
"""

Scenario: Use `WP_CLI_STRICT_ARGS_MODE` to distinguish between global and local args
Given an empty directory
And a cmd.php file:
"""
<?php
/**
* @when before_wp_load
*
* [--url=<url>]
* : URL passed to the callback.
*/
$cmd_test = function( $args, $assoc_args ) {
$url = WP_CLI::get_runner()->config['url'] ? ' ' . WP_CLI::get_runner()->config['url'] : '';
WP_CLI::log( 'global:' . $url );
$url = isset( $assoc_args['url'] ) ? ' ' . $assoc_args['url'] : '';
WP_CLI::log( 'local:' . $url );
};
WP_CLI::add_command( 'cmd-test', $cmd_test );
"""
And a wp-cli.yml file:
"""
require:
- cmd.php
"""

When I run `wp cmd-test --url=foo.dev`
Then STDOUT should be:
"""
global: foo.dev
local:
"""

When I run `WP_CLI_STRICT_ARGS_MODE=1 wp cmd-test --url=foo.dev`
Then STDOUT should be:
"""
global:
local: foo.dev
"""

When I run `WP_CLI_STRICT_ARGS_MODE=1 wp --url=bar.dev cmd-test --url=foo.dev`
Then STDOUT should be:
"""
global: bar.dev
local: foo.dev
"""
76 changes: 54 additions & 22 deletions php/WP_CLI/Configurator.php
Expand Up @@ -84,8 +84,8 @@ function get_aliases() {
* @return array(array)
*/
public function parse_args( $arguments ) {
list( $positional_args, $mixed_args ) = self::extract_assoc( $arguments );
list( $assoc_args, $runtime_config ) = $this->unmix_assoc_args( $mixed_args );
list( $positional_args, $mixed_args, $global_assoc, $local_assoc ) = self::extract_assoc( $arguments );
list( $assoc_args, $runtime_config ) = $this->unmix_assoc_args( $mixed_args, $global_assoc, $local_assoc );
return array( $positional_args, $assoc_args, $runtime_config );
}

Expand All @@ -96,21 +96,35 @@ public function parse_args( $arguments ) {
* @return array(array)
*/
public static function extract_assoc( $arguments ) {
$positional_args = $assoc_args = array();
$positional_args = $assoc_args = $global_assoc = $local_assoc = array();

foreach ( $arguments as $arg ) {
$positional_arg = $assoc_arg = null;

if ( preg_match( '|^--no-([^=]+)$|', $arg, $matches ) ) {
$assoc_args[] = array( $matches[1], false );
$assoc_arg = array( $matches[1], false );
} elseif ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) {
$assoc_args[] = array( $matches[1], true );
$assoc_arg = array( $matches[1], true );
} elseif ( preg_match( '|^--([^=]+)=(.*)|s', $arg, $matches ) ) {
$assoc_args[] = array( $matches[1], $matches[2] );
$assoc_arg = array( $matches[1], $matches[2] );
} else {
$positional_args[] = $arg;
$positional = $arg;
}

if ( ! is_null( $assoc_arg ) ) {
$assoc_args[] = $assoc_arg;
if ( count( $positional_args ) ) {
$local_assoc[] = $assoc_arg;
} else {
$global_assoc[] = $assoc_arg;
}
} else if ( ! is_null( $positional ) ) {
$positional_args[] = $positional;
}

}

return array( $positional_args, $assoc_args );
return array( $positional_args, $assoc_args, $global_assoc, $local_assoc );
}

/**
Expand All @@ -119,32 +133,50 @@ public static function extract_assoc( $arguments ) {
* @param array $mixed_args
* @return array
*/
private function unmix_assoc_args( $mixed_args ) {
private function unmix_assoc_args( $mixed_args, $global_assoc = array(), $local_assoc = array() ) {
$assoc_args = $runtime_config = array();

foreach ( $mixed_args as $tmp ) {
list( $key, $value ) = $tmp;

if ( isset( $this->spec[ $key ] ) && $this->spec[ $key ]['runtime'] !== false ) {
$details = $this->spec[ $key ];

if ( isset( $details['deprecated'] ) ) {
fwrite( STDERR, "WP-CLI: The --{$key} global parameter is deprecated. {$details['deprecated']}\n" );
if ( getenv( 'WP_CLI_STRICT_ARGS_MODE' ) ) {
foreach( $global_assoc as $tmp ) {
list( $key, $value ) = $tmp;
if ( isset( $this->spec[ $key ] ) && $this->spec[ $key ]['runtime'] !== false ) {
$this->assoc_arg_to_runtime_config( $key, $value, $runtime_config );
}
}
foreach( $local_assoc as $tmp ) {
$assoc_args[ $tmp[0] ] = $tmp[1];
}
} else {
foreach ( $mixed_args as $tmp ) {
list( $key, $value ) = $tmp;

if ( $details['multiple'] ) {
$runtime_config[ $key ][] = $value;
if ( isset( $this->spec[ $key ] ) && $this->spec[ $key ]['runtime'] !== false ) {
$this->assoc_arg_to_runtime_config( $key, $value, $runtime_config );
} else {
$runtime_config[ $key ] = $value;
$assoc_args[ $key ] = $value;
}
} else {
$assoc_args[ $key ] = $value;
}
}

return array( $assoc_args, $runtime_config );
}

/**
* Handle turning an $assoc_arg into a runtime arg.
*/
private function assoc_arg_to_runtime_config( $key, $value, &$runtime_config ) {
$details = $this->spec[ $key ];
if ( isset( $details['deprecated'] ) ) {
fwrite( STDERR, "WP-CLI: The --{$key} global parameter is deprecated. {$details['deprecated']}\n" );
}

if ( $details['multiple'] ) {
$runtime_config[ $key ][] = $value;
} else {
$runtime_config[ $key ] = $value;
}
}

/**
* Load a YAML file of parameters into scope.
*
Expand Down
16 changes: 15 additions & 1 deletion tests/test-configurator.php
Expand Up @@ -36,6 +36,20 @@ function testExtractAssocNoValue() {

}

function testExtractAssocGlobalLocal() {
$args = Configurator::extract_assoc( array( '--url=foo.dev', '--path=wp', 'foo', '--bar=', '--baz=text', '--url=bar.dev' ) );

$this->assertCount( 1, $args[0] );
$this->assertCount( 5, $args[1] );
$this->assertCount( 2, $args[2] );
$this->assertCount( 3, $args[3] );

$this->assertEquals( 'url', $args[2][0][0] );
$this->assertEquals( 'foo.dev', $args[2][0][1] );
$this->assertEquals( 'url', $args[3][2][0] );
$this->assertEquals( 'bar.dev', $args[3][2][1] );
}

function testExtractAssocDoubleDashInValue() {
$args = Configurator::extract_assoc( array( '--test=text--text' ) );

Expand All @@ -48,4 +62,4 @@ function testExtractAssocDoubleDashInValue() {
}


}
}

0 comments on commit 42cf7fb

Please sign in to comment.