From b2d8f2ed250efe6616a0a14faf35b0ad3b19b869 Mon Sep 17 00:00:00 2001 From: Jeff Kilroy Date: Sat, 29 Jul 2017 09:56:28 -0400 Subject: [PATCH] Add composer:create-project command --- README.md | 8 +- ...ct.php => ComposerCreateProjectAction.php} | 8 +- app/Commands/ComposerCreateProject.php | 126 ++++++++++++++++++ app/Commands/Domain.php | 20 --- app/Commands/Host.php | 8 +- app/Support/Shell/CommandExecutor.php | 35 +++++ app/Support/Traits/HasCommandExecutor.php | 18 +++ homeboy | 22 +-- tests/Commands/ComposerCreateProjectTest.php | 42 ++++++ 9 files changed, 251 insertions(+), 36 deletions(-) rename app/Actions/{ComposerCreateProject.php => ComposerCreateProjectAction.php} (67%) create mode 100644 app/Commands/ComposerCreateProject.php create mode 100644 app/Support/Shell/CommandExecutor.php create mode 100644 app/Support/Traits/HasCommandExecutor.php create mode 100644 tests/Commands/ComposerCreateProjectTest.php diff --git a/README.md b/README.md index c2be7ae..5c56c35 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Tool for automating sites using Laravel Homestead. With one command, Homeboy wil - [File](#file) - [Vagrant](#vagrant) - [Domain](#domain) + - [Composer](#composer) - [Troubleshooting](#troubleshooting) ## Requirements @@ -258,7 +259,12 @@ The domain command lets you quickly add a new domain record to your hosts file. homeboy domain ``` -Homeboy will prompt the domain as well as the ip address +### Composer + +The composer:create-project command prompts you details on running a "composer create-project [composer-project] [project-name]" command +``` +homeboy composer:create-project +``` ## Troubleshooting diff --git a/app/Actions/ComposerCreateProject.php b/app/Actions/ComposerCreateProjectAction.php similarity index 67% rename from app/Actions/ComposerCreateProject.php rename to app/Actions/ComposerCreateProjectAction.php index 2f84ef7..697a3e6 100644 --- a/app/Actions/ComposerCreateProject.php +++ b/app/Actions/ComposerCreateProjectAction.php @@ -4,14 +4,16 @@ use App\Actions\Interfaces\ActionInterface; -class ComposerCreateProject extends BaseAction implements ActionInterface { +class ComposerCreateProjectAction extends BaseAction implements ActionInterface { + private $commandExecutor; private $accessCommand; private $project; private $name; - public function __construct($accessCommand, $project, $name) + public function __construct($commandExecutor, $accessCommand, $project, $name) { + $this->commandExecutor = $commandExecutor; $this->accessCommand = $accessCommand; $this->project = $project; $this->name = $name; @@ -30,7 +32,7 @@ public function actionMessage(){ } public function run(){ - $shellOutput = shell_exec($this->command()); + $this->commandExecutor->run($this->command()); } } \ No newline at end of file diff --git a/app/Commands/ComposerCreateProject.php b/app/Commands/ComposerCreateProject.php new file mode 100644 index 0000000..ccef4eb --- /dev/null +++ b/app/Commands/ComposerCreateProject.php @@ -0,0 +1,126 @@ +config = $config; + parent::__construct($name); + } + + protected function configure() + { + $this + ->setName('composer:create-project') + ->setDescription('Create a new composer project') + ->setHelp(""); + } + + private function init(InputInterface $input, OutputInterface $output){ + $this->inputInterface = $input; + $this->outputInterface = $output; + $this->hasDotEnvFile(); + $this->questionHelper = $this->getHelper('question'); + $this->interrogator = new Interrogator($input, $output, $this->getHelper('question')); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->init($input, $output); + $this->interrogate(); + + $taskConfirmation = $this->getTaskConfirmationFromQuestion(); + + if($taskConfirmation){ + $this->runTasks(); + }else{ + $output->writeln('Tasks cancelled'); + } + + return; + + } + + private function interrogate(){ + + $this->projectDirectory = $this->interrogator->ask( + 'Directory to create project?', + $this->config->getFolder() + ); + + $this->composerProject = $this->interrogator->ask( + 'Composer project', + $this->config->getComposerProject() + ); + + $this->projectName = $this->interrogator->ask( + 'Project directory name', + 'project-'.time() + ); + + } + + private function composerCreateProjectAction(){ + if(!empty($this->config->getAccessLocalSitesDirectoryCommand())){ + $accessCommand = $this->config->getAccessLocalSitesDirectoryCommand(); + }else{ + $accessCommand = 'cd '.$this->projectDirectory; + } + return new ComposerCreateProjectAction($this->commandExecutor,$accessCommand, $this->composerProject, $this->projectName); + } + + private function getTaskConfirmationFromQuestion(){ + $this->outputInterface->writeln('The following tasks will be executed:'); + + $this->outputInterface->writeln('- '.$this->composerCreateProjectAction()->confirmationMessage()); + + $response = $this->interrogator->ask( + 'Run tasks?', + 'Y' + ); + if(strtoupper($response) == 'Y'){ + return true; + } + return false; + } + + private function runTasks(){ + + $this->outputInterface->writeln(''.$this->composerCreateProjectAction()->actionMessage().'...'); + $this->composerCreateProjectAction()->run(); + $this->outputInterface->writeln(''); + $this->outputInterface->writeln('Complete!'); + } + +} \ No newline at end of file diff --git a/app/Commands/Domain.php b/app/Commands/Domain.php index 03bfe82..0b762b4 100644 --- a/app/Commands/Domain.php +++ b/app/Commands/Domain.php @@ -2,24 +2,11 @@ namespace App\Commands; -use App\Actions\ComposerCreateProject; -use App\Actions\HomesteadAddDatabase; -use App\Actions\HomesteadMapSite; use App\Actions\HostsAddLine; -use App\Actions\ProvisionHomestead; -use App\Commands\Options\DatabaseOption; -use App\Commands\Options\DomainOption; -use App\Commands\Options\ProjectNameOption; -use App\Commands\Options\SkipConfirmationOption; -use App\Commands\Options\UseComposerOption; -use App\Commands\Options\UseDefaultsOption; use App\Configuration\Config; -use App\Formatters\DatabaseNameFormatter; -use App\Formatters\DomainFormatter; use App\Input\Interrogator; use App\Support\Traits\HasCommandOptions; use App\Support\Traits\RequireEnvFile; -use App\Support\Vagrant\Vagrant; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -41,8 +28,6 @@ class Domain extends Command private $interrogator; - private $vagrant; - public function __construct($name = null, Config $config) { $this->config = $config; @@ -63,11 +48,6 @@ private function init(InputInterface $input, OutputInterface $output){ $this->hasDotEnvFile(); $this->questionHelper = $this->getHelper('question'); $this->interrogator = new Interrogator($input, $output, $this->getHelper('question')); - $vagrantAccessDirectoryCommand = 'cd '.$this->config->getHomesteadBoxPath(); - if(!empty($this->config->getHomesteadAccessDirectoryCommand())){ - $vagrantAccessDirectoryCommand = $this->config->getHomesteadAccessDirectoryCommand(); - } - $this->vagrant = new Vagrant($vagrantAccessDirectoryCommand); } protected function execute(InputInterface $input, OutputInterface $output) diff --git a/app/Commands/Host.php b/app/Commands/Host.php index 2beca3e..9f58f90 100644 --- a/app/Commands/Host.php +++ b/app/Commands/Host.php @@ -2,7 +2,7 @@ namespace App\Commands; -use App\Actions\ComposerCreateProject; +use App\Actions\ComposerCreateProjectAction; use App\Actions\HomesteadAddDatabase; use App\Actions\HomesteadMapSite; use App\Actions\HostsAddLine; @@ -17,6 +17,7 @@ use App\Formatters\DatabaseNameFormatter; use App\Formatters\DomainFormatter; use App\Input\Interrogator; +use App\Support\Traits\HasCommandExecutor; use App\Support\Traits\HasCommandOptions; use App\Support\Traits\RequireEnvFile; use App\Support\Vagrant\Vagrant; @@ -29,6 +30,7 @@ class Host extends Command use RequireEnvFile; use HasCommandOptions; + use HasCommandExecutor; private $questionHelper; private $inputInterface; @@ -50,6 +52,8 @@ class Host extends Command private $vagrant; + private $commandExecutor; + public function __construct($name = null, Config $config) { $this->config = $config; @@ -222,7 +226,7 @@ private function composerCreateProjectAction(){ }else{ $accessCommand = 'cd '.$this->folder; } - return new ComposerCreateProject($accessCommand, $this->composerProject, $this->name); + return new ComposerCreateProjectAction($this->commandExecutor, $accessCommand, $this->composerProject, $this->name); } private function hostsAddLineAction(){ diff --git a/app/Support/Shell/CommandExecutor.php b/app/Support/Shell/CommandExecutor.php new file mode 100644 index 0000000..843a817 --- /dev/null +++ b/app/Support/Shell/CommandExecutor.php @@ -0,0 +1,35 @@ +execute = $execute; + } + + public function getExecute(){ + return $this->execute; + } + + public function setCommand($command){ + $this->command = $command; + } + + public function getCommand(){ + return $this->command; + } + + public function run($command=null){ + if($command){ + $this->setCommand($command); + } + if($this->execute){ + shell_exec($this->getCommand()); + } + } + +} \ No newline at end of file diff --git a/app/Support/Traits/HasCommandExecutor.php b/app/Support/Traits/HasCommandExecutor.php new file mode 100644 index 0000000..2a7f322 --- /dev/null +++ b/app/Support/Traits/HasCommandExecutor.php @@ -0,0 +1,18 @@ +commandExecutor = $commandExecutor; + } + + public function getCommandExecutor(){ + if(!$this->commandExecutor){ + $this->commandExecutor = new \App\Support\Shell\CommandExecutor(); + } + return $this->commandExecutor; + } + +} \ No newline at end of file diff --git a/homeboy b/homeboy index 45f07b4..9a5be54 100755 --- a/homeboy +++ b/homeboy @@ -29,17 +29,19 @@ if($config->hasDotEnvFile()){ $application = new Application(); -$setupCommand = new \App\Commands\Setup(null, $config); $hostCommand = new \App\Commands\Host(null, $config); -$vagrantCommand = new \App\Commands\Vagrant(null, $config); -$fileCommand = new \App\Commands\File(null, $config); -$domainCommand = new \App\Commands\Domain(null, $config); - -$application->add($setupCommand); -$application->add($hostCommand); -$application->add($vagrantCommand); -$application->add($fileCommand); -$application->add($domainCommand); + +$commands = [ + new \App\Commands\Setup(null, $config), + new \App\Commands\Vagrant(null, $config), + new \App\Commands\File(null, $config), + new \App\Commands\Domain(null, $config), + new \App\Commands\ComposerCreateProject(null, $config), +]; + +foreach($commands as $command){ + $application->add($command); +} $application->setDefaultCommand($hostCommand->getName()); diff --git a/tests/Commands/ComposerCreateProjectTest.php b/tests/Commands/ComposerCreateProjectTest.php new file mode 100644 index 0000000..d945b01 --- /dev/null +++ b/tests/Commands/ComposerCreateProjectTest.php @@ -0,0 +1,42 @@ +setExecute(false); + + $composerCreateProjectCommand = new \App\Commands\ComposerCreateProject(null, $config); + $composerCreateProjectCommand->setCommandExecutor($commandExecutor); + + $application = new \Symfony\Component\Console\Application(); + + $application->add($composerCreateProjectCommand); + + $command = $application->find($composerCreateProjectCommand->getName()); + $commandTester = new \Symfony\Component\Console\Tester\CommandTester($command); + $commandTester->setInputs([ + $projectDirectory, + $composerProject, + $projectName, + 'y', + ]); + $commandTester->execute(array( + 'command' => $command->getName(), + )); + + $expectedCommand = 'cd '.$projectDirectory.' && composer create-project '.$composerProject.' '.$projectName; + + $this->assertEquals($expectedCommand,$commandExecutor->getCommand()); + } + +} \ No newline at end of file