*/ class Create extends SyCommand { /** * Symfony Progress Bar for command * * @var Symfony\Component\Console\Helper\ProgressBar */ protected $progressBar; /** * Array of task sets containing tasks * * @var mixed */ protected $tasks; /** * Name of the deployment * * @var string */ protected $name; /** * Domain name of the deployment * * @var string */ protected $domain; /** * Configure the command * * @author Phil Burton */ protected function configure() { $this->addArgument('name', InputArgument::REQUIRED, 'The name of the new site.'); $this->addArgument('domain', InputArgument::REQUIRED, 'The domain name of the new site.'); $this ->setName('site:create') ->setDescription('Create a new site.') ->setHelp('This command allows you to create a new site.'); $this->addOption( 'test', 't', InputOption::VALUE_NONE, 'Run in test mode without any file or directory created?' ); $this->addOption( 'ignore-config', 'c', InputOption::VALUE_NONE, 'Ignore writing the config?' ); $this->addOption( 'ignore-filesystem', 'f', InputOption::VALUE_NONE, 'Ignore writing the deployment files and directories?' ); } /** * Run the command * * @param InputInterface $input * @param OutputInterface $output * @author Phil Burton */ protected function execute(InputInterface $input, OutputInterface $output) { $taskCount = 9; if ($input->getOption('ignore-filesystem')) { $taskCount -= 8; } if ($input->getOption('ignore-config')) { $taskCount -= 1; } if ($taskCount <= 0) { echo "Nothing to do.\n"; exit; } $this->name = $input->getArgument('name'); $this->domain = $input->getArgument('domain'); $output->writeln( 'Creating new site with name: ' . $input->getArgument('name') . ' and domain: ' . $input->getArgument('domain') ); // Set-up progress bar $this->progressBar = new ProgressBar($output, $taskCount); $this->progressBar->setFormatDefinition('custom', ' %current%/%max% -- %message%'); $this->progressBar->setFormat('custom'); $this->progressBar->setMessage('Starting...'); $this->progressBar->start(); $this->progressBar->setMessage('Running pre-flight checks'); // Construct the file commands so we run checks first $this->progressBar->advance(); try { $this->runPreflightChecks($input); } catch (\Exception $e) { $this->complete($output, "Error with pre-flight checks:\n" . $e->getMessage()); } try { if (!$input->getOption('test')) { if (!$input->getOption('ignore-config')) { $this->createConfig($input); } if (!$input->getOption('ignore-filesystem')) { $this->createFilesystem($input); } } } catch (\Exception $e) { $this->complete($output, "Unexpected Error creating files and directories:\n " . $e->getMessage()); } // Finish up $this->complete($output, 'Complete', true); } /** * Show a message and end the program * Optionally complete the progress bar * * @author Phil Burton * @param OutputInterface $output * @param string $message * @param boolean $completeProgressBar */ public function complete(OutputInterface $output, string $message, $completeProgressBar = false) { if ($completeProgressBar) { $this->progressBar->advance(); $this->progressBar->finish(); } $output->writeln(''); $output->writeln($message); exit; } /** * Run the required tasks to check we can complete the full deployment * * @author Phil Burton * @param InputInterface $input */ public function runPreflightChecks(InputInterface $input) { $ignoreFilesystem = $input->getOption('ignore-filesystem'); $ignoreConfig = $input->getOption('ignore-config'); if (!$ignoreFilesystem) { $this->addTask( 'check-filesystem', 'Creating site directory', new CreateDirectory( $this->getFullSitesPath($this->name) ) ); } if (!$ignoreConfig) { $this->addTask( 'check-config', 'Creating nginx config file', new CreateFile( CONFIG_ROOT . '/' . $this->name . '.conf', include_once(DIPPER_ROOT . '/nginx/stub.php') ) ); } } /** * Run the creation of the config tasks * * @author Phil Burton */ public function createConfig() { $this->runTaskSet('check-config'); } /** * Run the creatuion of the filesystem tasks * * @author Phil Burton * @param InputInterface $input */ public function createFilesystem(InputInterface $input) { $this->runTaskSet('check-filesystem'); $this->runTask( 'Creating logs directory', new CreateDirectory( $this->getFullSitesPath($this->name) . '/logs' ), true ); $this->runTask( 'Creating access log file', new CreateFile( $this->getFullSitesPath($this->name) . '/logs/' . $this->name . '.access_log' ), true ); $this->runTask( 'Creating error log file', new CreateFile( $this->getFullSitesPath($this->name) . '/logs/' . $this->name . '.errors_log' ), true ); $this->runTask( 'Creating web folder', new CreateDirectory( $this->getFullSitesPath($this->name) . '/web' ), true ); $this->runTask( 'Creating directory index.php', new CreateFile( $this->getFullSitesPath($this->name) . '/web/index.php' ), true ); } /** * Add a task to a task set * * @author Phil Burton * @param string $taskSetName * @param string $taskName * @param TaskInterface $task */ public function addTask(string $taskSetName, string $taskName, TaskInterface $task) { $this->taskPriority[$taskSetName][] = $taskName; $this->tasks[$taskSetName][$taskName] = $task; } /** * Get the array of tasks from a taskset * * @author Phil Burton * @param string $taskSetName * @return TaskInterface[] */ public function getTaskSet(string $taskSetName) { $tasks = $this->tasks; if (array_key_exists($taskSetName, $tasks)) { return $tasks[$taskSetName]; } return false; } /** * Run all the tasks in a taskset * * @author Phil Burton * @param string $taskSetName] * @param boolean $advanceProgressBar */ public function runTaskSet(string $taskSetName, $advanceProgressBar = false) { $tasks = $this->getTaskSet($taskSetName); if (!$tasks) { throw new \Exception('Could not find task set `' . $taskSetName . '`'); } foreach ($this->taskPriority[$taskSetName] as $message) { $task = $tasks[$message]; // Create file in web root for execution $this->runTask($message, $task, $advanceProgressBar); } } /** * Return the full path of a given file * * @author Phil Burton * @param string $path * @return string */ protected function getFullSitesPath($path) { return SITES_ROOT . "/" . $path; } /** * Run a task * * @author Phil Burton * @param mixed $task * @param string $message * @return string */ protected function runTask(string $message, TaskInterface $task, $advanceProgressBar = false) { if ($advanceProgressBar) { $this->progressBar->advance(); $this->progressBar->setMessage($message); } $task->execute(); } }