From 64c3d1ef95a48687acf6774d13c0e6fb56fa2a67 Mon Sep 17 00:00:00 2001 From: "renan.saddam" Date: Thu, 13 Nov 2008 00:33:53 +0000 Subject: [PATCH] Fixing issue when Dispatcher is getting plugin shell. Fixes #5740. git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@7871 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/console/cake.php | 65 +++--- cake/tests/cases/console/cake.test.php | 193 ++++++++++++++++-- .../test_plugin/vendors/shells/example.php | 37 ++++ .../test_plugin/vendors/shells/tasks/empty | 0 .../vendors/shells/templates/empty | 0 .../vendors/shells/example.php | 37 ++++ .../vendors/shells/tasks/empty | 0 .../vendors/shells/templates/empty | 0 .../vendors/shells/welcome.php | 37 ++++ cake/tests/test_app/vendors/shells/sample.php | 37 ++++ 10 files changed, 363 insertions(+), 43 deletions(-) create mode 100644 cake/tests/test_app/plugins/test_plugin/vendors/shells/example.php create mode 100644 cake/tests/test_app/plugins/test_plugin/vendors/shells/tasks/empty create mode 100644 cake/tests/test_app/plugins/test_plugin/vendors/shells/templates/empty create mode 100644 cake/tests/test_app/plugins/test_plugin_two/vendors/shells/example.php create mode 100644 cake/tests/test_app/plugins/test_plugin_two/vendors/shells/tasks/empty create mode 100644 cake/tests/test_app/plugins/test_plugin_two/vendors/shells/templates/empty create mode 100644 cake/tests/test_app/plugins/test_plugin_two/vendors/shells/welcome.php create mode 100644 cake/tests/test_app/vendors/shells/sample.php diff --git a/cake/console/cake.php b/cake/console/cake.php index 738ab72f7..97824e62d 100644 --- a/cake/console/cake.php +++ b/cake/console/cake.php @@ -126,8 +126,9 @@ class ShellDispatcher { set_time_limit(0); $this->__initConstants(); $this->parseParams($args); - $this->__initEnvironment(); - exit($this->dispatch()); + $this->_initEnvironment(); + $this->__buildPaths(); + $this->_stop($this->dispatch()); } /** * Defines core configuration. @@ -156,9 +157,9 @@ class ShellDispatcher { /** * Defines current working environment. * - * @access private + * @access protected */ - function __initEnvironment() { + function _initEnvironment() { $this->stdin = fopen('php://stdin', 'r'); $this->stdout = fopen('php://stdout', 'w'); $this->stderr = fopen('php://stderr', 'w'); @@ -167,7 +168,7 @@ class ShellDispatcher { $this->stderr("\nCakePHP Console: "); $this->stderr("\nUnable to load Cake core:"); $this->stderr("\tMake sure " . DS . 'cake' . DS . 'libs exists in ' . CAKE_CORE_INCLUDE_PATH); - exit(); + $this->_stop(); } if (!isset($this->args[0]) || !isset($this->params['working'])) { @@ -176,26 +177,33 @@ class ShellDispatcher { $this->stderr('Please make sure that ' . DIRECTORY_SEPARATOR . 'cake' . DIRECTORY_SEPARATOR . 'console is in your system path,'); $this->stderr('and check the manual for the correct usage of this command.'); $this->stderr('(http://manual.cakephp.org/)'); - exit(); + $this->_stop(); } if (basename(__FILE__) != basename($this->args[0])) { $this->stderr("\nCakePHP Console: "); $this->stderr('Warning: the dispatcher may have been loaded incorrectly, which could lead to unexpected results...'); if ($this->getInput('Continue anyway?', array('y', 'n'), 'y') == 'n') { - exit(); + $this->_stop(); } } $this->shiftArgs(); - + } +/** + * Builds the shell paths. + * + * @access private + * @return void + */ + function __buildPaths() { $paths = array(); $pluginPaths = Configure::read('pluginPaths'); foreach ($pluginPaths as $pluginPath) { $plugins = Configure::listObjects('plugin', $pluginPath); foreach ((array)$plugins as $plugin) { - $path = $pluginPath . strtolower($plugin) . DS . 'vendors' . DS . 'shells' . DS; + $path = $pluginPath . Inflector::underscore($plugin) . DS . 'vendors' . DS . 'shells' . DS; if (file_exists($path)) { $paths[] = $path; } @@ -273,14 +281,15 @@ class ShellDispatcher { $this->shellName = Inflector::camelize($this->shell); $this->shellClass = $this->shellName . 'Shell'; - if ($this->shell == 'help') { + if ($this->shell === 'help') { $this->help(); } else { $loaded = false; - foreach ($this->shellPaths as $path) { - $this->shellPath = $path . $this->shell . ".php"; - if (file_exists($this->shellPath)) { + $this->shellPath = $path . $this->shell . '.php'; + + $isPlugin = ($plugin && strpos($path, DS . $plugin . DS . 'vendors' . DS . 'shells' . DS) !== false); + if (($isPlugin && file_exists($this->shellPath)) || (!$plugin && file_exists($this->shellPath))) { $loaded = true; break; } @@ -317,7 +326,7 @@ class ShellDispatcher { if (isset($this->args[0]) && $this->args[0] == 'help') { if (method_exists($shell->{$task}, 'help')) { $shell->{$task}->help(); - exit(); + $this->_stop(); } else { $this->help(); } @@ -452,7 +461,7 @@ class ShellDispatcher { } } - if ($params['app'][0] == '/' || preg_match('/([a-z])(:)/i', $params['app'], $matches)) { + if ($params['app'][0] == '/' || preg_match('/([a-zA-Z])(:)/i', $params['app'], $matches)) { $params['root'] = dirname($params['app']); } elseif (strpos($params['app'], '/')) { $params['root'] .= '/' . dirname($params['app']); @@ -536,18 +545,16 @@ class ShellDispatcher { foreach ($this->shellPaths as $path) { if (is_dir($path)) { $shells = Configure::listObjects('file', $path); - $path = r(CORE_PATH, 'CORE/', $path); - $path = r(ROOT, 'ROOT', $path); - $this->stdout("\n " . rtrim($path, DS) . ":"); + $path = str_replace(CORE_PATH, 'CORE/', $path); + $path = str_replace(ROOT, 'ROOT', $path); + $path = rtrim($path, DS); + $this->stdout("\n " . $path . ":"); if (empty($shells)) { $this->stdout("\t - none"); } else { foreach ($shells as $shell) { - if ($shell != 'shell.php') { - if (!isset($_shells[$shell])) { - $this->stdout("\t " . r('.php', '', $shell)); - } - $_shells[$shell] = rtrim($path, DS); + if ($shell !== 'shell.php') { + $this->stdout("\t " . str_replace('.php', '', $shell)); } } } @@ -555,7 +562,17 @@ class ShellDispatcher { } $this->stdout("\nTo run a command, type 'cake shell_name [args]'"); $this->stdout("To get help on a specific command, type 'cake shell_name help'"); - exit(); + $this->_stop(); + } +/** + * Stop execution of the current script + * + * @param $status see http://php.net/exit for values + * @return void + * @access protected + */ + function _stop($status = 0) { + exit($status); } } if (!defined('DISABLE_AUTO_DISPATCH')) { diff --git a/cake/tests/cases/console/cake.test.php b/cake/tests/cases/console/cake.test.php index d978fa26d..b70613760 100644 --- a/cake/tests/cases/console/cake.test.php +++ b/cake/tests/cases/console/cake.test.php @@ -49,16 +49,65 @@ class TestShellDispatcher extends ShellDispatcher { */ var $params = array(); /** - * construct method + * stdout property * - * @param array $args - * @access private + * @var string + * @access public + */ + var $stdout = ''; +/** + * stderr property + * + * @var string + * @access public + */ + var $stderr = ''; +/** + * stopped property + * + * @var string + * @access public + */ + var $stopped = null; +/** + * _initEnvironment method + * + * @access protected * @return void */ - function __construct($args = array()) { - set_time_limit(0); - $this->__initConstants(); - $this->parseParams($args); + function _initEnvironment() { + // + } +/** + * stderr method + * + * @access public + * @return void + */ + function stderr($string) { + $this->stderr .= rtrim($string, ' '); + } +/** + * stdout method + * + * @access public + * @return void + */ + function stdout($string, $newline = true) { + if ($newline) { + $this->stdout .= rtrim($string, ' ') . "\n"; + } else { + $this->stdout .= rtrim($string, ' '); + } + } +/** + * _stop method + * + * @access protected + * @return void + */ + function _stop($status = 0) { + $this->stopped = 'Stopped with status: ' . $status; } } /** @@ -68,6 +117,34 @@ class TestShellDispatcher extends ShellDispatcher { * @subpackage cake.tests.cases.libs */ class ShellDispatcherTest extends UnitTestCase { +/** + * setUp method + * + * @access public + * @return void + */ + function setUp() { + if (!isset($this->pluginPaths)) { + $this->pluginPaths = Configure::read('pluginPaths'); + $this->shellPaths = Configure::read('shellPaths'); + } + + Configure::write('pluginPaths', array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS)); + Configure::write('shellPaths', array( + ROOT . DS . CONSOLE_LIBS, + TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'vendors' . DS . 'shells' . DS + )); + } +/** + * tearDown method + * + * @access public + * @return void + */ + function tearDown() { + Configure::write('pluginPaths', $this->pluginPaths); + Configure::write('shellPaths', $this->shellPaths); + } /** * testParseParams method * @@ -99,8 +176,8 @@ class ShellDispatcherTest extends UnitTestCase { $expected = array( 'app' => 'app', 'webroot' => 'webroot', - 'working' => CAKE_CORE_INCLUDE_PATH . DS . 'app', - 'root' => CAKE_CORE_INCLUDE_PATH, + 'working' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH . DS . 'app'), + 'root' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH), ); $Dispatcher->params = $Dispatcher->args = array(); $Dispatcher->parseParams($params); @@ -115,8 +192,8 @@ class ShellDispatcherTest extends UnitTestCase { $expected = array( 'app' => 'new', 'webroot' => 'webroot', - 'working' => CAKE_CORE_INCLUDE_PATH . DS . 'new', - 'root' => CAKE_CORE_INCLUDE_PATH + 'working' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH . DS . 'new'), + 'root' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH) ); $Dispatcher->params = $Dispatcher->args = array(); $Dispatcher->parseParams($params); @@ -135,8 +212,8 @@ class ShellDispatcherTest extends UnitTestCase { $expected = array( 'app' => 'new', 'webroot' => 'webroot', - 'working' => CAKE_CORE_INCLUDE_PATH . DS . 'new', - 'root' => CAKE_CORE_INCLUDE_PATH + 'working' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH . DS . 'new'), + 'root' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH) ); $Dispatcher->params = $Dispatcher->args = array(); @@ -155,8 +232,8 @@ class ShellDispatcherTest extends UnitTestCase { $expected = array( 'app' => 'new', 'webroot' => 'webroot', - 'working' => CAKE_CORE_INCLUDE_PATH . DS . 'new', - 'root' => CAKE_CORE_INCLUDE_PATH + 'working' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH . DS . 'new'), + 'root' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH) ); $Dispatcher->params = $Dispatcher->args = array(); $Dispatcher->parseParams($params); @@ -175,8 +252,8 @@ class ShellDispatcherTest extends UnitTestCase { $expected = array( 'app' => 'new', 'webroot' => 'webroot', - 'working' => CAKE_CORE_INCLUDE_PATH . DS . 'new', - 'root' => CAKE_CORE_INCLUDE_PATH, + 'working' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH . DS . 'new'), + 'root' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH), 'dry' => 1 ); $Dispatcher->params = $Dispatcher->args = array(); @@ -199,8 +276,8 @@ class ShellDispatcherTest extends UnitTestCase { $expected = array( 'app' => 'app', 'webroot' => 'webroot', - 'working' => CAKE_CORE_INCLUDE_PATH . DS . 'app', - 'root' => CAKE_CORE_INCLUDE_PATH, + 'working' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH . DS . 'app'), + 'root' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH), 'dry' => 1, 'f' => 1, 'name' => 'DbAcl' @@ -320,7 +397,85 @@ class ShellDispatcherTest extends UnitTestCase { $Dispatcher->params = $Dispatcher->args = array(); $Dispatcher->parseParams($params); $this->assertEqual($expected, $Dispatcher->params); + } +/** + * testBuildPaths method + * + * @access public + * @return void + */ + function testBuildPaths() { + $Dispatcher =& new TestShellDispatcher(); + $this->assertEqual($Dispatcher->shellPaths, array( + TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin' . DS . 'vendors' . DS . 'shells' . DS, + TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin_two' . DS . 'vendors' . DS . 'shells' . DS, + APP . 'vendors' . DS . 'shells' . DS, + VENDORS . 'shells' . DS, + ROOT . DS . CONSOLE_LIBS, + TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'vendors' . DS . 'shells' . DS, + )); + } +/** + * testDispatch method + * + * @access public + * @return void + */ + function testDispatch() { + $Dispatcher =& new TestShellDispatcher(array('sample')); + $this->assertPattern('/This is the main method called from SampleShell/', $Dispatcher->stdout); + $Dispatcher =& new TestShellDispatcher(array('test_plugin_two.example')); + $this->assertPattern('/This is the main method called from TestPluginTwo.ExampleShell/', $Dispatcher->stdout); + + $Dispatcher =& new TestShellDispatcher(array('test_plugin_two.welcome', 'say_hello')); + $this->assertPattern('/This is the say_hello method called from TestPluginTwo.WelcomeShell/', $Dispatcher->stdout); + } +/** + * testHelpCommand method + * + * @access public + * @return void + */ + function testHelpCommand() { + $Dispatcher =& new TestShellDispatcher(); + + $expected = "/ ROOT(\\\|\/)cake(\\\|\/)tests(\\\|\/)test_app(\\\|\/)plugins(\\\|\/)test_plugin(\\\|\/)vendors(\\\|\/)shells:"; + $expected .= "\n\t example"; + $expected .= "\n/"; + $this->assertPattern($expected, $Dispatcher->stdout); + + $expected = "/ ROOT(\\\|\/)cake(\\\|\/)tests(\\\|\/)test_app(\\\|\/)plugins(\\\|\/)test_plugin_two(\\\|\/)vendors(\\\|\/)shells:"; + $expected .= "\n\t example"; + $expected .= "\n\t welcome"; + $expected .= "\n/"; + $this->assertPattern($expected, $Dispatcher->stdout); + + $expected = "/ ROOT(\\\|\/)app(\\\|\/)vendors(\\\|\/)shells:"; + $expected .= "\n\t - none"; + $expected .= "\n/"; + $this->assertPattern($expected, $Dispatcher->stdout); + + $expected = "/ ROOT(\\\|\/)vendors(\\\|\/)shells:"; + $expected .= "\n\t - none"; + $expected .= "\n/"; + $this->assertPattern($expected, $Dispatcher->stdout); + + $expected = "/ ROOT(\\\|\/)cake(\\\|\/)console(\\\|\/)libs:"; + $expected .= "\n\t acl"; + $expected .= "\n\t api"; + $expected .= "\n\t bake"; + $expected .= "\n\t console"; + $expected .= "\n\t i18n"; + $expected .= "\n\t schema"; + $expected .= "\n\t testsuite"; + $expected .= "\n/"; + $this->assertPattern($expected, $Dispatcher->stdout); + + $expected = "/ ROOT(\\\|\/)cake(\\\|\/)tests(\\\|\/)test_app(\\\|\/)vendors(\\\|\/)shells:"; + $expected .= "\n\t sample"; + $expected .= "\n/"; + $this->assertPattern($expected, $Dispatcher->stdout); } } ?> \ No newline at end of file diff --git a/cake/tests/test_app/plugins/test_plugin/vendors/shells/example.php b/cake/tests/test_app/plugins/test_plugin/vendors/shells/example.php new file mode 100644 index 000000000..de1bb8f66 --- /dev/null +++ b/cake/tests/test_app/plugins/test_plugin/vendors/shells/example.php @@ -0,0 +1,37 @@ + + * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org) + * + * Licensed under The Open Group Test Suite License + * Redistributions of files must retain the above copyright notice. + * + * @filesource + * @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org) + * @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests + * @package cake.tests + * @subpackage cake.tests.test_app.plugins.test_plugin.vendors.shells + * @since CakePHP(tm) v 1.2.0.7871 + * @version $Revision$ + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License + */ +class ExampleShell extends Shell { +/** + * main method + * + * @access public + * @return void + */ + function main() { + $this->out('This is the main method called from TestPlugin.ExampleShell'); + } +} \ No newline at end of file diff --git a/cake/tests/test_app/plugins/test_plugin/vendors/shells/tasks/empty b/cake/tests/test_app/plugins/test_plugin/vendors/shells/tasks/empty new file mode 100644 index 000000000..e69de29bb diff --git a/cake/tests/test_app/plugins/test_plugin/vendors/shells/templates/empty b/cake/tests/test_app/plugins/test_plugin/vendors/shells/templates/empty new file mode 100644 index 000000000..e69de29bb diff --git a/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/example.php b/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/example.php new file mode 100644 index 000000000..9f590db93 --- /dev/null +++ b/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/example.php @@ -0,0 +1,37 @@ + + * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org) + * + * Licensed under The Open Group Test Suite License + * Redistributions of files must retain the above copyright notice. + * + * @filesource + * @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org) + * @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests + * @package cake.tests + * @subpackage cake.tests.test_app.plugins.test_plugin_two.vendors.shells + * @since CakePHP(tm) v 1.2.0.7871 + * @version $Revision$ + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License + */ +class ExampleShell extends Shell { +/** + * main method + * + * @access public + * @return void + */ + function main() { + $this->out('This is the main method called from TestPluginTwo.ExampleShell'); + } +} \ No newline at end of file diff --git a/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/tasks/empty b/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/tasks/empty new file mode 100644 index 000000000..e69de29bb diff --git a/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/templates/empty b/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/templates/empty new file mode 100644 index 000000000..e69de29bb diff --git a/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/welcome.php b/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/welcome.php new file mode 100644 index 000000000..8bcb0e63a --- /dev/null +++ b/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/welcome.php @@ -0,0 +1,37 @@ + + * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org) + * + * Licensed under The Open Group Test Suite License + * Redistributions of files must retain the above copyright notice. + * + * @filesource + * @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org) + * @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests + * @package cake.tests + * @subpackage cake.tests.test_app.plugins.test_plugin_two.vendors.shells + * @since CakePHP(tm) v 1.2.0.7871 + * @version $Revision$ + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License + */ +class WelcomeShell extends Shell { +/** + * say_hello method + * + * @access public + * @return void + */ + function say_hello() { + $this->out('This is the say_hello method called from TestPluginTwo.WelcomeShell'); + } +} \ No newline at end of file diff --git a/cake/tests/test_app/vendors/shells/sample.php b/cake/tests/test_app/vendors/shells/sample.php new file mode 100644 index 000000000..7c115fa92 --- /dev/null +++ b/cake/tests/test_app/vendors/shells/sample.php @@ -0,0 +1,37 @@ + + * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org) + * + * Licensed under The Open Group Test Suite License + * Redistributions of files must retain the above copyright notice. + * + * @filesource + * @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org) + * @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests + * @package cake.tests + * @subpackage cake.tests.test_app.vendors.shells + * @since CakePHP(tm) v 1.2.0.7871 + * @version $Revision$ + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License + */ +class SampleShell extends Shell { +/** + * main method + * + * @access public + * @return void + */ + function main() { + $this->out('This is the main method called from SampleShell'); + } +} \ No newline at end of file