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
This commit is contained in:
renan.saddam 2008-11-13 00:33:53 +00:00
parent a194f6a25e
commit 64c3d1ef95
10 changed files with 363 additions and 43 deletions

View file

@ -126,8 +126,9 @@ class ShellDispatcher {
set_time_limit(0); set_time_limit(0);
$this->__initConstants(); $this->__initConstants();
$this->parseParams($args); $this->parseParams($args);
$this->__initEnvironment(); $this->_initEnvironment();
exit($this->dispatch()); $this->__buildPaths();
$this->_stop($this->dispatch());
} }
/** /**
* Defines core configuration. * Defines core configuration.
@ -156,9 +157,9 @@ class ShellDispatcher {
/** /**
* Defines current working environment. * Defines current working environment.
* *
* @access private * @access protected
*/ */
function __initEnvironment() { function _initEnvironment() {
$this->stdin = fopen('php://stdin', 'r'); $this->stdin = fopen('php://stdin', 'r');
$this->stdout = fopen('php://stdout', 'w'); $this->stdout = fopen('php://stdout', 'w');
$this->stderr = fopen('php://stderr', 'w'); $this->stderr = fopen('php://stderr', 'w');
@ -167,7 +168,7 @@ class ShellDispatcher {
$this->stderr("\nCakePHP Console: "); $this->stderr("\nCakePHP Console: ");
$this->stderr("\nUnable to load Cake core:"); $this->stderr("\nUnable to load Cake core:");
$this->stderr("\tMake sure " . DS . 'cake' . DS . 'libs exists in ' . CAKE_CORE_INCLUDE_PATH); $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'])) { 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('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('and check the manual for the correct usage of this command.');
$this->stderr('(http://manual.cakephp.org/)'); $this->stderr('(http://manual.cakephp.org/)');
exit(); $this->_stop();
} }
if (basename(__FILE__) != basename($this->args[0])) { if (basename(__FILE__) != basename($this->args[0])) {
$this->stderr("\nCakePHP Console: "); $this->stderr("\nCakePHP Console: ");
$this->stderr('Warning: the dispatcher may have been loaded incorrectly, which could lead to unexpected results...'); $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') { if ($this->getInput('Continue anyway?', array('y', 'n'), 'y') == 'n') {
exit(); $this->_stop();
} }
} }
$this->shiftArgs(); $this->shiftArgs();
}
/**
* Builds the shell paths.
*
* @access private
* @return void
*/
function __buildPaths() {
$paths = array(); $paths = array();
$pluginPaths = Configure::read('pluginPaths'); $pluginPaths = Configure::read('pluginPaths');
foreach ($pluginPaths as $pluginPath) { foreach ($pluginPaths as $pluginPath) {
$plugins = Configure::listObjects('plugin', $pluginPath); $plugins = Configure::listObjects('plugin', $pluginPath);
foreach ((array)$plugins as $plugin) { 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)) { if (file_exists($path)) {
$paths[] = $path; $paths[] = $path;
} }
@ -273,14 +281,15 @@ class ShellDispatcher {
$this->shellName = Inflector::camelize($this->shell); $this->shellName = Inflector::camelize($this->shell);
$this->shellClass = $this->shellName . 'Shell'; $this->shellClass = $this->shellName . 'Shell';
if ($this->shell == 'help') { if ($this->shell === 'help') {
$this->help(); $this->help();
} else { } else {
$loaded = false; $loaded = false;
foreach ($this->shellPaths as $path) { foreach ($this->shellPaths as $path) {
$this->shellPath = $path . $this->shell . ".php"; $this->shellPath = $path . $this->shell . '.php';
if (file_exists($this->shellPath)) {
$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; $loaded = true;
break; break;
} }
@ -317,7 +326,7 @@ class ShellDispatcher {
if (isset($this->args[0]) && $this->args[0] == 'help') { if (isset($this->args[0]) && $this->args[0] == 'help') {
if (method_exists($shell->{$task}, 'help')) { if (method_exists($shell->{$task}, 'help')) {
$shell->{$task}->help(); $shell->{$task}->help();
exit(); $this->_stop();
} else { } else {
$this->help(); $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']); $params['root'] = dirname($params['app']);
} elseif (strpos($params['app'], '/')) { } elseif (strpos($params['app'], '/')) {
$params['root'] .= '/' . dirname($params['app']); $params['root'] .= '/' . dirname($params['app']);
@ -536,18 +545,16 @@ class ShellDispatcher {
foreach ($this->shellPaths as $path) { foreach ($this->shellPaths as $path) {
if (is_dir($path)) { if (is_dir($path)) {
$shells = Configure::listObjects('file', $path); $shells = Configure::listObjects('file', $path);
$path = r(CORE_PATH, 'CORE/', $path); $path = str_replace(CORE_PATH, 'CORE/', $path);
$path = r(ROOT, 'ROOT', $path); $path = str_replace(ROOT, 'ROOT', $path);
$this->stdout("\n " . rtrim($path, DS) . ":"); $path = rtrim($path, DS);
$this->stdout("\n " . $path . ":");
if (empty($shells)) { if (empty($shells)) {
$this->stdout("\t - none"); $this->stdout("\t - none");
} else { } else {
foreach ($shells as $shell) { foreach ($shells as $shell) {
if ($shell != 'shell.php') { if ($shell !== 'shell.php') {
if (!isset($_shells[$shell])) { $this->stdout("\t " . str_replace('.php', '', $shell));
$this->stdout("\t " . r('.php', '', $shell));
}
$_shells[$shell] = rtrim($path, DS);
} }
} }
} }
@ -555,7 +562,17 @@ class ShellDispatcher {
} }
$this->stdout("\nTo run a command, type 'cake shell_name [args]'"); $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'"); $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')) { if (!defined('DISABLE_AUTO_DISPATCH')) {

View file

@ -49,16 +49,65 @@ class TestShellDispatcher extends ShellDispatcher {
*/ */
var $params = array(); var $params = array();
/** /**
* construct method * stdout property
* *
* @param array $args * @var string
* @access private * @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 * @return void
*/ */
function __construct($args = array()) { function _initEnvironment() {
set_time_limit(0); //
$this->__initConstants(); }
$this->parseParams($args); /**
* 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 * @subpackage cake.tests.cases.libs
*/ */
class ShellDispatcherTest extends UnitTestCase { 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 * testParseParams method
* *
@ -99,8 +176,8 @@ class ShellDispatcherTest extends UnitTestCase {
$expected = array( $expected = array(
'app' => 'app', 'app' => 'app',
'webroot' => 'webroot', 'webroot' => 'webroot',
'working' => CAKE_CORE_INCLUDE_PATH . DS . 'app', 'working' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH . DS . 'app'),
'root' => CAKE_CORE_INCLUDE_PATH, 'root' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH),
); );
$Dispatcher->params = $Dispatcher->args = array(); $Dispatcher->params = $Dispatcher->args = array();
$Dispatcher->parseParams($params); $Dispatcher->parseParams($params);
@ -115,8 +192,8 @@ class ShellDispatcherTest extends UnitTestCase {
$expected = array( $expected = array(
'app' => 'new', 'app' => 'new',
'webroot' => 'webroot', 'webroot' => 'webroot',
'working' => CAKE_CORE_INCLUDE_PATH . DS . 'new', 'working' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH . DS . 'new'),
'root' => CAKE_CORE_INCLUDE_PATH 'root' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH)
); );
$Dispatcher->params = $Dispatcher->args = array(); $Dispatcher->params = $Dispatcher->args = array();
$Dispatcher->parseParams($params); $Dispatcher->parseParams($params);
@ -135,8 +212,8 @@ class ShellDispatcherTest extends UnitTestCase {
$expected = array( $expected = array(
'app' => 'new', 'app' => 'new',
'webroot' => 'webroot', 'webroot' => 'webroot',
'working' => CAKE_CORE_INCLUDE_PATH . DS . 'new', 'working' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH . DS . 'new'),
'root' => CAKE_CORE_INCLUDE_PATH 'root' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH)
); );
$Dispatcher->params = $Dispatcher->args = array(); $Dispatcher->params = $Dispatcher->args = array();
@ -155,8 +232,8 @@ class ShellDispatcherTest extends UnitTestCase {
$expected = array( $expected = array(
'app' => 'new', 'app' => 'new',
'webroot' => 'webroot', 'webroot' => 'webroot',
'working' => CAKE_CORE_INCLUDE_PATH . DS . 'new', 'working' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH . DS . 'new'),
'root' => CAKE_CORE_INCLUDE_PATH 'root' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH)
); );
$Dispatcher->params = $Dispatcher->args = array(); $Dispatcher->params = $Dispatcher->args = array();
$Dispatcher->parseParams($params); $Dispatcher->parseParams($params);
@ -175,8 +252,8 @@ class ShellDispatcherTest extends UnitTestCase {
$expected = array( $expected = array(
'app' => 'new', 'app' => 'new',
'webroot' => 'webroot', 'webroot' => 'webroot',
'working' => CAKE_CORE_INCLUDE_PATH . DS . 'new', 'working' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH . DS . 'new'),
'root' => CAKE_CORE_INCLUDE_PATH, 'root' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH),
'dry' => 1 'dry' => 1
); );
$Dispatcher->params = $Dispatcher->args = array(); $Dispatcher->params = $Dispatcher->args = array();
@ -199,8 +276,8 @@ class ShellDispatcherTest extends UnitTestCase {
$expected = array( $expected = array(
'app' => 'app', 'app' => 'app',
'webroot' => 'webroot', 'webroot' => 'webroot',
'working' => CAKE_CORE_INCLUDE_PATH . DS . 'app', 'working' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH . DS . 'app'),
'root' => CAKE_CORE_INCLUDE_PATH, 'root' => str_replace('\\', '/', CAKE_CORE_INCLUDE_PATH),
'dry' => 1, 'dry' => 1,
'f' => 1, 'f' => 1,
'name' => 'DbAcl' 'name' => 'DbAcl'
@ -320,7 +397,85 @@ class ShellDispatcherTest extends UnitTestCase {
$Dispatcher->params = $Dispatcher->args = array(); $Dispatcher->params = $Dispatcher->args = array();
$Dispatcher->parseParams($params); $Dispatcher->parseParams($params);
$this->assertEqual($expected, $Dispatcher->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);
} }
} }
?> ?>

View file

@ -0,0 +1,37 @@
<?php
/* SVN FILE: $Id$ */
/**
* Short description for file.
*
* Long description for file
*
* PHP versions 4 and 5
*
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
* 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');
}
}

View file

@ -0,0 +1,37 @@
<?php
/* SVN FILE: $Id$ */
/**
* Short description for file.
*
* Long description for file
*
* PHP versions 4 and 5
*
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
* 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');
}
}

View file

@ -0,0 +1,37 @@
<?php
/* SVN FILE: $Id$ */
/**
* Short description for file.
*
* Long description for file
*
* PHP versions 4 and 5
*
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
* 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');
}
}

View file

@ -0,0 +1,37 @@
<?php
/* SVN FILE: $Id$ */
/**
* Short description for file.
*
* Long description for file
*
* PHP versions 4 and 5
*
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
* 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');
}
}