|
@@ -1,14 +1,27 @@
|
|
|
<?php
|
|
|
+declare(strict_types = 1);
|
|
|
|
|
|
namespace Fgm\Drupal\Composer;
|
|
|
|
|
|
-use Composer\Command\BaseCommand;
|
|
|
+use Symfony\Component\Console\Input\InputArgument;
|
|
|
+use Symfony\Component\Console\Input\InputDefinition;
|
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
|
+use Symfony\Component\Yaml\Exception\ParseException;
|
|
|
+use Symfony\Component\Yaml\Yaml;
|
|
|
+use Twig\Environment;
|
|
|
+use Twig\Extension\DebugExtension;
|
|
|
+use Twig\Loader\FilesystemLoader;
|
|
|
+use Twig\TemplateWrapper;
|
|
|
|
|
|
class BuildSettingsCommand extends BaseBuilderCommand
|
|
|
{
|
|
|
|
|
|
+ /**
|
|
|
+ * The name of the argument defining the file to generate.
|
|
|
+ */
|
|
|
+ const ARG_FILE = 'file';
|
|
|
+
|
|
|
/**
|
|
|
* @var string
|
|
|
*/
|
|
@@ -24,7 +37,11 @@ class BuildSettingsCommand extends BaseBuilderCommand
|
|
|
$this
|
|
|
->setName('build:settings')
|
|
|
->setDescription('Builds the *.settings.local.php files.')
|
|
|
- ->setDefinition([])
|
|
|
+ ->setDefinition(
|
|
|
+ new InputDefinition([
|
|
|
+ new InputArgument(static::ARG_FILE, InputArgument::OPTIONAL),
|
|
|
+ ])
|
|
|
+ )
|
|
|
->setHelp(
|
|
|
<<<EOT
|
|
|
The build:settings command combines shared and per-environment parameters and passes
|
|
@@ -39,9 +56,88 @@ EOT
|
|
|
*/
|
|
|
public function execute(InputInterface $input, OutputInterface $output)
|
|
|
{
|
|
|
- $messageFormat = empty($this->eventName)
|
|
|
- ? "BuildSettingsCommand Executed on its own"
|
|
|
- : "BuildSettingsCommand Executed on \"%s\" event";
|
|
|
- $output->write(sprintf($messageFormat, $this->eventName), true);
|
|
|
+ $file = $input->getArgument(static::ARG_FILE);
|
|
|
+ $conf = $this->getBuilderConfig();
|
|
|
+ $templateName = $conf['templates'][$file] ?? '';
|
|
|
+ if (empty($templateName)) {
|
|
|
+ $output->writeln(sprintf(
|
|
|
+ 'Could not build file %s: no such template in composer.json extra section',
|
|
|
+ $file
|
|
|
+ ));
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ $settingsPath = $this->getSettingsPath();
|
|
|
+ $templatePath = "${settingsPath}/${templateName}";
|
|
|
+ $realTemplatePath = realpath($templatePath);
|
|
|
+ if (empty($realTemplatePath)) {
|
|
|
+ $output->writeln(sprintf("Could not load template %s: no such file", $templateName));
|
|
|
+ return 2;
|
|
|
+ }
|
|
|
+
|
|
|
+ $paramsPath = "${settingsPath}/merged.params.local.yml";
|
|
|
+ $realParamsPath = realpath($paramsPath);
|
|
|
+ if (empty($realTemplatePath)) {
|
|
|
+ $output->writeln(sprintf("Could not load parameters %s: no such file", $paramsPath));
|
|
|
+ return 3;
|
|
|
+ }
|
|
|
+
|
|
|
+ $yaml = new Yaml();
|
|
|
+ try {
|
|
|
+ $params = $yaml->parseFile($realParamsPath);
|
|
|
+ } catch (ParseException $e) {
|
|
|
+ $output->writeln(sprintf("Could not parse %s: %s", $realParamsPath, $e->getMessage()));
|
|
|
+ return 4;
|
|
|
+ }
|
|
|
+
|
|
|
+ $loader = new FilesystemLoader($settingsPath, $settingsPath);
|
|
|
+ $twig = new Environment($loader, [
|
|
|
+ 'auto_reload' => true,
|
|
|
+ 'cache' => false,
|
|
|
+ 'debug' => true,
|
|
|
+ 'strict_variables' => true,
|
|
|
+ ]);
|
|
|
+ $twig->addExtension(new DebugExtension());
|
|
|
+
|
|
|
+ $wrapper = $twig->load($templateName);
|
|
|
+ foreach ($params['sites'] as $name => $siteParams) {
|
|
|
+ foreach (['build', 'run'] as $stage) {
|
|
|
+ $context = [
|
|
|
+ 'instance' => $params['instance'],
|
|
|
+ 'name' => $name,
|
|
|
+ 'stage' => $stage,
|
|
|
+ 'site' => $siteParams,
|
|
|
+ ];
|
|
|
+ $error = $this->render($wrapper, $context, $output);
|
|
|
+ if ($error) {
|
|
|
+ $output->writeln(sprintf("Failed rendering %s settings for site %s", $stage, $name));
|
|
|
+ return 5;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function render(TemplateWrapper $wrapper, array $context, OutputInterface $output): int
|
|
|
+ {
|
|
|
+ $settingsPath = "web/sites/${context['name']}/${context['stage']}.settings.local.php";
|
|
|
+ if (file_exists($settingsPath)) {
|
|
|
+ $ok = unlink($settingsPath);
|
|
|
+ if (!$ok) {
|
|
|
+ $output->writeln(sprintf(
|
|
|
+ "Could not remove old %s file",
|
|
|
+ $settingsPath
|
|
|
+ ));
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $rendered = $wrapper->render($context);
|
|
|
+ $ok = file_put_contents($settingsPath, $rendered, LOCK_EX);
|
|
|
+ if (!$ok) {
|
|
|
+ $output->writeln(sprintf('Could not write new %s file', $settingsPath));
|
|
|
+ return 2;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
}
|