123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- <?php
- declare(strict_types = 1);
- namespace Fgm\Drupal\Composer;
- use Drupal\Component\Utility\NestedArray;
- 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
- {
-
- const ARG_FILE = 'file';
-
- protected $eventName;
-
- public function configure()
- {
- parent::configure();
- $this->eventName = $this->getName();
- $this
- ->setName('build:settings')
- ->setDescription('Builds the *.settings.local.php files.')
- ->setDefinition(
- new InputDefinition([
- new InputArgument(static::ARG_FILE, InputArgument::OPTIONAL),
- ])
- )
- ->setHelp(
- <<<EOT
- The build:settings command combines shared and per-environment parameters and passes
- them to the settings.local.php.twig template to build the settings/(build|run).settings.local.php files.
- EOT
- );
- }
-
- public function execute(InputInterface $input, OutputInterface $output)
- {
- [$templateName, $err] = $this->validateTemplateName($input, $output);
- if ($err) {
- 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) {
- $stageSettings = NestedArray::mergeDeepArray([
- $siteParams['settings']['both'] ?? [],
- $siteParams['settings'][$stage] ?? []
- ], true);
- $stageParams = $siteParams;
- $stageParams['settings'] = $stageSettings;
- $context = [
- 'instance' => $params['instance'],
- 'name' => $name,
- 'stage' => $stage,
- 'site' => $stageParams,
- ];
- $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;
- }
-
- protected function validateTemplateName(InputInterface $input, OutputInterface $output): array {
- $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];
- }
- return [$templateName, 0];
- }
- }
|