From 7b1b835bc161ae819fa76ddc418ab681a94c41a8 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 7 Oct 2010 22:44:02 -0400 Subject: [PATCH] Adding very basic implementation for parsing long and short options. --- cake/console/console_option_parser.php | 75 +++++++++++++++++-- .../console/console_option_parser.test.php | 28 +++++++ 2 files changed, 98 insertions(+), 5 deletions(-) diff --git a/cake/console/console_option_parser.php b/cake/console/console_option_parser.php index bdcdf32b3af..d312607c83e 100644 --- a/cake/console/console_option_parser.php +++ b/cake/console/console_option_parser.php @@ -98,8 +98,8 @@ public function epilog($text = null) { * when this option is not present. * - `description` - Description for this option. * - `type` - Require a certain type. Available types are `int` and `string`. If the options - * value is the wrong type an exception will be raised. Leave undefined to accept anything. - * - `default` - The default value for this option. If not defined the default will be null. + * value is the wrong type an exception will be raised. Leave undefined to accept anything. + * - `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. * @param array $params An array of parameters that define the behavior of the option @@ -107,13 +107,18 @@ public function epilog($text = null) { */ public function addOption($name, $params = array()) { $defaults = array( + 'name' => $name, 'shortcut' => null, 'required' => false, 'description' => '', 'type' => null, - 'default' => null + 'default' => true ); - $this->_options[$name] = array_merge($defaults, $params); + $options = array_merge($defaults, $params); + $this->_options[$name] = $options; + if (!empty($options['shortcut'])) { + $this->_options[$options['shortcut']] = $options; + } return $this; } @@ -125,7 +130,67 @@ public function addOption($name, $params = array()) { */ public function parse($argv) { $params = $args = array(); - + $this->_tokens = $argv; + while ($token = array_shift($this->_tokens)) { + if (substr($token, 0, 2) == '--') { + $params = $this->_parseLongOption($token, $params); + } elseif (substr($token, 0, 1) == '-') { + $params = $this->_parseShortOption($token, $params); + } + } return array($params, $args); } + +/** + * Parse the value for a long option out of $this->_tokens + * + * @param string $option The option to parse. + * @param array $params The params to append the parsed value into + * @return array Params with $option added in. + */ + protected function _parseLongOption($option, $params) { + $name = substr($option, 2); + return $this->_parseOptionName($name, $params); + } + +/** + * Parse the value for a short option out of $this->_tokens + * + * @param string $option The option to parse. + * @param array $params The params to append the parsed value into + * @return array Params with $option added in. + */ + protected function _parseShortOption($option, $params) { + $key = substr($option, 1); + $name = $this->_options[$key]['name']; + return $this->_parseOptionName($name, $params); + } + +/** + * Parse an option by its name index. + * + * @param string $option The option to parse. + * @param array $params The params to append the parsed value into + * @return array Params with $option added in. + */ + protected function _parseOptionName($name, $params) { + $definition = $this->_options[$name]; + $nextValue = $this->_nextToken(); + if (empty($nextValue)) { + $value = $definition['default']; + } else if ($nextValue{0} != '-') { + $value = $nextValue; + } + $params[$name] = $value; + return $params; + } + +/** + * Find the next token in the argv set. + * + * @return next token or '' + */ + protected function _nextToken() { + return isset($this->_tokens[0]) ? $this->_tokens[0] : ''; + } } \ No newline at end of file diff --git a/cake/tests/cases/console/console_option_parser.test.php b/cake/tests/cases/console/console_option_parser.test.php index 868540f1be1..23c7a546c02 100644 --- a/cake/tests/cases/console/console_option_parser.test.php +++ b/cake/tests/cases/console/console_option_parser.test.php @@ -59,6 +59,34 @@ function testAddOptionReturnSelf() { $this->assertEquals($parser, $result, 'Did not return $this from addOption'); } +/** + * test adding an option and using the long value for parsing. + * + * @return void + */ + function testAddOptionLong() { + $parser = new ConsoleOptionParser(); + $parser->addOption('test', array( + 'shortcut' => 't' + )); + $result = $parser->parse(array('--test', 'value')); + $this->assertEqual(array('test' => 'value'), $result[0], 'Long parameter did not parse out'); + } + +/** + * test adding an option and using the default. + * + * @return void + */ + function testAddOptionDefault() { + $parser = new ConsoleOptionParser(); + $parser->addOption('test', array( + 'default' => 'default value', + )); + $result = $parser->parse(array('--test')); + $this->assertEqual(array('test' => 'default value'), $result[0], 'Default value did not parse out'); + } + /** * test adding an option and using the shortcut value for parsing. *