summaryrefslogtreecommitdiff
path: root/src/Client/Script
diff options
context:
space:
mode:
Diffstat (limited to 'src/Client/Script')
-rw-r--r--src/Client/Script/Command/Site/Create.php348
-rw-r--r--src/Client/Script/Console.php24
2 files changed, 372 insertions, 0 deletions
diff --git a/src/Client/Script/Command/Site/Create.php b/src/Client/Script/Command/Site/Create.php
new file mode 100644
index 0000000..df9fc18
--- /dev/null
+++ b/src/Client/Script/Command/Site/Create.php
@@ -0,0 +1,348 @@
+<?php
+
+namespace App\Script\Command\Site;
+
+use Symfony\Component\Console\Command\Command as SyCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Helper\ProgressBar;
+use App\Filesystem\CreateFile;
+use App\Filesystem\CreateDirectory;
+use App\Task\TaskInterface;
+
+/**
+ * A new Symfony command for creating a new site deployment
+ *
+ * @author Phil Burton <phil@d3r.com>
+ */
+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 <phil@d3r.com>
+ */
+ 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 <phil@d3r.com>
+ */
+ 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 <phil@pgburton.com>
+ * @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 <phil@pgburton.com>
+ * @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 <phil@pgburton.com>
+ */
+ public function createConfig()
+ {
+ $this->runTaskSet('check-config');
+ }
+
+ /**
+ * Run the creatuion of the filesystem tasks
+ *
+ * @author Phil Burton <phil@pgburton.com>
+ * @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 <phil@pgburton.com>
+ * @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 <phil@pgburton.com>
+ * @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 <phil@pgburton.com>
+ * @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 <phil@pgburton.com>
+ * @param string $path
+ * @return string
+ */
+ protected function getFullSitesPath($path)
+ {
+ return SITES_ROOT . "/" . $path;
+ }
+
+ /**
+ * Run a task
+ *
+ * @author Phil Burton <phil@pgburton.com>
+ * @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();
+ }
+}
diff --git a/src/Client/Script/Console.php b/src/Client/Script/Console.php
new file mode 100644
index 0000000..5f5d90d
--- /dev/null
+++ b/src/Client/Script/Console.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Script;
+
+use Symfony\Component\Console\Application;
+use App\Script\Command\Site\Create;
+
+/**
+ * Main application class
+ */
+class Console
+{
+ /**
+ * Create symfony application and add commands
+ *
+ * @author Phil Burton <phil@pgburton.com>
+ */
+ public function __construct()
+ {
+ $application = new Application();
+ $application->add(new Create());
+ $application->run();
+ }
+}