diff --git a/cake/console/console_option_parser.php b/cake/console/console_option_parser.php
index 5c4bd1904b5..1bf516c31a3 100644
--- a/cake/console/console_option_parser.php
+++ b/cake/console/console_option_parser.php
@@ -52,6 +52,13 @@ class ConsoleOptionParser {
*/
protected $_options = array();
+/**
+ * Map of short -> long options, generated when using addOption()
+ *
+ * @var string
+ */
+ protected $_shortOptions = array();
+
/**
* Positional argument definitions.
*
@@ -99,8 +106,24 @@ class ConsoleOptionParser {
* can generate a help display for you. You can view the help for shells by using the `--help` or `-h` switch.
*
*/
- public function __construct() {
+ public function __construct($command = null, $defaultOptions = true) {
+ $this->_command = $command;
+ $this->addOption('help', array(
+ 'short' => 'h',
+ 'help' => 'Display this help.',
+ 'boolean' => true
+ ));
+
+ if ($defaultOptions) {
+ $this->addOption('verbose', array(
+ 'short' => 'v',
+ 'help' => __('Enable verbose output.')
+ ))->addOption('quiet', array(
+ 'short' => 'q',
+ 'help' => __('Enable quiet output.')
+ ));
+ }
}
/**
@@ -158,7 +181,7 @@ public function addOption($name, $params = array()) {
$options = array_merge($defaults, $params);
$this->_options[$name] = $options;
if (!empty($options['short'])) {
- $this->_options[$options['short']] = $options;
+ $this->_shortOptions[$options['short']] = $name;
}
return $this;
}
@@ -200,6 +223,15 @@ public function arguments() {
return $this->_args;
}
+/**
+ * Get the defined options in the parser.
+ *
+ * @return array
+ */
+ public function options() {
+ return $this->_options;
+ }
+
/**
* Parse the argv array into a set of params and args.
*
@@ -229,6 +261,62 @@ public function parse($argv) {
return array($params, $args);
}
+/**
+ * Gets formatted help for this parser object.
+ * Generates help text based on the description, options, arguments and epilog
+ * in the parser.
+ *
+ * @return string
+ */
+ public function help() {
+ $out = array();
+ $out[] = 'Usage:';
+ $out[] = 'cake ' . $this->_command . $this->_generateUsage();
+ $out[] = '';
+ if (!empty($this->_options)) {
+ $max = 0;
+ foreach ($this->_options as $description) {
+ $max = (strlen($description['name']) > $max) ? strlen($description['name']) : $max;
+ }
+ $max += 3;
+ $out[] = 'Options:';
+ $out[] = '';
+ foreach ($this->_options as $description) {
+ $out[] = $this->_optionHelp($description, $max);
+ }
+ }
+ return implode("\n", $out);
+ }
+
+/**
+ * Generate the usage for a shell based on its arguments and options.
+ *
+ * @return void
+ */
+ protected function _generateUsage() {
+
+ }
+
+/**
+ * Generate the usage for a single option.
+ *
+ * @return string
+ */
+ protected function _optionHelp($definition, $nameWidth) {
+ $default = $short = '';
+ if (!empty($definition['default']) && $definition['default'] !== true) {
+ $default = sprintf(__(' (default: %s)'), $definition['default']);
+ }
+ if (!empty($definition['short'])) {
+ $short = ', -' . $definition['short'];
+ }
+ $name = sprintf('--%s%s', $definition['name'], $short);
+ if (strlen($name) < $nameWidth) {
+ $name = str_pad($name, $nameWidth, ' ');
+ }
+ return sprintf('%s %s%s', $name, $definition['help'], $default);
+ }
+
/**
* Parse the value for a long option out of $this->_tokens. Will handle
* options with an `=` in them.
@@ -264,7 +352,7 @@ protected function _parseShortOption($option, $params) {
array_unshift($this->_tokens, '-' . $flags[$i]);
}
}
- $name = $this->_options[$key]['name'];
+ $name = $this->_shortOptions[$key];
return $this->_parseOptionName($name, $params);
}
diff --git a/cake/tests/cases/console/console_option_parser.test.php b/cake/tests/cases/console/console_option_parser.test.php
index 2b7863483e4..3b99fa710d7 100644
--- a/cake/tests/cases/console/console_option_parser.test.php
+++ b/cake/tests/cases/console/console_option_parser.test.php
@@ -222,4 +222,28 @@ function testPositionalArgNotEnough() {
$parser->parse(array('one'));
}
+
+/**
+ * test getting help with defined options.
+ *
+ * @return void
+ */
+ function testGetHelpWithOptions() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->addOption('test', array('short' => 't', 'help' => 'A test option.'))
+ ->addOption('connection', array('help' => 'The connection to use.', 'default' => 'default'));
+
+ $result = $parser->help();
+ $expected = <<Usage:
+cake mycommand [-h] [-t] [--connection default]
+
+Options:
+
+--help, -h Display this help.
+--test, -t A test option.
+--connection The connection to use. (default: default)
+TEXT;
+ $this->assertEquals($expected, $result, 'Help does not match');
+ }
}
\ No newline at end of file