Skip to content

Commit

Permalink
Adding support for positional arguments.
Browse files Browse the repository at this point in the history
Adding tests and support for positional arguments. Renaming description
key to help as its shorter.
  • Loading branch information
markstory committed Oct 14, 2010
1 parent 6f1dae2 commit 3e402e2
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 5 deletions.
66 changes: 62 additions & 4 deletions cake/console/console_option_parser.php
Expand Up @@ -63,6 +63,12 @@ class ConsoleOptionParser {
*
* ### Positional arguments
*
* If no positional arguments are defined, all of them will be parsed. If you define positional
* arguments any arguments greater than those defined will cause exceptions. Additionally you can
* declare arguments as optional, by setting the required param to false.
*
* `$parser->addArgument('model', array('required' => false));`
*
* ### Providing Help text
*
* By providing help text for your positional arguments and named arguments, the ConsoleOptionParser
Expand Down Expand Up @@ -109,7 +115,7 @@ public function epilog($text = null) {
* ### Params
*
* - `short` - The single letter variant for this option, leave undefined for none.
* - `description` - Description for this option. Used when generating help for the option.
* - `help` - Help text for this option. Used when generating help for the option.
* - `default` - The default value for this option. If not defined the default will be true.
*
* @param string $name The long name you want to the value to be parsed out as when options are parsed.
Expand All @@ -120,7 +126,7 @@ public function addOption($name, $params = array()) {
$defaults = array(
'name' => $name,
'short' => null,
'description' => '',
'help' => '',
'default' => true
);
$options = array_merge($defaults, $params);
Expand All @@ -134,17 +140,46 @@ public function addOption($name, $params = array()) {
/**
* Add a positional argument to the option parser.
*
* @return void
* ### Params
*
* - `help` The help text to display for this argument.
* - `required` Whether this parameter is required.
* - `index` The index for the arg, if left undefined the argument will be put
* onto the end of the arguments. If you define the same index twice the first
* option will be overwritten.
*
* @param string $name The name of the argument.
* @param array $params Parameters for the argument, see above.
* @return $this.
*/
public function addArgument($name, $params = array()) {

$index = count($this->_args);
$defaults = array(
'name' => $name,
'help' => '',
'index' => $index,
'required' => false
);
$options = array_merge($defaults, $params);
$this->_args[$options['index']] = $options;
return $this;
}

/**
* Gets the arguments defined in the parser.
*
* @return array Array of argument descriptions
*/
public function arguments() {
return $this->_args;
}

/**
* Parse the argv array into a set of params and args.
*
* @param array $argv Array of args (argv) to parse
* @return Array array($params, $args)
* @throws InvalidArgumentException When an invalid parameter is encountered.
*/
public function parse($argv) {
$params = $args = array();
Expand All @@ -154,6 +189,8 @@ public function parse($argv) {
$params = $this->_parseLongOption($token, $params);
} elseif (substr($token, 0, 1) == '-') {
$params = $this->_parseShortOption($token, $params);
} else {
$args = $this->_parseArg($token, $args);
}
}
return array($params, $args);
Expand Down Expand Up @@ -217,6 +254,27 @@ protected function _parseOptionName($name, $params) {
return $params;
}

/**
* Checks that the argument doesn't exceed the declared arguments.
*
* @param string $argument The argument to append
* @param array $args The array of parsed args to append to.
* @return array Args
*/
protected function _parseArg($argument, $args) {
if (empty($this->_args)) {
array_push($args, $argument);
return $args;
}
$position = 0;
$next = count($args);
if (!isset($this->_args[$next])) {
throw new InvalidArgumentException(__('Too many arguments.'));
}
array_push($args, $argument);
return $args;
}

/**
* Find the next token in the argv set.
*
Expand Down
44 changes: 43 additions & 1 deletion cake/tests/cases/console/console_option_parser.test.php
Expand Up @@ -129,7 +129,7 @@ function testAddOptionMultipleShort() {
$result = $parser->parse(array('-o', '-t', '-f'));
$expected = array('file' => true, 'test' => true, 'output' => true);
$this->assertEquals($expected, $result[0], 'Short parameter did not parse out');

$result = $parser->parse(array('-otf'));
$this->assertEquals($expected, $result[0], 'Short parameter did not parse out');
}
Expand All @@ -149,4 +149,46 @@ function testMultipleOptions() {
$expected = array('test' => 'value', 'table' => true, 'connection' => 'postgres');
$this->assertEquals($expected, $result[0], 'multiple options did not parse');
}

/**
* test positional argument parsing.
*
* @return void
*/
function testPositionalArgument() {
$parser = new ConsoleOptionParser();
$result = $parser->addArgument('name', array('help' => 'An argument'));
$this->assertEquals($parser, $result, 'Should returnn this');
}

/**
* test overwriting positional arguments.
*
* @return void
*/
function testPositionalArgOverwrite() {
$parser = new ConsoleOptionParser();
$parser->addArgument('name', array('help' => 'An argument'))
->addArgument('other', array('index' => 0));

$result = $parser->arguments();
$this->assertEquals(1, count($result), 'Overwrite did not occur');
}

/**
* test parsing arguments.
*
* @expectedException InvalidArgumentException
* @return void
*/
function testParseArgument() {
$parser = new ConsoleOptionParser();
$parser->addArgument('name', array('help' => 'An argument'))
->addArgument('other');

$expected = array('one', 'two');
$result = $parser->parse($expected);
$this->assertEquals($expected, $result[1], 'Arguments are not as expected');
$result = $parser->parse(array('one', 'two', 'three'));
}
}

0 comments on commit 3e402e2

Please sign in to comment.