Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactored the shell reflection portion into a seperate task.

  • Loading branch information...
commit ac9b7f3882ba5ba8ab240508e46fc8d0ff30b056 1 parent 5c523a0
@WyriHaximus WyriHaximus authored
View
51 lib/Cake/Console/Command/CommandListShell.php
@@ -25,6 +25,13 @@
class CommandListShell extends AppShell {
/**
+ * Contains tasks to load and instantiate
+ *
+ * @var array
+ */
+ public $tasks = array('Command');
+
+/**
* startup
*
* @return void
@@ -55,7 +62,7 @@ public function main() {
$this->out(__d('cake_console', "<info>Available Shells:</info>"), 2);
}
- $shellList = $this->_getShellList();
+ $shellList = $this->Command->getShellList();
if (empty($shellList)) {
return;
}
@@ -68,48 +75,6 @@ public function main() {
}
/**
- * Gets the shell command listing.
- *
- * @return array
- */
- protected function _getShellList() {
- $skipFiles = array('AppShell');
-
- $plugins = CakePlugin::loaded();
- $shellList = array_fill_keys($plugins, null) + array('CORE' => null, 'app' => null);
-
- $corePath = App::core('Console/Command');
- $shells = App::objects('file', $corePath[0]);
- $shells = array_diff($shells, $skipFiles);
- $this->_appendShells('CORE', $shells, $shellList);
-
- $appShells = App::objects('Console/Command', null, false);
- $appShells = array_diff($appShells, $shells, $skipFiles);
- $this->_appendShells('app', $appShells, $shellList);
-
- foreach ($plugins as $plugin) {
- $pluginShells = App::objects($plugin . '.Console/Command');
- $this->_appendShells($plugin, $pluginShells, $shellList);
- }
-
- return array_filter($shellList);
- }
-
-/**
- * Scan the provided paths for shells, and append them into $shellList
- *
- * @param string $type
- * @param array $shells
- * @param array $shellList
- * @return void
- */
- protected function _appendShells($type, $shells, &$shellList) {
- foreach ($shells as $shell) {
- $shellList[$type][] = Inflector::underscore(str_replace('Shell', '', $shell));
- }
- }
-
-/**
* Output text.
*
* @param array $shellList
View
131 lib/Cake/Console/Command/CompletionShell.php
@@ -14,14 +14,21 @@
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
-App::uses('CommandListShell', 'Console/Command');
+App::uses('AppShell', 'Console/Command');
/**
* Provide command completion shells such as bash.
*
* @package Cake.Console.Command
*/
-class CompletionShell extends CommandListShell {
+class CompletionShell extends AppShell {
+
+/**
+ * Contains tasks to load and instantiate
+ *
+ * @var array
+ */
+ public $tasks = array('Command');
/**
* Echo no header by overriding the startup method
@@ -37,7 +44,7 @@ public function startup() {
* @return void
*/
public function main() {
- return $this->out($this->OptionParser->help());
+ return $this->out($this->getOptionParser()->help());
}
/**
@@ -46,7 +53,7 @@ public function main() {
* @return void
*/
public function commands() {
- $options = $this->_commands();
+ $options = $this->Command->commands();
return $this->_output($options);
}
@@ -56,26 +63,12 @@ public function commands() {
* @return void
*/
public function options() {
- if (!$this->args) {
- $parser = new ConsoleOptionParser();
- } else {
- $Shell = $this->_getShell($this->args[0]);
- if (!$Shell) {
- $parser = new ConsoleOptionParser();
- } else {
- $parser = $Shell->getOptionParser();
- }
+ $commandName = '';
+ if (!empty($this->args[0])) {
+ $commandName = $this->args[0];
}
+ $options = $this->Command->options($commandName);
- $options = array();
- $array = $parser->options();
- foreach ($array as $name => $obj) {
- $options[] = "--$name";
- $short = $obj->short();
- if ($short) {
- $options[] = "-$short";
- }
- }
return $this->_output($options);
}
@@ -89,7 +82,7 @@ public function subCommands() {
return $this->_output();
}
- $options = $this->_subCommands($this->args[0]);
+ $options = $this->Command->subCommands($this->args[0]);
return $this->_output($options);
}
@@ -149,98 +142,6 @@ public function getOptionParser() {
}
/**
- * Return a list of all commands
- *
- * @return array
- */
- protected function _commands() {
- $shellList = $this->_getShellList();
- unset($shellList['Completion']);
-
- $options = array();
- foreach ($shellList as $type => $commands) {
- $prefix = '';
- if (!in_array(strtolower($type), array('app', 'core'))) {
- $prefix = $type . '.';
- }
-
- foreach ($commands as $shell) {
- $options[] = $prefix . $shell;
- }
- }
-
- return $options;
- }
-
-/**
- * Return a list of subcommands for a given command
- *
- * @param string $commandName
- * @return array
- */
- protected function _subCommands($commandName) {
- $Shell = $this->_getShell($commandName);
-
- if (!$Shell) {
- return array();
- }
-
- $taskMap = TaskCollection::normalizeObjectArray((array)$Shell->tasks);
- $return = array_keys($taskMap);
- $return = array_map('Inflector::underscore', $return);
-
- $ShellReflection = new ReflectionClass('AppShell');
- $shellMethods = $ShellReflection->getMethods(ReflectionMethod::IS_PUBLIC);
- $shellMethodNames = array('main', 'help');
- foreach ($shellMethods as $method) {
- $shellMethodNames[] = $method->getName();
- }
-
- $Reflection = new ReflectionClass($Shell);
- $methods = $Reflection->getMethods(ReflectionMethod::IS_PUBLIC);
- $methodNames = array();
- foreach ($methods as $method) {
- $methodNames[] = $method->getName();
- }
-
- $return += array_diff($methodNames, $shellMethodNames);
- sort($return);
-
- return $return;
- }
-
-/**
- * Get Shell instance for the given command
- *
- * @param mixed $commandName
- * @return mixed
- */
- protected function _getShell($commandName) {
- list($pluginDot, $name) = pluginSplit($commandName, true);
-
- if (in_array(strtolower($pluginDot), array('app.', 'core.'))) {
- $commandName = $name;
- $pluginDot = '';
- }
-
- if (!in_array($commandName, $this->_commands())) {
- return false;
- }
-
- $name = Inflector::camelize($name);
- $pluginDot = Inflector::camelize($pluginDot);
- $class = $name . 'Shell';
- APP::uses($class, $pluginDot . 'Console/Command');
-
- $Shell = new $class();
- $Shell->plugin = trim($pluginDot, '.');
- $Shell->initialize();
- $Shell->loadTasks();
-
- return $Shell;
- }
-
-/**
* Emit results as a string, space delimited
*
* @param array $options
View
183 lib/Cake/Console/Command/Task/CommandTask.php
@@ -0,0 +1,183 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.5
+ * @license http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+
+App::uses('AppShell', 'Console/Command');
+
+/**
+ * Base class for Shell Command reflection.
+ *
+ * @package Cake.Console.Command.Task
+ */
+class CommandTask extends AppShell {
+
+/**
+ * Gets the shell command listing.
+ *
+ * @return array
+ */
+ public function getShellList() {
+ $skipFiles = array('AppShell');
+
+ $plugins = CakePlugin::loaded();
+ $shellList = array_fill_keys($plugins, null) + array('CORE' => null, 'app' => null);
+
+ $corePath = App::core('Console/Command');
+ $shells = App::objects('file', $corePath[0]);
+ $shells = array_diff($shells, $skipFiles);
+ $this->_appendShells('CORE', $shells, $shellList);
+
+ $appShells = App::objects('Console/Command', null, false);
+ $appShells = array_diff($appShells, $shells, $skipFiles);
+ $this->_appendShells('app', $appShells, $shellList);
+
+ foreach ($plugins as $plugin) {
+ $pluginShells = App::objects($plugin . '.Console/Command');
+ $this->_appendShells($plugin, $pluginShells, $shellList);
+ }
+
+ return array_filter($shellList);
+ }
+
+/**
+ * Scan the provided paths for shells, and append them into $shellList
+ *
+ * @param string $type
+ * @param array $shells
+ * @param array $shellList
+ * @return void
+ */
+ protected function _appendShells($type, $shells, &$shellList) {
+ foreach ($shells as $shell) {
+ $shellList[$type][] = Inflector::underscore(str_replace('Shell', '', $shell));
+ }
+ }
+
+/**
+ * Return a list of all commands
+ *
+ * @return array
+ */
+ public function commands() {
+ $shellList = $this->getShellList();
+
+ $options = array();
+ foreach ($shellList as $type => $commands) {
+ $prefix = '';
+ if (!in_array(strtolower($type), array('app', 'core'))) {
+ $prefix = $type . '.';
+ }
+
+ foreach ($commands as $shell) {
+ $options[] = $prefix . $shell;
+ }
+ }
+
+ return $options;
+ }
+
+/**
+ * Return a list of subcommands for a given command
+ *
+ * @param string $commandName
+ * @return array
+ */
+ public function subCommands($commandName) {
+ $Shell = $this->getShell($commandName);
+
+ if (!$Shell) {
+ return array();
+ }
+
+ $taskMap = TaskCollection::normalizeObjectArray((array)$Shell->tasks);
+ $return = array_keys($taskMap);
+ $return = array_map('Inflector::underscore', $return);
+
+ $ShellReflection = new ReflectionClass('AppShell');
+ $shellMethods = $ShellReflection->getMethods(ReflectionMethod::IS_PUBLIC);
+ $shellMethodNames = array('main', 'help');
+ foreach ($shellMethods as $method) {
+ $shellMethodNames[] = $method->getName();
+ }
+
+ $Reflection = new ReflectionClass($Shell);
+ $methods = $Reflection->getMethods(ReflectionMethod::IS_PUBLIC);
+ $methodNames = array();
+ foreach ($methods as $method) {
+ $methodNames[] = $method->getName();
+ }
+
+ $return += array_diff($methodNames, $shellMethodNames);
+ sort($return);
+
+ return $return;
+ }
+
+/**
+ * Get Shell instance for the given command
+ *
+ * @param mixed $commandName
+ * @return mixed
+ */
+ public function getShell($commandName) {
+ list($pluginDot, $name) = pluginSplit($commandName, true);
+
+ if (in_array(strtolower($pluginDot), array('app.', 'core.'))) {
+ $commandName = $name;
+ $pluginDot = '';
+ }
+
+ if (!in_array($commandName, $this->commands())) {
+ return false;
+ }
+
+ $name = Inflector::camelize($name);
+ $pluginDot = Inflector::camelize($pluginDot);
+ $class = $name . 'Shell';
+ APP::uses($class, $pluginDot . 'Console/Command');
+
+ $Shell = new $class();
+ $Shell->plugin = trim($pluginDot, '.');
+ $Shell->initialize();
+
+ return $Shell;
+ }
+
+/**
+ * Get Shell instance for the given command
+ *
+ * @param mixed $commandName
+ * @return array
+ */
+ public function options($commandName) {
+ $Shell = $this->getShell($commandName);
+ if (!$Shell) {
+ $parser = new ConsoleOptionParser();
+ } else {
+ $parser = $Shell->getOptionParser();
+ }
+
+ $options = array();
+ $array = $parser->options();
+ foreach ($array as $name => $obj) {
+ $options[] = "--$name";
+ $short = $obj->short();
+ if ($short) {
+ $options[] = "-$short";
+ }
+ }
+ return $options;
+ }
+
+}
View
7 lib/Cake/Test/Case/Console/Command/CommandListShellTest.php
@@ -22,6 +22,7 @@
App::uses('ConsoleOutput', 'Console');
App::uses('ConsoleInput', 'Console');
App::uses('Shell', 'Console');
+App::uses('CommandTask', 'Console/Command/Task');
/**
* Class TestStringOutput
@@ -70,6 +71,12 @@ public function setUp() {
array('in', '_stop', 'clear'),
array($out, $out, $in)
);
+
+ $this->Shell->Command = $this->getMock(
+ 'CommandTask',
+ array('in', '_stop', 'clear'),
+ array($out, $out, $in)
+ );
}
/**
View
7 lib/Cake/Test/Case/Console/Command/CompletionShellTest.php
@@ -22,6 +22,7 @@
App::uses('ConsoleOutput', 'Console');
App::uses('ConsoleInput', 'Console');
App::uses('Shell', 'Console');
+App::uses('CommandTask', 'Console/Command/Task');
/**
* Class TestCompletionStringOutput
@@ -70,6 +71,12 @@ public function setUp() {
array('in', '_stop', 'clear'),
array($out, $out, $in)
);
+
+ $this->Shell->Command = $this->getMock(
+ 'CommandTask',
+ array('in', '_stop', 'clear'),
+ array($out, $out, $in)
+ );
}
/**
View
240 lib/Cake/Test/Case/Console/Command/Task/CommandTaskTest.php
@@ -0,0 +1,240 @@
+<?php
+/**
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Console.Command
+ * @since CakePHP v 2.5
+ * @license http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+
+App::uses('CommandTask', 'Console/Command/Task');
+
+/**
+ * CommandTaskTest class
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class CommandTaskTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ App::build(array(
+ 'Plugin' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS
+ ),
+ 'Console/Command' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Console' . DS . 'Command' . DS
+ )
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->CommandTask = $this->getMock(
+ 'CommandTask',
+ array('in', '_stop', 'clear'),
+ array($out, $out, $in)
+ );
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->CommandTask);
+ CakePlugin::unload();
+ }
+
+/**
+ * Test the resulting list of shells
+ *
+ * @return void
+ */
+ public function testGetShellList() {
+ $result = $this->CommandTask->getShellList();
+
+ $expected = array(
+ 'CORE' => array(
+ 'acl',
+ 'api',
+ 'bake',
+ 'command_list',
+ 'completion',
+ 'console',
+ 'i18n',
+ 'schema',
+ 'server',
+ 'test',
+ 'testsuite',
+ 'upgrade'
+ ),
+ 'TestPlugin' => array(
+ 'example'
+ ),
+ 'TestPluginTwo' => array(
+ 'example',
+ 'welcome'
+ ),
+ 'app' => array(
+ 'sample'
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test the resulting list of commands
+ *
+ * @return void
+ */
+ public function testCommands() {
+ $result = $this->CommandTask->commands();
+
+ $expected = array(
+ 'TestPlugin.example',
+ 'TestPluginTwo.example',
+ 'TestPluginTwo.welcome',
+ 'acl',
+ 'api',
+ 'bake',
+ 'command_list',
+ 'completion',
+ 'console',
+ 'i18n',
+ 'schema',
+ 'server',
+ 'test',
+ 'testsuite',
+ 'upgrade',
+ 'sample'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test the resulting list of subcommands for the given command
+ *
+ * @return void
+ */
+ public function testSubCommands() {
+ $result = $this->CommandTask->subCommands('acl');
+
+ $expected = array(
+ 'check',
+ 'create',
+ 'db_config',
+ 'delete',
+ 'deny',
+ 'getPath',
+ 'grant',
+ 'inherit',
+ 'initdb',
+ 'nodeExists',
+ 'parseIdentifier',
+ 'setParent',
+ 'view'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that unknown commands return an empty array
+ *
+ * @return void
+ */
+ public function testSubCommandsUnknownCommand() {
+ $result = $this->CommandTask->subCommands('yoghurt');
+
+ $expected = array();
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that getting a existing shell returns the shell instance
+ *
+ * @return void
+ */
+ public function testGetShell() {
+ $result = $this->CommandTask->getShell('acl');
+ $this->assertInstanceOf('AclShell', $result);
+ }
+
+/**
+ * Test that getting a non-existing shell returns false
+ *
+ * @return void
+ */
+ public function testGetShellNonExisting() {
+ $result = $this->CommandTask->getShell('strawberry');
+ $this->assertFalse($result);
+ }
+
+/**
+ * Test that getting a existing core shell with 'core.' prefix returns the correct shell instance
+ *
+ * @return void
+ */
+ public function testGetShellCore() {
+ $result = $this->CommandTask->getShell('core.bake');
+ $this->assertInstanceOf('BakeShell', $result);
+ }
+
+/**
+ * Test the options array for a known command
+ *
+ * @return void
+ */
+ public function testOptions() {
+ $result = $this->CommandTask->options('bake');
+
+ $expected = array(
+ '--help',
+ '-h',
+ '--verbose',
+ '-v',
+ '--quiet',
+ '-q',
+ '--connection',
+ '-c',
+ '--theme',
+ '-t'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test the options array for an unknown command
+ *
+ * @return void
+ */
+ public function testOptionsUnknownCommand() {
+ $result = $this->CommandTask->options('pie');
+
+ $expected = array(
+ '--help',
+ '-h',
+ '--verbose',
+ '-v',
+ '--quiet',
+ '-q'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+}
Please sign in to comment.
Something went wrong with that request. Please try again.