From 02c4e00556c3f8da505f8fb7e8e6f3504b234011 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 3 Oct 2010 23:42:24 -0400 Subject: [PATCH] Starting to move command list out to a separate class so ShellDispatcher can stop having stderr/stdout connections. --- cake/console/libs/command_list.php | 102 ++++++++++++++++ cake/console/shell_dispatcher.php | 2 +- .../cases/console/libs/command_list.test.php | 112 ++++++++++++++++++ 3 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 cake/console/libs/command_list.php create mode 100644 cake/tests/cases/console/libs/command_list.test.php diff --git a/cake/console/libs/command_list.php b/cake/console/libs/command_list.php new file mode 100644 index 00000000000..566152221a8 --- /dev/null +++ b/cake/console/libs/command_list.php @@ -0,0 +1,102 @@ +out("\nWelcome to CakePHP v" . Configure::version() . " Console"); + $this->out("---------------------------------------------------------------"); + $this->out("Current Paths:"); + $this->out(" -app: ". $this->params['app']); + $this->out(" -working: " . rtrim($this->params['working'], DS)); + $this->out(" -root: " . rtrim($this->params['root'], DS)); + $this->out(" -core: " . rtrim(CORE_PATH, DS)); + $this->out(""); + $this->out("Changing Paths:"); + $this->out("your working path should be the same as your application path"); + $this->out("to change your path use the '-app' param."); + $this->out("Example: -app relative/path/to/myapp or -app /absolute/path/to/myapp"); + + $this->out("\nAvailable Shells:"); + $shellList = array(); + foreach ($this->Dispatch->shellPaths as $path) { + if (!is_dir($path)) { + continue; + } + $shells = App::objects('file', $path); + if (empty($shells)) { + continue; + } + if (preg_match('@plugins[\\\/]([^\\\/]*)@', $path, $matches)) { + $type = Inflector::camelize($matches[1]); + } elseif (preg_match('@([^\\\/]*)[\\\/]vendors[\\\/]@', $path, $matches)) { + $type = $matches[1]; + } elseif (strpos($path, CAKE_CORE_INCLUDE_PATH . DS . 'cake') === 0) { + $type = 'CORE'; + } else { + $type = 'app'; + } + foreach ($shells as $shell) { + if ($shell !== 'shell.php') { + $shell = str_replace('.php', '', $shell); + $shellList[$shell][$type] = $type; + } + } + } + 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("\nTo run a command, type 'cake shell_name [args]'"); + $this->out("To get help on a specific command, type 'cake shell_name help'"); + } +} diff --git a/cake/console/shell_dispatcher.php b/cake/console/shell_dispatcher.php index d5d0bc2339b..d772d5cc0af 100644 --- a/cake/console/shell_dispatcher.php +++ b/cake/console/shell_dispatcher.php @@ -353,7 +353,6 @@ public function dispatch() { return $Shell->main(); } } - throw new MissingShellMethodException(array('shell' => $this->shell, 'method' => $arg)); } @@ -548,6 +547,7 @@ public function shiftArgs() { * */ public function help() { + // Make Command List and display it here. $this->clear(); $this->stdout("\nWelcome to CakePHP v" . Configure::version() . " Console"); $this->stdout("---------------------------------------------------------------"); diff --git a/cake/tests/cases/console/libs/command_list.test.php b/cake/tests/cases/console/libs/command_list.test.php new file mode 100644 index 00000000000..602226ccaa9 --- /dev/null +++ b/cake/tests/cases/console/libs/command_list.test.php @@ -0,0 +1,112 @@ +output .= $message; + } +} + +class CommandListTest extends CakeTestCase { +/** + * setUp method + * + * @return void + */ + public function setUp() { + parent::setUp(); + App::build(array( + 'plugins' => array( + TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS + ), + 'shells' => array( + CORE_PATH ? CONSOLE_LIBS : ROOT . DS . CONSOLE_LIBS, + TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'vendors' . DS . 'shells' . DS + ) + ), true); + App::objects('plugins', null, false); + + $this->Dispatcher = $this->getMock( + 'ShellDispatcher', + array('getInput', 'stderr', '_stop', '_initEnvironment', 'dispatch', 'clear') + ); + $this->Dispatcher->stdout = new TestStringOutput(); + + $this->Shell = $this->getMock( + 'CommandListShell', + array('in', '_stop'), + array(&$this->Dispatcher) + ); + } + +/** + * teardown + * + * @return void + */ + function tearDown() { + unset($this->Dispatcher, $this->Shell); + } + +/** + * test that main finds core shells. + * + * @return void + */ + function testMain() { + $this->Shell->main(); + $output = $this->Dispatcher->stdout->output; + + $expected = "/example \[.*TestPlugin, TestPluginTwo.*\]/"; + $this->assertPattern($expected, $output); + + $expected = "/welcome \[.*TestPluginTwo.*\]/"; + $this->assertPattern($expected, $output); + + $expected = "/acl \[.*CORE.*\]/"; + $this->assertPattern($expected, $output); + + $expected = "/api \[.*CORE.*\]/"; + $this->assertPattern($expected, $output); + + $expected = "/bake \[.*CORE.*\]/"; + $this->assertPattern($expected, $output); + + $expected = "/console \[.*CORE.*\]/"; + $this->assertPattern($expected, $output); + + $expected = "/i18n \[.*CORE.*\]/"; + $this->assertPattern($expected, $output); + + $expected = "/schema \[.*CORE.*\]/"; + $this->assertPattern($expected, $output); + + $expected = "/testsuite \[.*CORE.*\]/"; + $this->assertPattern($expected, $output); + + $expected = "/sample \[.*test_app.*\]/"; + $this->assertPattern($expected, $output); + } +}