Browse Source

Merge pull request #3732 from cakephp/3.0-plugin-bake

3.0 plugin bake
José Lorenzo Rodríguez 11 years ago
parent
commit
d45d4a1235

+ 41 - 1
src/Console/Command/Task/BakeTask.php

@@ -81,7 +81,7 @@ class BakeTask extends Shell {
 	public function getPath() {
 		$path = APP . $this->pathFragment;
 		if (isset($this->plugin)) {
-			$path = $this->_pluginPath($this->plugin) . $this->pathFragment;
+			$path = $this->_pluginPath($this->plugin) . 'src/' . $this->pathFragment;
 		}
 		return str_replace('/', DS, $path);
 	}
@@ -102,6 +102,46 @@ class BakeTask extends Shell {
 	}
 
 /**
+ * Executes an external shell command and pipes its output to the stdout
+ *
+ * @param string $command the command to execute
+ * @return void
+ * @throws \RuntimeException if any errors occurred during the execution
+ */
+	public function callProcess($command) {
+		$descriptorSpec = [
+			0 => ['pipe', 'r'],
+			1 => ['pipe', 'w'],
+			2 => ['pipe', 'w']
+		];
+		$this->_io->verbose('Running ' . $command);
+		$process = proc_open(
+			$command,
+			$descriptorSpec,
+			$pipes
+		);
+		if (!is_resource($process)) {
+			$this->error(__d('cake_console', 'Could not start subprocess.'));
+			return false;
+		}
+		$output = $error = '';
+		fclose($pipes[0]);
+
+		$output = stream_get_contents($pipes[1]);
+		fclose($pipes[1]);
+
+		$error = stream_get_contents($pipes[2]);
+		fclose($pipes[2]);
+		proc_close($process);
+
+		if ($error) {
+			throw new \RuntimeException($error);
+		}
+
+		$this->out($output);
+	}
+
+/**
  * Handles splitting up the plugin prefix and classname.
  *
  * Sets the plugin parameter and plugin property.

+ 1 - 1
src/Console/Command/Task/FixtureTask.php

@@ -45,7 +45,7 @@ class FixtureTask extends BakeTask {
 		$dir = 'Test/Fixture/';
 		$path = ROOT . DS . $dir;
 		if (isset($this->plugin)) {
-			$path = $this->_pluginPath($this->plugin) . $dir;
+			$path = $this->_pluginPath($this->plugin) . 'tests/Fixture/';
 		}
 		return str_replace('/', DS, $path);
 	}

+ 60 - 5
src/Console/Command/Task/PluginTask.php

@@ -39,7 +39,7 @@ class PluginTask extends BakeTask {
  *
  * @var array
  */
-	public $tasks = ['Template'];
+	public $tasks = ['Template', 'Project'];
 
 /**
  * initialize
@@ -139,9 +139,10 @@ class PluginTask extends BakeTask {
 			$out .= "use App\\Controller\\AppController as BaseController;\n\n";
 			$out .= "class AppController extends BaseController {\n\n";
 			$out .= "}\n";
-			$this->createFile($this->path . $plugin . DS . 'Controller' . DS . $controllerFileName, $out);
+			$this->createFile($this->path . $plugin . DS . $classBase . DS . 'Controller' . DS . $controllerFileName, $out);
 
-			$this->_modifyBootstrap($plugin);
+			$hasAutoloader = $this->_modifyAutoloader($plugin, $this->path);
+			$this->_modifyBootstrap($plugin, $hasAutoloader);
 			$this->_generatePhpunitXml($plugin, $this->path);
 			$this->_generateTestBootstrap($plugin, $this->path);
 
@@ -156,13 +157,20 @@ class PluginTask extends BakeTask {
  * Update the app's bootstrap.php file.
  *
  * @param string $plugin Name of plugin
+ * @param boolean $hasAutoloader Whether or not there is an autoloader configured for
+ * the plugin
  * @return void
  */
-	protected function _modifyBootstrap($plugin) {
+	protected function _modifyBootstrap($plugin, $hasAutoloader) {
 		$bootstrap = new File($this->bootstrap, false);
 		$contents = $bootstrap->read();
 		if (!preg_match("@\n\s*Plugin::loadAll@", $contents)) {
-			$bootstrap->append("\nPlugin::load('$plugin', ['bootstrap' => false, 'routes' => false]);\n");
+			$autoload = $hasAutoloader ? null : "'autoload' => true, ";
+			$bootstrap->append(sprintf(
+				"\nPlugin::load('%s', [%s'bootstrap' => false, 'routes' => false]);\n",
+				$plugin,
+				$autoload
+			));
 			$this->out('');
 			$this->out(sprintf('%s modified', $this->bootstrap));
 		}
@@ -206,6 +214,53 @@ class PluginTask extends BakeTask {
 	}
 
 /**
+ * Modifies App's composer.json to include the plugin and tries to call
+ * composer dump-autoload to refresh the autoloader cache
+ *
+ * @param string $plugin Name of plugin
+ * @param string $path The path to save the phpunit.xml file to.
+ * @return boolean True if composer could be modified correctly
+ */
+	protected function _modifyAutoloader($plugin, $path) {
+		$path = dirname($path);
+
+		if (!file_exists($path . DS . 'composer.json')) {
+			return false;
+		}
+
+		$file = $path . DS . 'composer.json';
+		$config = json_decode(file_get_contents($file), true);
+		$config['autoload']['psr-4'][$plugin . '\\'] = "./Plugin/$plugin/src";
+		$config['autoload']['psr-4'][$plugin . '\\Test\\'] = "./Plugin/$plugin/tests";
+
+		$this->out(__d('cake_console', '<info>Modifying composer autoloader</info>'));
+
+		file_put_contents(
+			$file,
+			json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
+		);
+
+		$composer = $this->Project->findComposer();
+
+		if (!$composer) {
+			$this->error(__d('cake_console', 'Could not locate composer, Add composer to your PATH, or use the -composer option.'));
+			return false;
+		}
+
+		try {
+			$command = 'cd ' . escapeshellarg($path) . '; ';
+			$command .= 'php ' . escapeshellarg($composer) . ' dump-autoload ';
+			$this->callProcess($command);
+		} catch (\RuntimeException $e) {
+			$error = $e->getMessage();
+			$this->error(__d('cake_console', 'Could not run `composer dump-autoload`: %s', $error));
+			return false;
+		}
+
+		return true;
+	}
+
+/**
  * find and change $this->path to the user selection
  *
  * @param array $pathOptions The list of paths to look in.

+ 5 - 27
src/Console/Command/Task/ProjectTask.php

@@ -146,36 +146,14 @@ class ProjectTask extends BakeTask {
 
 		$command = 'php ' . escapeshellarg($composer) . ' create-project -s dev cakephp/app ' . escapeshellarg($path);
 
-		$descriptorSpec = [
-			0 => ['pipe', 'r'],
-			1 => ['pipe', 'w'],
-			2 => ['pipe', 'w']
-		];
-		$this->_io->verbose('Running ' . $command);
-		$process = proc_open(
-			$command,
-			$descriptorSpec,
-			$pipes
-		);
-		if (!is_resource($process)) {
-			$this->error(__d('cake_console', 'Could not start subprocess.'));
-			return false;
-		}
-		$output = $error = '';
-		fclose($pipes[0]);
-
-		$output = stream_get_contents($pipes[1]);
-		fclose($pipes[1]);
-
-		$error = stream_get_contents($pipes[2]);
-		fclose($pipes[2]);
-		proc_close($process);
-
-		if ($error) {
+		try {
+			$this->callProcess($command);
+		} catch (\RuntimeException $e) {
+			$error = $e->getMessage();
 			$this->error(__d('cake_console', 'Installation from packagist.org failed with: %s', $error));
 			return false;
 		}
-		$this->out($output);
+
 		return true;
 	}
 

+ 1 - 1
src/Console/Command/Task/TemplateTask.php

@@ -59,7 +59,7 @@ class TemplateTask extends Shell {
 
 		$plugins = App::objects('Plugin');
 		foreach ($plugins as $plugin) {
-			$paths[] = $this->_pluginPath($plugin) . 'Console/';
+			$paths[] = $this->_pluginPath($plugin) . 'src/Console/';
 		}
 
 		$core = current(App::core('Console'));

+ 1 - 1
src/Console/Command/Task/TestTask.php

@@ -466,7 +466,7 @@ class TestTask extends BakeTask {
 		$dir = 'Test/TestCase/';
 		$path = ROOT . DS . $dir;
 		if (isset($this->plugin)) {
-			$path = $this->_pluginPath($this->plugin) . $dir;
+			$path = $this->_pluginPath($this->plugin) . 'tests/TestCase/';
 		}
 		return $path;
 	}

+ 4 - 4
tests/TestCase/Console/Command/Task/CellTaskTest.php

@@ -85,13 +85,13 @@ class CellTaskTest extends TestCase {
 		$this->Task->expects($this->at(0))
 			->method('createFile')
 			->with(
-				$this->_normalizePath($path . 'Template/Cell/Example/display.ctp'),
+				$this->_normalizePath($path . 'src/Template/Cell/Example/display.ctp'),
 				''
 			);
 		$this->Task->expects($this->at(1))
 			->method('createFile')
 			->with(
-				$this->_normalizePath($path . 'View/Cell/ExampleCell.php'),
+				$this->_normalizePath($path . 'src/View/Cell/ExampleCell.php'),
 				$this->stringContains('class ExampleCell extends Cell')
 			);
 
@@ -112,13 +112,13 @@ class CellTaskTest extends TestCase {
 		$this->Task->expects($this->at(0))
 			->method('createFile')
 			->with(
-				$this->_normalizePath($path . 'Template/Cell/Example/display.ctp'),
+				$this->_normalizePath($path . 'src/Template/Cell/Example/display.ctp'),
 				''
 			);
 		$this->Task->expects($this->at(1))
 			->method('createFile')
 			->with(
-				$this->_normalizePath($path . 'View/Cell/ExampleCell.php'),
+				$this->_normalizePath($path . 'src/View/Cell/ExampleCell.php'),
 				$this->stringContains('class ExampleCell extends Cell')
 			);
 

+ 2 - 2
tests/TestCase/Console/Command/Task/ControllerTaskTest.php

@@ -214,7 +214,7 @@ class ControllerTaskTest extends TestCase {
 		$this->Task->plugin = 'ControllerTest';
 
 		Plugin::load('ControllerTest', array('path' => APP . 'Plugin/ControllerTest/'));
-		$path = APP . 'Plugin/ControllerTest/Controller/BakeArticlesController.php';
+		$path = APP . 'Plugin/ControllerTest/src/Controller/BakeArticlesController.php';
 
 		$this->Task->expects($this->at(1))
 			->method('createFile')
@@ -354,7 +354,7 @@ class ControllerTaskTest extends TestCase {
 		$this->Task->connection = 'test';
 
 		Plugin::load('ControllerTest', array('path' => APP . 'Plugin/ControllerTest/'));
-		$path = APP . 'Plugin/ControllerTest/Controller/BakeArticlesController.php';
+		$path = APP . 'Plugin/ControllerTest/src/Controller/BakeArticlesController.php';
 
 		$this->Task->expects($this->at(1))
 			->method('createFile')

+ 2 - 2
tests/TestCase/Console/Command/Task/FixtureTaskTest.php

@@ -225,7 +225,7 @@ class FixtureTaskTest extends TestCase {
  */
 	public function testMainWithPluginModel() {
 		$this->Task->connection = 'test';
-		$filename = $this->_normalizePath(TEST_APP . 'Plugin/TestPlugin/Test/Fixture/ArticleFixture.php');
+		$filename = $this->_normalizePath(TEST_APP . 'Plugin/TestPlugin/tests/Fixture/ArticleFixture.php');
 
 		Plugin::load('TestPlugin');
 
@@ -407,7 +407,7 @@ class FixtureTaskTest extends TestCase {
 	public function testGeneratePluginFixtureFile() {
 		$this->Task->connection = 'test';
 		$this->Task->plugin = 'TestPlugin';
-		$filename = $this->_normalizePath(TEST_APP . 'Plugin/TestPlugin/Test/Fixture/ArticleFixture.php');
+		$filename = $this->_normalizePath(TEST_APP . 'Plugin/TestPlugin/tests/Fixture/ArticleFixture.php');
 
 		Plugin::load('TestPlugin');
 		$this->Task->expects($this->at(0))->method('createFile')

+ 2 - 2
tests/TestCase/Console/Command/Task/ModelTaskTest.php

@@ -823,7 +823,7 @@ class ModelTaskTest extends TestCase {
 
 		// fake plugin path
 		Plugin::load('ControllerTest', array('path' => APP . 'Plugin' . DS . 'ControllerTest' . DS));
-		$path = $this->_normalizePath(APP . 'Plugin/ControllerTest/Model/Table/BakeArticlesTable.php');
+		$path = $this->_normalizePath(APP . 'Plugin/ControllerTest/src/Model/Table/BakeArticlesTable.php');
 		$this->Task->expects($this->once())->method('createFile')
 			->with($path, $this->logicalAnd(
 				$this->stringContains('namespace ControllerTest\\Model\\Table;'),
@@ -845,7 +845,7 @@ class ModelTaskTest extends TestCase {
 
 		// fake plugin path
 		Plugin::load('ControllerTest', array('path' => APP . 'Plugin' . DS . 'ControllerTest' . DS));
-		$path = APP . 'Plugin' . DS . 'ControllerTest' . DS . 'Model' . DS . 'Entity' . DS . 'BakeArticle.php';
+		$path = APP . 'Plugin' . DS . 'ControllerTest' . DS . 'src' . DS . 'Model' . DS . 'Entity' . DS . 'BakeArticle.php';
 		$path = $this->_normalizePath($path);
 		$this->Task->expects($this->once())->method('createFile')
 			->with($path, $this->logicalAnd(

+ 2 - 2
tests/TestCase/Console/Command/Task/PluginTaskTest.php

@@ -75,7 +75,7 @@ class PluginTaskTest extends TestCase {
 
 		$path = $this->Task->path . 'BakeTestPlugin';
 
-		$file = $path . DS . 'Controller' . DS . 'AppController.php';
+		$file = $path . DS . 'src' . DS . 'Controller' . DS . 'AppController.php';
 		$this->Task->expects($this->at(1))->method('createFile')
 			->with($file, $this->stringContains('namespace BakeTestPlugin\Controller;'));
 
@@ -140,7 +140,7 @@ class PluginTaskTest extends TestCase {
 			->will($this->returnValue('y'));
 
 		$path = $this->Task->path . 'BakeTestPlugin';
-		$file = $path . DS . 'Controller' . DS . 'AppController.php';
+		$file = $path . DS . 'src' . DS . 'Controller' . DS . 'AppController.php';
 		$this->Task->expects($this->at(1))->method('createFile')
 			->with($file, $this->stringContains('class AppController extends BaseController {'));
 

+ 2 - 2
tests/TestCase/Console/Command/Task/SimpleBakeTaskTest.php

@@ -87,7 +87,7 @@ class SimpleBakeTaskTest extends TestCase {
  */
 	public function testMainWithPlugin() {
 		Plugin::load('TestPlugin');
-		$filename = $this->_normalizePath(TEST_APP . 'Plugin/TestPlugin/Model/Behavior/ExampleBehavior.php');
+		$filename = $this->_normalizePath(TEST_APP . 'Plugin/TestPlugin/src/Model/Behavior/ExampleBehavior.php');
 		$this->Task->expects($this->once())
 			->method('createFile')
 			->with(
@@ -164,7 +164,7 @@ class SimpleBakeTaskTest extends TestCase {
 		$this->Task->expects($this->once())
 			->method('createFile')
 			->with(
-				$this->_normalizePath($path . 'Model/Behavior/ExampleBehavior.php'),
+				$this->_normalizePath($path . 'src/Model/Behavior/ExampleBehavior.php'),
 				$this->stringContains('class ExampleBehavior extends Behavior')
 			);
 

+ 2 - 2
tests/TestCase/Console/Command/Task/TestTaskTest.php

@@ -587,7 +587,7 @@ class TestTaskTest extends TestCase {
 		$this->Task->plugin = 'TestPlugin';
 
 		Plugin::load('TestPlugin');
-		$path = TEST_APP . 'Plugin/TestPlugin/Test/TestCase/View/Helper/FormHelperTest.php';
+		$path = TEST_APP . 'Plugin/TestPlugin/tests/TestCase/View/Helper/FormHelperTest.php';
 		$path = str_replace('/', DS, $path);
 		$this->Task->expects($this->once())->method('createFile')
 			->with($path, $this->anything());
@@ -645,7 +645,7 @@ class TestTaskTest extends TestCase {
 		$class = 'TestPlugin\Model\Entity\Post';
 		$result = $this->Task->testCaseFileName('entity', $class);
 
-		$expected = TEST_APP . 'Plugin/TestPlugin/Test/TestCase/Model/Entity/PostTest.php';
+		$expected = TEST_APP . 'Plugin/TestPlugin/tests/TestCase/Model/Entity/PostTest.php';
 		$this->assertPathEquals($expected, $result);
 	}
 

+ 3 - 3
tests/TestCase/Console/Command/Task/ViewTaskTest.php

@@ -248,11 +248,11 @@ class ViewTaskTest extends TestCase {
 
 		$this->Task->params['plugin'] = $this->Task->plugin = 'TestPlugin';
 		$result = $this->Task->getPath();
-		$this->assertPathEquals($pluginPath . 'Template/Posts/', $result);
+		$this->assertPathEquals($pluginPath . 'src/Template/Posts/', $result);
 
 		$this->Task->params['prefix'] = 'admin';
 		$result = $this->Task->getPath();
-		$this->assertPathEquals($pluginPath . 'Template/Admin/Posts/', $result);
+		$this->assertPathEquals($pluginPath . 'src/Template/Admin/Posts/', $result);
 
 		Plugin::unload('TestPlugin');
 	}
@@ -547,7 +547,7 @@ class ViewTaskTest extends TestCase {
 		$this->_setupTask(['in', 'err', 'createFile']);
 
 		$this->Task->connection = 'test';
-		$filename = $this->_normalizePath(TEST_APP . 'Plugin/TestPlugin/Template/ViewTaskComments/index.ctp');
+		$filename = $this->_normalizePath(TEST_APP . 'Plugin/TestPlugin/src/Template/ViewTaskComments/index.ctp');
 
 		Plugin::load('TestPlugin');