args[0])) { $project = $this->args[0]; } else { $appContents = array_diff(scandir(APP), ['.', '..']); if (empty($appContents)) { $suggestedPath = rtrim(APP, DS); } else { $suggestedPath = APP . 'MyApp'; } } while (!$project) { $prompt = 'What is the path to the project you want to bake?'; $project = $this->in($prompt, null, $suggestedPath); } $namespace = basename($project); if (!preg_match('/^\w[\w\d_]+$/', $namespace)) { $this->err('Project Name/Namespace needs to start with a letter and can only contain letters, digits and underscore'); $this->args = []; return $this->main(); } if ($project && !Folder::isAbsolute($project) && isset($_SERVER['PWD'])) { $project = $_SERVER['PWD'] . DS . $project; } $response = false; while (!$response && is_dir($project) === true && file_exists($project . 'Config' . 'boostrap.php')) { $prompt = sprintf('A project already exists in this location: %s Overwrite?', $project); $response = $this->in($prompt, ['y', 'n'], 'n'); if (strtolower($response) === 'n') { $response = $project = false; } } if ($project === false) { $this->out('Aborting project creation.'); return; } if ($this->bake($project)) { $this->out('Project baked successfully!'); return $project; } } /** * Uses either the CLI option or looks in $PATH and cwd for composer. * * @return string|false Either the path to composer or false if it cannot be found. */ public function findComposer() { if (!empty($this->params['composer'])) { $path = $this->params['composer']; if (file_exists($path)) { return $path; } } $composer = false; $path = env('PATH'); if (!empty($path)) { $paths = explode(PATH_SEPARATOR, $path); $composer = $this->_searchPath($paths); } return $composer; } /** * Search the $PATH for composer. * * @param array $path The paths to search. * @return string|bool */ protected function _searchPath($path) { $composer = ['composer.phar', 'composer']; foreach ($path as $dir) { foreach ($composer as $cmd) { if (is_file($dir . DS . $cmd)) { $this->_io->verbose('Found composer executable in ' . $dir); return $dir . DS . $cmd; } } } return false; } /** * Uses composer to generate a new package using the cakephp/app project. * * @param string $path Project path * @return mixed */ public function bake($path) { $composer = $this->findComposer(); if (!$composer) { $this->error('Cannot bake project. Could not find composer. Add composer to your PATH, or use the -composer option.'); return false; } $this->out('Downloading a new cakephp app from packagist.org'); $command = 'php ' . escapeshellarg($composer) . ' create-project -s dev cakephp/app ' . escapeshellarg($path); try { $this->callProcess($command); } catch (\RuntimeException $e) { $error = $e->getMessage(); $this->error('Installation from packagist.org failed with: %s', $error); return false; } return true; } /** * get the option parser. * * @return \Cake\Console\ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); return $parser->description( 'Generate a new CakePHP project skeleton.' )->addArgument('name', [ 'help' => 'Application directory to make, if it starts with "/" the path is absolute.' ])->addOption('empty', [ 'boolean' => true, 'help' => 'Create empty files in each of the directories. Good if you are using git' ])->addOption('theme', [ 'short' => 't', 'help' => 'Theme to use when baking code.' ])->addOption('composer', [ 'default' => ROOT . '/composer.phar', 'help' => 'The path to the composer executable.' ])->removeOption('plugin'); } }