build-configs/src/Console/Command/BuildConfigurationCommand.php

125 lines
4.4 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
2023-01-21 20:42:52 +00:00
namespace OliverDaviesLtd\BuildConfigs\Console\Command;
2023-02-03 20:29:37 +00:00
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
2023-02-02 18:06:47 +00:00
use OliverDaviesLtd\BuildConfigs\Enum\Language;
2023-02-03 20:29:37 +00:00
use OliverDaviesLtd\BuildConfigs\Enum\WebServer;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
2023-01-19 20:38:10 +00:00
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
2023-01-19 18:37:13 +00:00
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Yaml\Yaml;
2023-01-19 18:37:13 +00:00
use Twig\Environment;
#[AsCommand(
description: 'Build configuration files',
2023-01-21 20:42:52 +00:00
name: 'build-configs'
)]
final class BuildConfigurationCommand extends Command
{
/** @phpstan-ignore-next-line */
2023-02-03 22:04:20 +00:00
private Collection $filesToGenerate;
private string $outputDir;
2023-01-19 18:53:42 +00:00
public function __construct(
private Environment $twig,
private Filesystem $filesystem,
) {
parent::__construct();
2023-02-03 22:04:20 +00:00
$this->filesToGenerate = new Collection();
2023-01-19 18:53:42 +00:00
}
2023-01-19 20:38:10 +00:00
protected function configure(): void
{
$this
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'The configuration file to use', 'build.yaml')
2023-01-19 20:38:10 +00:00
->addOption('output-dir', 'o', InputOption::VALUE_REQUIRED, 'The directory to create files in', '.');
}
2023-01-19 19:47:15 +00:00
public function execute(InputInterface $input, OutputInterface $output): int
{
$configFile = $input->getOption('config');
$this->outputDir = $input->getOption('output-dir');
2023-01-19 20:38:10 +00:00
2023-01-19 18:53:42 +00:00
$io = new SymfonyStyle($input, $output);
$configurationData = Yaml::parseFile($configFile);
2023-01-19 19:47:15 +00:00
$configurationData['dockerCompose'] = $configurationData['docker-compose'];
$configurationData['docker-compose'] = null;
if (isset($configurationData['docker-compose'])) {
$configurationData['dockerCompose'] = $configurationData['docker-compose'];
$configurationData['docker-compose'] = null;
}
2023-01-19 19:47:15 +00:00
$io->info("Building configuration for {$configurationData['name']}.");
2023-02-03 22:04:20 +00:00
$this->filesToGenerate->push(['env.example', '.env.example']);
$this->filesToGenerate->push(['Dockerfile', 'Dockerfile']);
2023-01-19 19:47:15 +00:00
if (isset($configurationData['dockerCompose']) && $configurationData['dockerCompose'] !== null) {
2023-02-03 22:04:20 +00:00
$this->filesToGenerate->push(['docker-compose.yaml', 'docker-compose.yaml']);
2023-01-19 19:47:15 +00:00
}
2023-02-03 20:29:37 +00:00
if (self::isPhp(Arr::get($configurationData, 'language'))) {
2023-02-03 22:04:20 +00:00
$this->filesToGenerate->push(['php/phpcs.xml', 'phpcs.xml.dist']);
$this->filesToGenerate->push(['php/phpstan.neon', 'phpstan.neon.dist']);
$this->filesToGenerate->push(['php/phpunit.xml', 'phpunit.xml.dist']);
2023-01-21 19:52:58 +00:00
$this->filesystem->mkdir("{$this->outputDir}/tools/docker/images/php/root/usr/local/bin");
2023-02-03 22:04:20 +00:00
$this->filesToGenerate->push(['php/docker-entrypoint-php', 'tools/docker/images/php/root/usr/local/bin/docker-entrypoint-php']);
2023-01-21 19:52:58 +00:00
}
2023-01-21 19:53:25 +00:00
2023-02-03 20:29:37 +00:00
if (self::isNginx(Arr::get($configurationData, 'web.type'))) {
$this->filesystem->mkdir("{$this->outputDir}/tools/docker/images/nginx/root/etc/nginx/conf.d");
2023-02-03 22:04:20 +00:00
$this->filesToGenerate->push(['default.conf', 'tools/docker/images/nginx/root/etc/nginx/conf.d/default.conf']);
2023-01-19 18:53:42 +00:00
}
2023-01-19 18:37:13 +00:00
$this->generateFiles($configurationData);
return Command::SUCCESS;
}
2023-02-03 20:29:37 +00:00
/**
* @param array<string, string> $configurationData
*/
private function generateFiles(array $configurationData): void
{
2023-02-03 22:04:20 +00:00
$this->filesToGenerate->map(function(array $filenames): array {
$filenames[0] = "{$filenames[0]}.twig";
$filenames[1] = "{$this->outputDir}/${filenames[1]}";
return $filenames;
})->each(function(array $filenames) use ($configurationData): void {
$this->filesystem->dumpFile($filenames[1], $this->twig->render($filenames[0], $configurationData));
});
}
2023-02-03 20:29:37 +00:00
private static function isNginx(?string $webServer): bool
{
if (is_null($webServer)) {
return false;
}
return strtoupper($webServer) === WebServer::NGINX->name;
2023-02-03 20:29:37 +00:00
}
private static function isPhp(?string $language): bool
{
if (is_null($language)) {
return false;
}
return strtoupper($language) === Language::PHP->name;
2023-02-03 20:29:37 +00:00
}
}