diff --git a/cake/console/shells/command_list.php b/cake/console/shells/command_list.php index ef5d52478..03e2bbed4 100644 --- a/cake/console/shells/command_list.php +++ b/cake/console/shells/command_list.php @@ -42,6 +42,25 @@ class CommandListShell extends Shell { $this->out("Example: -app relative/path/to/myapp or -app /absolute/path/to/myapp", 2); $this->out("Available Shells:", 2); + + $shellList = $this->_getShellList(); + + if ($shellList) { + ksort($shellList); + if (empty($this->params['xml'])) { + $this->_asText($shellList); + } else { + $this->_asXml($shellList); + } + } + } + +/** + * Gets the shell command listing. + * + * @return array + */ + protected function _getShellList() { $shellList = array(); $corePaths = App::core('shells'); @@ -55,37 +74,7 @@ class CommandListShell extends Shell { $pluginPath = App::pluginPath($plugin) . 'console' . DS . 'shells' . DS; $shellList = $this->_appendShells($plugin, array($pluginPath), $shellList); } - - if ($shellList) { - ksort($shellList); - if (DS === '/') { - $width = exec('tput cols') - 2; - } - if (empty($width)) { - $width = 80; - } - $columns = max(1, floor($width / 30)); - $rows = ceil(count($shellList) / $columns); - - foreach ($shellList as $shell => $types) { - sort($types); - $shellList[$shell] = str_pad($shell . ' [' . implode ($types, ', ') . ']', $width / $columns); - } - $out = array_chunk($shellList, $rows); - for ($i = 0; $i < $rows; $i++) { - $row = ''; - for ($j = 0; $j < $columns; $j++) { - if (!isset($out[$j][$i])) { - continue; - } - $row .= $out[$j][$i]; - } - $this->out(" " . $row); - } - } - $this->out(); - $this->out("To run a command, type cake shell_name [args]"); - $this->out("To get help on a specific command, type cake shell_name --help", 2); + return $shellList; } /** @@ -112,4 +101,76 @@ class CommandListShell extends Shell { } return $shellList; } + +/** + * Output text. + * + * @return void + */ + protected function _asText($shellList) { + if (DS === '/') { + $width = exec('tput cols') - 2; + } + if (empty($width)) { + $width = 80; + } + $columns = max(1, floor($width / 30)); + $rows = ceil(count($shellList) / $columns); + + foreach ($shellList as $shell => $types) { + sort($types); + $shellList[$shell] = str_pad($shell . ' [' . implode ($types, ', ') . ']', $width / $columns); + } + $out = array_chunk($shellList, $rows); + for ($i = 0; $i < $rows; $i++) { + $row = ''; + for ($j = 0; $j < $columns; $j++) { + if (!isset($out[$j][$i])) { + continue; + } + $row .= $out[$j][$i]; + } + $this->out(" " . $row); + } + $this->out(); + $this->out("To run a command, type cake shell_name [args]"); + $this->out("To get help on a specific command, type cake shell_name --help", 2); + } + +/** + * Output as XML + * + * @return void + */ + protected function _asXml($shellList) { + $plugins = App::objects('plugin'); + $shells = new SimpleXmlElement(''); + foreach ($shellList as $name => $location) { + $source = current($location); + $callable = $name; + if (in_array($source, $plugins)) { + $callable = Inflector::underscore($source) . '.' . $name; + } + $shell = $shells->addChild('shell'); + $shell->addAttribute('name', $name); + $shell->addAttribute('call_as', $callable); + $shell->addAttribute('provider', $source); + $shell->addAttribute('help', $callable . ' -h'); + } + $this->out($shells->saveXml()); + } + +/** + * get the option parser + * + * @return void + */ + public function getOptionParser() { + $parser = parent::getOptionParser(); + return $parser->description('Get the list of available shells for this CakePHP application.') + ->addOption('xml', array( + 'help' => __('Get the listing as XML.'), + 'boolean' => true + )); + } } diff --git a/cake/tests/cases/console/shells/command_list.test.php b/cake/tests/cases/console/shells/command_list.test.php index 8353989e2..303b42570 100644 --- a/cake/tests/cases/console/shells/command_list.test.php +++ b/cake/tests/cases/console/shells/command_list.test.php @@ -48,7 +48,7 @@ class CommandListTest extends CakeTestCase { TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'console' . DS . 'shells' . DS ) ), true); - App::objects('plugins', null, false); + App::objects('plugin', null, false); $this->Dispatcher = $this->getMock( 'ShellDispatcher', @@ -82,7 +82,7 @@ class CommandListTest extends CakeTestCase { function testMain() { $this->Shell->main(); $output = $this->Shell->stdout->output; - +; $expected = "/example \[.*TestPlugin, TestPluginTwo.*\]/"; $this->assertPattern($expected, $output); @@ -113,4 +113,25 @@ class CommandListTest extends CakeTestCase { $expected = "/sample \[.*app.*\]/"; $this->assertPattern($expected, $output); } + +/** + * test xml output. + * + * @return void + */ + function testMainXml() { + $this->Shell->params['xml'] = true; + $this->Shell->main(); + + $output = $this->Shell->stdout->output; + + $find = ''; + $this->assertContains($find, $output); + + $find = ''; + $this->assertContains($find, $output); + + $find = ''; + $this->assertContains($find, $output); + } }