From 451267631bb40671147e1ef2c3f1638d030b92d2 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 29 Aug 2013 15:41:37 -0400 Subject: [PATCH] First pass at making ProjectTask wrap and proxy to composer. Instead of using the skel dir that no longer exists, composer should be used instead. --- lib/Cake/Console/Command/Task/ProjectTask.php | 134 +++-------- .../Console/Command/Task/ProjectTaskTest.php | 226 +----------------- 2 files changed, 39 insertions(+), 321 deletions(-) diff --git a/lib/Cake/Console/Command/Task/ProjectTask.php b/lib/Cake/Console/Command/Task/ProjectTask.php index 37053d687d1..dffb6b67568 100644 --- a/lib/Cake/Console/Command/Task/ProjectTask.php +++ b/lib/Cake/Console/Command/Task/ProjectTask.php @@ -80,50 +80,14 @@ public function execute() { } } + if ($project === false) { + $this->out(__d('cake_console', 'Aborting project creation.')); + return; + } + $success = true; if ($this->bake($project)) { $path = Folder::slashTerm($project); - - if ($this->appNamespace($path) === true) { - $this->out(__d('cake_console', ' * Namespace set for \'App.namespace\' and namespace declarations')); - } else { - $this->err(__d('cake_console', 'The namespace was NOT set')); - $success = false; - } - - if ($this->securitySalt($path) === true) { - $this->out(__d('cake_console', ' * Random hash key created for \'Security.salt\'')); - } else { - $this->err(__d('cake_console', 'Unable to generate random hash for \'Security.salt\', you should change it in %s', APP . 'Config' . DS . 'app.php')); - $success = false; - } - - if ($this->cachePrefix($path)) { - $this->out(__d('cake_console', ' * Cache prefix set')); - } else { - $this->err(__d('cake_console', 'The cache prefix was NOT set')); - $success = false; - } - - $hardCode = false; - if ($this->cakeOnIncludePath()) { - $this->out(__d('cake_console', 'CakePHP is on your `include_path`. CAKE_CORE_INCLUDE_PATH will be set, but commented out.')); - } else { - $this->out(__d('cake_console', 'CakePHP is not on your `include_path`, CAKE_CORE_INCLUDE_PATH will be hard coded.')); - $this->out(__d('cake_console', 'You can fix this by adding CakePHP to your `include_path`.')); - $hardCode = true; - } - $success = $this->corePath($path, $hardCode) === true; - if ($success) { - $this->out(__d('cake_console', ' * CAKE_CORE_INCLUDE_PATH set to %s in %s', CAKE_CORE_INCLUDE_PATH, 'Config/paths.php')); - } else { - $this->err(__d('cake_console', 'Unable to set CAKE_CORE_INCLUDE_PATH, you should change it in %s', $path . 'Config' . DS . 'paths.php')); - $success = false; - } - if ($success && $hardCode) { - $this->out(__d('cake_console', ' * Remember to check these values after moving to production server')); - } - $Folder = new Folder($path); if (!$Folder->chmod($path . 'tmp', 0777)) { $this->err(__d('cake_console', 'Could not set permissions on %s', $path . DS . 'tmp')); @@ -164,67 +128,45 @@ public function cakeOnIncludePath() { * @param string $skip array of directories to skip when copying * @return mixed */ - public function bake($path, $skel = null, $skip = array('empty')) { - if (!$skel && !empty($this->params['skel'])) { - $skel = $this->params['skel']; - } - while (!$skel) { - $skel = $this->in( - __d('cake_console', "What is the path to the directory layout you wish to copy?"), - null, - CAKE . 'Console' . DS . 'Templates' . DS . 'skel' - ); - if (!$skel) { - $this->err(__d('cake_console', 'The directory path you supplied was empty. Please try again.')); - } else { - while (is_dir($skel) === false) { - $skel = $this->in( - __d('cake_console', 'Directory path does not exist please choose another:'), - null, - CAKE . 'Console' . DS . 'Templates' . DS . 'skel' - ); - } - } + public function bake($path) { + $composer = APP . 'composer.phar'; + if (!file_exists($composer)) { + $this->err(__d('cake_console', 'Cannot bake project. Could not find composer at "%s".', $composer)); + return false; } + $command = 'php ' . escapeshellarg($composer) . ' create-project cakephp/cakephp-app --dev'; - $app = basename($path); - - $this->out(__d('cake_console', 'Skel Directory: ') . $skel); - $this->out(__d('cake_console', 'Will be copied to: ') . $path); - $this->out(__d('cake_console', 'With namespace: ') . $app); - $this->hr(); - - $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n', 'q'), 'y'); - - switch (strtolower($looksGood)) { - case 'y': - $Folder = new Folder($skel); - if (!empty($this->params['empty'])) { - $skip = array(); - } + $descriptorSpec = array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w') + ); + $process = proc_open( + $command, + $descriptorSpec, + $pipes + ); + if (!is_resource($process)) { + $this->err(__d('cake_console', 'Could not start subprocess.')); + return false; + } + $output = $error = ''; + fwrite($pipes[0], $input); + fclose($pipes[0]); - if ($Folder->copy(array('to' => $path, 'skip' => $skip))) { - $this->hr(); - $this->out(__d('cake_console', 'Created: %s in %s', $app, $path)); - $this->hr(); - } else { - $this->err(__d('cake_console', "Could not create '%s' properly.", $app)); - return false; - } + $output = stream_get_contents($pipes[1]); + fclose($pipes[1]); - foreach ($Folder->messages() as $message) { - $this->out(String::wrap(' * ' . $message), 1, Shell::VERBOSE); - } + $error = stream_get_contents($pipes[2]); + fclose($pipes[2]); + proc_close($process); - return true; - case 'n': - unset($this->args[0]); - $this->execute(); - return false; - case 'q': - $this->out(__d('cake_console', 'Bake Aborted.')); - return false; + if ($error) { + $this->err($error); + return false; } + $this->out($output); + return true; } /** diff --git a/lib/Cake/Test/TestCase/Console/Command/Task/ProjectTaskTest.php b/lib/Cake/Test/TestCase/Console/Command/Task/ProjectTaskTest.php index e8b0a12341b..73abbd3097c 100644 --- a/lib/Cake/Test/TestCase/Console/Command/Task/ProjectTaskTest.php +++ b/lib/Cake/Test/TestCase/Console/Command/Task/ProjectTaskTest.php @@ -63,65 +63,10 @@ public function tearDown() { * @return void */ protected function _setupTestProject() { - $skel = CAKE . 'Console/Templates/skel'; $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y')); - $this->Task->bake($this->Task->path . 'BakeTestApp', $skel); + $this->Task->bake($this->Task->path . 'BakeTestApp'); } -/** - * test bake() method and directory creation. - * - * @return void - */ - public function testBake() { - $this->_setupTestProject(); - $path = $this->Task->path . 'BakeTestApp'; - - $this->assertTrue(is_dir($path), 'No project dir %s'); - $dirs = array( - 'Config', - 'Config/Schema', - 'Console', - 'Console/Command', - 'Console/Templates', - 'Console/Command/Task', - 'Controller', - 'Controller/Component', - 'Locale', - 'Model', - 'Model/Behavior', - 'Model/Datasource', - 'Plugin', - 'Test', - 'Test/TestCase', - 'Test/TestCase/Controller', - 'Test/TestCase/Controller/Component', - 'Test/TestCase/Model', - 'Test/TestCase/Model/Behavior', - 'Test/TestCase/View', - 'Test/TestCase/View/Helper', - 'Test/Fixture', - 'vendor', - 'View', - 'View/Helper', - 'tmp', - 'tmp/cache', - 'tmp/cache/models', - 'tmp/cache/persistent', - 'tmp/cache/views', - 'tmp/logs', - 'tmp/sessions', - 'tmp/tests', - 'webroot', - 'webroot/css', - 'webroot/files', - 'webroot/img', - 'webroot/js', - ); - foreach ($dirs as $dir) { - $this->assertTrue(is_dir($path . DS . $dir), 'Missing ' . $dir); - } - } /** * test bake with an absolute path. @@ -140,148 +85,6 @@ public function testExecuteWithAbsolutePath() { $this->assertRegExp('/define\(\'CAKE_CORE_INCLUDE_PATH\', .*?DS/', $contents); } -/** - * test bake with CakePHP on the include path. The constants should remain commented out. - * - * @return void - */ - public function testExecuteWithCakeOnIncludePath() { - if (!function_exists('ini_set')) { - $this->markTestAsSkipped('Not access to ini_set, cannot proceed.'); - } - $restore = ini_get('include_path'); - ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . $restore); - - $path = $this->Task->args[0] = TMP . 'tests/BakeTestApp'; - $this->Task->params['skel'] = CAKE . 'Console/Templates/skel'; - $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y')); - $this->Task->execute(); - - $this->assertTrue(is_dir($this->Task->args[0]), 'No project dir'); - $contents = file_get_contents($path . DS . 'Config/paths.php'); - $this->assertRegExp('#//define\(\'CAKE_CORE_INCLUDE_PATH#', $contents); - - ini_set('include_path', $restore); - } - -/** - * test bake() method with -empty flag, directory creation and empty files. - * - * @return void - */ - public function testBakeEmptyFlag() { - $this->Task->params['empty'] = true; - $this->_setupTestProject(); - $path = $this->Task->path . 'BakeTestApp'; - - $empty = array( - 'Console/Command/Task' => 'empty', - 'Controller/Component' => 'empty', - 'Lib' => 'empty', - 'Model/Behavior' => 'empty', - 'Model/Datasource' => 'empty', - 'Plugin' => 'empty', - 'Test/TestCase/Model/Behavior' => 'empty', - 'Test/TestCase/Controller/Component' => 'empty', - 'Test/TestCase/View/Helper' => 'empty', - 'Test/Fixture' => 'empty', - 'vendor' => 'empty', - 'View/Elements' => 'empty', - 'View/Scaffolds' => 'empty', - 'tmp/cache/models' => 'empty', - 'tmp/cache/persistent' => 'empty', - 'tmp/cache/views' => 'empty', - 'tmp/logs' => 'empty', - 'tmp/sessions' => 'empty', - 'tmp/tests' => 'empty', - 'webroot/js' => 'empty', - 'webroot/files' => 'empty' - ); - - foreach ($empty as $dir => $file) { - $this->assertTrue(is_file($path . DS . $dir . DS . $file), sprintf('Missing %s file in %s', $file, $dir)); - } - } - -/** - * test App.namespace and namespace - * - * @return void - */ - public function testAppNamespace() { - $this->_setupTestProject(); - - $path = $this->Task->path . 'BakeTestApp/'; - $result = $this->Task->appNamespace($path); - $this->assertTrue($result); - - $File = new File($path . 'Config/app.php'); - $contents = $File->read(); - $this->assertRegExp('/\$namespace = \'BakeTestApp\';/', $contents); - - $files = array( - 'Config/bootstrap', - 'Controller/AppController', - 'Model/AppModel', - 'View/Helper/AppHelper' - ); - foreach ($files as $file) { - $file = $path . $file . '.php'; - $this->assertRegExp('/namespace BakeTestApp\\\/', $contents); - } - } - -/** - * test generation of Security.salt - * - * @return void - */ - public function testSecuritySaltGeneration() { - $this->_setupTestProject(); - - $path = $this->Task->path . 'BakeTestApp/'; - $result = $this->Task->securitySalt($path); - $this->assertTrue($result); - - $File = new File($path . 'Config/app.php'); - $contents = $File->read(); - $this->assertNotRegExp('/DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi/', $contents, 'Default Salt left behind. %s'); - } - -/** - * test generation of cache prefix - * - * @return void - */ - public function testCachePrefixGeneration() { - $this->_setupTestProject(); - - $path = $this->Task->path . 'BakeTestApp/'; - $result = $this->Task->cachePrefix($path); - $this->assertTrue($result); - - $File = new File($path . 'Config/cache.php'); - $contents = $File->read(); - $this->assertRegExp('/\$prefix = \'.+\';/', $contents, '$prefix is not defined'); - $this->assertNotRegExp('/\$prefix = \'myapp_\';/', $contents, 'Default cache prefix left behind. %s'); - } - -/** - * Test that Config/paths.php is generated correctly. - * - * @return void - */ - public function testIndexPhpGeneration() { - $this->_setupTestProject(); - - $path = $this->Task->path . 'BakeTestApp/'; - $this->Task->corePath($path); - - $File = new File($path . 'Config/paths.php'); - $contents = $File->read(); - $this->assertNotRegExp('/define\(\'CAKE_CORE_INCLUDE_PATH\', ROOT/', $contents); - } - /** * test getPrefix method, and that it returns Routing.prefix or writes to config file. * @@ -338,31 +141,4 @@ public function testGetPrefixWithMultiplePrefixes() { $result = $this->Task->getPrefix(); $this->assertEquals('ninja_', $result); } - -/** - * Test execute method with one param to destination folder. - * - * @return void - */ - public function testExecute() { - $this->Task->params['skel'] = CAKE . 'Console/Templates/skel'; - $this->Task->params['working'] = TMP . 'tests/'; - - $invalidPath = $this->Task->path . 'bake-test-app'; - $path = $this->Task->path . 'BakeTestApp'; - $this->Task->expects($this->at(0))->method('in')->will($this->returnValue($invalidPath)); - $this->Task->expects($this->at(2))->method('in')->will($this->returnValue($path)); - $this->Task->expects($this->at(3))->method('in')->will($this->returnValue('y')); - - $this->Task->execute(); - $this->assertTrue(is_dir($path), 'No project dir'); - $this->assertTrue(is_dir($path . DS . 'Controller'), 'No controllers dir '); - $this->assertTrue(is_dir($path . DS . 'Controller/Component'), 'No components dir '); - $this->assertTrue(is_dir($path . DS . 'Model'), 'No models dir'); - $this->assertTrue(is_dir($path . DS . 'View'), 'No views dir'); - $this->assertTrue(is_dir($path . DS . 'View/Helper'), 'No helpers dir'); - $this->assertTrue(is_dir($path . DS . 'Test'), 'No tests dir'); - $this->assertTrue(is_dir($path . DS . 'Test/TestCase'), 'No cases dir'); - $this->assertTrue(is_dir($path . DS . 'Test/Fixture'), 'No fixtures dir'); - } }