Browse Source

New build:merge_params command.

Frederic G. MARAND 4 years ago
parent
commit
9a3a02928b

+ 2 - 1
composer.json

@@ -18,7 +18,8 @@
   "minimum-stability": "dev",
   "name": "fgm/drupal_composer_builder",
   "require": {
-    "composer-plugin-api": "^1.1"
+    "composer-plugin-api": "^1.1",
+    "drupal/core-utility": "^8"
   },
   "type": "composer-plugin",
   "require-dev": {

+ 17 - 0
src/BaseBuilderCommand.php

@@ -0,0 +1,17 @@
+<?php
+
+
+namespace Fgm\Drupal\Composer;
+
+
+use Composer\Command\BaseCommand;
+
+abstract class BaseBuilderCommand extends BaseCommand
+{
+
+    protected function getBuilderConfig(): array
+    {
+        $conf = $this->getComposer()->getPackage()->getExtra()[Builder::NAME] ?? [];
+        return $conf;
+    }
+}

+ 7 - 7
src/BuildSettingsCommand.php

@@ -6,7 +6,7 @@ use Composer\Command\BaseCommand;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
 
-class BuildSettingsCommand extends BaseCommand
+class BuildSettingsCommand extends BaseBuilderCommand
 {
 
     /**
@@ -22,15 +22,16 @@ class BuildSettingsCommand extends BaseCommand
         parent::configure();
         $this->eventName = $this->getName();
         $this
-        ->setName('build:settings')
-        ->setDescription('Builds the *.settings.local.php files.')
-        ->setDefinition([])
-        ->setHelp(<<<EOT
+            ->setName('build:settings')
+            ->setDescription('Builds the *.settings.local.php files.')
+            ->setDefinition([])
+            ->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
-        );
+            );
     }
 
     /**
@@ -38,7 +39,6 @@ EOT
      */
     public function execute(InputInterface $input, OutputInterface $output)
     {
-        $conf = $this->getComposer()->getPackage()->getExtra()[Builder::NAME] ?? [];
         $messageFormat = empty($this->eventName)
         ? "BuildSettingsCommand Executed on its own"
         : "BuildSettingsCommand Executed on \"%s\" event";

+ 14 - 5
src/Builder.php

@@ -54,7 +54,7 @@ class Builder implements Capable, Capability, EventSubscriberInterface, PluginIn
     /**
      * Apply plugin modifications to Composer
      *
-     * @param Composer $composer
+     * @param Composer    $composer
      * @param IOInterface $io
      */
     public function activate(Composer $composer, IOInterface $io)
@@ -69,12 +69,12 @@ class Builder implements Capable, Capability, EventSubscriberInterface, PluginIn
     public function getCapabilities()
     {
         return [
-        CommandProvider::class => BuilderCommandProvider::class,
+            CommandProvider::class => BuilderCommandProvider::class,
         ];
     }
 
     /**
-     * Event callback.
+     * Event callback: run build:settings  on post-install|update only.
      *
      * @param \Composer\Script\Event $event
      *
@@ -82,7 +82,16 @@ class Builder implements Capable, Capability, EventSubscriberInterface, PluginIn
      */
     public function onScriptEvent(ScriptEvent $event)
     {
-        $buildCommand = new BuildSettingsCommand($event->getName());
-        $buildCommand->run(new ArgvInput([]), new ConsoleOutput());
+        if (in_array(
+            $event->getName(),
+            [
+              ScriptEvents::POST_INSTALL_CMD,
+              ScriptEvents::POST_UPDATE_CMD,
+            ]
+        )
+        ) {
+            $buildCommand = new BuildSettingsCommand($event->getName());
+            $buildCommand->run(new ArgvInput([]), new ConsoleOutput());
+        }
     }
 }

+ 2 - 1
src/BuilderCommandProvider.php

@@ -44,7 +44,8 @@ class BuilderCommandProvider implements CommandProvider
     public function getCommands()
     {
         return [
-        new BuildSettingsCommand(),
+            new BuildSettingsCommand(),
+            new MergeParamsCommand(),
         ];
     }
 }

+ 97 - 0
src/MergeParamsCommand.php

@@ -0,0 +1,97 @@
+<?php
+
+namespace Fgm\Drupal\Composer;
+
+use Drupal\Component\Utility\NestedArray;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Yaml\Yaml;
+
+class MergeParamsCommand extends BaseBuilderCommand
+{
+    const DEFAULT_SITE = '_default';
+
+    /**
+   * @var string
+   */
+    protected $eventName;
+
+    /**
+   * {@inheritDoc}
+   */
+    public function configure()
+    {
+        parent::configure();
+        $this->eventName = $this->getName();
+        $this
+            ->setName('build:merge_params')
+            ->setDescription('Merges the params.local.yml with dist.params.local.yml.')
+            ->setDefinition([])
+            ->setHelp(
+                <<<EOT
+The build:merge_params command combines shared and per-environment parameters and
+generates merged.params.local.yml containing the merged result.
+
+EOT
+            );
+    }
+
+    protected function merge(array $dist, array $local): array
+    {
+        if (empty($local)) {
+            return $dist;
+        }
+
+        // Merge local into defaults.
+        $merged = NestedArray::mergeDeep($dist, $local);
+
+        // Generate per-site data from settings/_default.
+        $default = $merged['sites'][static::DEFAULT_SITE] ?? [];
+        $sites = array_diff_key($merged['sites'], [static::DEFAULT_SITE => null]);
+        $merged['sites'] = [];
+        foreach ($sites as $name => $params) {
+            $merged['sites'][$name] = NestedArray::mergeDeep($default, $params);
+        }
+        return $merged;
+    }
+
+    /**
+   * {@inheritDoc}
+   */
+    public function execute(InputInterface $input, OutputInterface $output)
+    {
+        $settingsPath = getcwd() . "/settings/";
+        $yaml = new Yaml();
+
+        // Load defaults.
+        $defaultsPath = "${settingsPath}/dist.params.local.yml";
+        $realDefaultsPath = realpath($defaultsPath);
+        if (empty($realDefaultsPath)) {
+            $output->writeln("Failed to open $defaultsPath");
+            return 1;
+        }
+        $defaults = $yaml->parseFile($realDefaultsPath);
+
+        // Load local.
+        $localPath = "${settingsPath}/params.local.yml";
+        $realLocalPath = realpath($localPath);
+        if (empty($realLocalPath)) {
+            if ($output->isVerbose()) {
+                $output->writeln("File $localPath not found, using only defaults");
+            }
+            $local = [];
+        } else {
+            $local = $yaml->parseFile($realLocalPath);
+        }
+
+        // Merge.
+        $merged = $this->merge($defaults, $local);
+
+        // Write.
+        $ok = file_put_contents("${settingsPath}/merged.params.local.yml", $yaml->dump($merged, 10, 2));
+        if (!$ok) {
+            $output->writeln("Failed to write merged params.");
+            return 2;
+        }
+    }
+}