From f5ac200841ff8525396e93b59a329944b28b58f3 Mon Sep 17 00:00:00 2001
From: jurgenhaas <juergen.haas@lakedrops.com>
Date: Wed, 26 Jun 2024 13:43:25 +0200
Subject: [PATCH] composer/plugin/drupal-environment#17 Implement default
 settings for composer.json

---
 defaults/config.json           | 25 ++++++++++++
 defaults/curated.json          | 41 +++++++++++++++++++
 defaults/drupal-libraries.json | 31 +++++++++++++++
 defaults/drupal-scaffold.json  | 21 ++++++++++
 defaults/installer-paths.json  | 29 ++++++++++++++
 defaults/installer-types.json  |  3 ++
 src/Plugin.php                 | 72 ++++++++++++++++++++++++++++++++++
 7 files changed, 222 insertions(+)
 create mode 100644 defaults/config.json
 create mode 100644 defaults/curated.json
 create mode 100644 defaults/drupal-libraries.json
 create mode 100644 defaults/drupal-scaffold.json
 create mode 100644 defaults/installer-paths.json
 create mode 100644 defaults/installer-types.json

diff --git a/defaults/config.json b/defaults/config.json
new file mode 100644
index 0000000..d8021db
--- /dev/null
+++ b/defaults/config.json
@@ -0,0 +1,25 @@
+{
+  "preferred-install": {
+    "*": "dist"
+  },
+  "sort-packages": true,
+  "discard-changes": true,
+  "gitlab-domains": [
+    "gitlab.lakedrops.com"
+  ],
+  "allow-plugins": {
+    "composer/installers": true,
+    "dealerdirect/phpcodesniffer-composer-installer": true,
+    "cweagans/composer-patches": true,
+    "drupal/core-composer-scaffold": true,
+    "endroid/installer": true,
+    "bitegra/*": true,
+    "lakedrops/*": true,
+    "php-http/discovery": false,
+    "phpstan/extension-installer": true,
+    "mxr576/ddqg-composer-audit": true,
+    "oomphinc/composer-installers-extender": true,
+    "drupal/core-vendor-hardening": true,
+    "zodiacmedia/drupal-libraries-installer": true
+  }
+}
diff --git a/defaults/curated.json b/defaults/curated.json
new file mode 100644
index 0000000..92cc27e
--- /dev/null
+++ b/defaults/curated.json
@@ -0,0 +1,41 @@
+[
+  "DDQG-deprecated-drupal-variationcache-1.5.0.0",
+  "DDQG-unsupported-drupal-activitypub-1.0.0.0-alpha19",
+  "DDQG-unsupported-drupal-advanced_cors-1.5.0.0",
+  "DDQG-unsupported-drupal-analog_digital_clock-10.1.2.0",
+  "DDQG-unsupported-drupal-block_field-1.0.0.0-RC4",
+  "DDQG-unsupported-drupal-bpmn_io-2.0.0.0-RC1",
+  "DDQG-unsupported-drupal-commerce_xquantity-2.0.0.0-beta1",
+  "DDQG-unsupported-drupal-conditional_fields-4.0.0.0-alpha5",
+  "DDQG-unsupported-drupal-config_update-2.0.0.0-alpha3",
+  "DDQG-unsupported-drupal-content_access-2.0.0.0",
+  "DDQG-unsupported-drupal-core-10.3.0.0-RC1",
+  "DDQG-unsupported-drupal-eca-2.0.0.0-RC1",
+  "DDQG-unsupported-drupal-eca_metatag-2.0.0.0-RC1",
+  "DDQG-unsupported-drupal-eca_tamper-2.0.0.0-RC1",
+  "DDQG-unsupported-drupal-entitygroupfield-1.0.0.0-beta1",
+  "DDQG-unsupported-drupal-gin-3.0.0.0-RC11",
+  "DDQG-unsupported-drupal-gin_toolbar-1.0.0.0-RC6",
+  "DDQG-unsupported-drupal-hide_submit_d8-0.0.0.0-dev",
+  "DDQG-unsupported-drupal-inline_entity_form-1.0.0.0-RC17",
+  "DDQG-unsupported-drupal-layout_library-1.0.0.0-beta4",
+  "DDQG-unsupported-drupal-login_destination-2.0.0.0-beta7",
+  "DDQG-unsupported-drupal-masquerade-2.0.0.0-RC4",
+  "DDQG-unsupported-drupal-matomo-2.0.0.0-alpha1",
+  "DDQG-unsupported-drupal-media_entity_link-2.0.1.0",
+  "DDQG-unsupported-drupal-menu_breadcrumb-2.0.0.0-alpha0",
+  "DDQG-unsupported-drupal-name-1.0.0.0-RC6",
+  "DDQG-unsupported-drupal-openid_connect-3.0.0.0-alpha3",
+  "DDQG-unsupported-drupal-peertube-2.0.0.0-beta2",
+  "DDQG-unsupported-drupal-reader-1.0.0.0-beta2",
+  "DDQG-unsupported-drupal-readmehelp-2.0.0.0-beta1",
+  "DDQG-unsupported-drupal-schema_diff-1.0.0.0-alpha2",
+  "DDQG-unsupported-drupal-services-5.0.0.0-beta10",
+  "DDQG-unsupported-drupal-sitemap-2.0.0.0-beta6",
+  "DDQG-unsupported-drupal-slick_extras-1.0.0.0-RC7",
+  "DDQG-unsupported-drupal-smart_date-4.1.0.0-RC9",
+  "DDQG-unsupported-drupal-tamper-1.0.0.0-alpha4",
+  "DDQG-unsupported-drupal-taxonomy_machine_name-0.0.0.0-dev",
+  "DDQG-unsupported-drupal-views_menu_children_filter-3.0.0.0-RC4",
+  "DDQG-unsupported-drupal-xnumber-2.0.0.0-beta2"
+]
diff --git a/defaults/drupal-libraries.json b/defaults/drupal-libraries.json
new file mode 100644
index 0000000..4a18a33
--- /dev/null
+++ b/defaults/drupal-libraries.json
@@ -0,0 +1,31 @@
+{
+  "blazy": "https://github.com/dinbror/blazy/archive/1.8.2.zip",
+  "codemirror": "https://github.com/components/codemirror/archive/refs/tags/5.65.12.zip",
+  "colorbox": "https://github.com/jackmoore/colorbox/archive/refs/tags/1.6.4.zip",
+  "dompurify": "https://github.com/cure53/DOMPurify/archive/refs/tags/3.0.9.zip",
+  "dropzone": "https://github.com/dropzone/dropzone/releases/download/v5.9.3/dist.zip",
+  "imagesloaded": "https://api.github.com/repos/desandro/imagesloaded/zipball/67c4e57453120935180c45c6820e7d3fbd2ea1f9",
+  "jquery.chosen": "https://github.com/harvesthq/chosen/releases/download/v1.8.7/chosen_v1.8.7.zip",
+  "jquery.geocomplete": "https://github.com/ubilabs/geocomplete/archive/refs/tags/1.7.0.zip",
+  "jquery.hotkeys": "https://github.com/jeresig/jquery.hotkeys/archive/refs/tags/0.2.0.zip",
+  "jquery.icheck": "https://github.com/dargullin/icheck/archive/refs/tags/1.0.2.zip",
+  "jquery.image-picker": "https://github.com/rvera/image-picker/archive/refs/tags/0.3.1.zip",
+  "jquery.inputmask": "https://github.com/RobinHerbots/jquery.inputmask/archive/refs/tags/5.0.8.zip",
+  "jquery.intl-tel-input": "https://github.com/jackocnr/intl-tel-input/archive/refs/tags/v17.0.19.zip",
+  "jquery.rateit": "https://github.com/gjunge/rateit.js/archive/refs/tags/1.1.5.zip",
+  "jquery.select2": "https://github.com/select2/select2/archive/refs/tags/4.0.13.zip",
+  "jquery-simple-color": "https://github.com/recurser/jquery-simple-color/archive/refs/tags/v1.2.3.tar.gz",
+  "jquery.textcounter": "https://github.com/ractoon/jQuery-Text-Counter/archive/refs/tags/0.9.1.zip",
+  "jquery.timepicker": "https://github.com/jonthornton/jquery-timepicker/archive/refs/tags/1.14.0.zip",
+  "jquery.toggles": "https://github.com/simontabor/jquery-toggles/archive/refs/tags/v4.0.0.zip",
+  "masonry": "https://api.github.com/repos/desandro/masonry/zipball/3b0883cf4a4a046896719b9cf282ea74be7ffecd",
+  "popperjs": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
+  "progress-tracker": "https://github.com/NigelOToole/progress-tracker/archive/refs/tags/2.0.7.zip",
+  "select2": "https://github.com/select2/select2/archive/4.0.13.zip",
+  "signature_pad": "https://github.com/szimek/signature_pad/archive/refs/tags/v2.3.0.zip",
+  "slick": "https://github.com/kenwheeler/slick/archive/1.8.0.zip",
+  "spectrum": "https://github.com/bgrins/spectrum/archive/refs/tags/1.8.0.tar.gz",
+  "svg-pan-zoom": "https://github.com/ariutta/svg-pan-zoom/archive/refs/tags/3.6.1.zip",
+  "tabby": "https://github.com/cferdinandi/tabby/archive/refs/tags/v12.0.3.zip",
+  "tippyjs": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz"
+}
diff --git a/defaults/drupal-scaffold.json b/defaults/drupal-scaffold.json
new file mode 100644
index 0000000..f9b73b3
--- /dev/null
+++ b/defaults/drupal-scaffold.json
@@ -0,0 +1,21 @@
+{
+  "locations": {
+    "web-root": "./web"
+  },
+  "file-mapping": {
+    "[project-root]/.editorconfig": false,
+    "[project-root]/.gitattributes": false,
+    "[web-root]/example.gitignore": false,
+    "[web-root]/INSTALL.txt": false,
+    "[web-root]/README.txt": false,
+    "[web-root]/sites/README.txt": false,
+    "[web-root]/sites/development.services.yml": false,
+    "[web-root]/sites/example.settings.local.php": false,
+    "[web-root]/sites/example.sites.php": false,
+    "[web-root]/sites/default/default.services.yml": false,
+    "[web-root]/sites/default/default.settings.php": false,
+    "[web-root]/modules/README.txt": false,
+    "[web-root]/profiles/README.txt": false,
+    "[web-root]/themes/README.txt": false
+  }
+}
diff --git a/defaults/installer-paths.json b/defaults/installer-paths.json
new file mode 100644
index 0000000..078d24c
--- /dev/null
+++ b/defaults/installer-paths.json
@@ -0,0 +1,29 @@
+{
+  "web/core": [
+    "type:drupal-core"
+  ],
+  "web/modules/contrib/{$name}": [
+    "type:drupal-module"
+  ],
+  "web/profiles/contrib/{$name}": [
+    "type:drupal-profile"
+  ],
+  "web/recipes/contrib/{$name}": [
+    "type:drupal-recipe"
+  ],
+  "web/themes/contrib/{$name}": [
+    "type:drupal-theme"
+  ],
+  "web/themes/custom/{$name}": [
+    "type:drupal-custom-theme"
+  ],
+  "web/libraries/{$name}": [
+    "type:drupal-library"
+  ],
+  "drush/Commands/{$name}": [
+    "type:drupal-drush"
+  ],
+  "tests/{$name}": [
+    "type:lakedrops-tests"
+  ]
+}
diff --git a/defaults/installer-types.json b/defaults/installer-types.json
new file mode 100644
index 0000000..6ceaaa2
--- /dev/null
+++ b/defaults/installer-types.json
@@ -0,0 +1,3 @@
+[
+  "lakedrops-tests"
+]
diff --git a/src/Plugin.php b/src/Plugin.php
index b67aa8c..81d390b 100644
--- a/src/Plugin.php
+++ b/src/Plugin.php
@@ -9,6 +9,7 @@ use Composer\Script\Event;
 use Composer\Script\ScriptEvents;
 use Drupal\Composer\Plugin\Scaffold\Handler as DrupalScaffoldHandler;
 use LakeDrops\Component\Composer\BasePlugin;
+use LakeDrops\Component\Composer\NestedArray;
 
 /**
  * Composer plugin for handling drupal scaffold.
@@ -51,11 +52,48 @@ class Plugin extends BasePlugin {
    */
   public static function getSubscribedEvents(): array {
     return [
+      ScriptEvents::PRE_INSTALL_CMD => ['alterConfigAndExtras', 999],
+      ScriptEvents::PRE_UPDATE_CMD => ['alterConfigAndExtras', 999],
       ScriptEvents::POST_CREATE_PROJECT_CMD => ['prepareProject', 1],
       ScriptEvents::POST_INSTALL_CMD => ['prepareProject', 1],
     ];
   }
 
+  /**
+   * Post update project event callback.
+   *
+   * @param \Composer\Script\Event $event
+   *   The event that triggered the plugin.
+   */
+  public function alterConfigAndExtras(Event $event): void {
+    $extra = $event->getComposer()->getPackage()->getExtra();
+    if (isset($extra['lakedrops-config-file']) || isset($extra['lakedrops-curated-file'])) {
+      $config = $event->getComposer()->getConfig()->all();
+      if (isset($extra['lakedrops-config-file'])) {
+        $defaultConfig = $this->readJson('config', $extra['lakedrops-config-file'], $event->getIO());
+        $config = NestedArray::mergeDeep($defaultConfig, $config);
+      }
+      if (isset($extra['lakedrops-curated-file'])) {
+        $config['audit']['ignore'] = $this->readJson('audit ignore', $extra['lakedrops-curated-file'], $event->getIO());
+      }
+      $event->getComposer()->setConfig($config);
+    }
+
+    $extras = [
+      'drupal-scaffold',
+      'installer-types',
+      'installer-paths',
+      'drupal-libraries',
+    ];
+    foreach ($extras as $item) {
+      $key = 'lakedrops-extra-' . $item . '-file';
+      if (isset($extra[$key])) {
+        $extra[$item] = $this->readJson($item, $extra[$key], $event->getIO());
+      }
+    }
+    $event->getComposer()->getPackage()->setExtra($extra);
+  }
+
   /**
    * Post update project event callback.
    *
@@ -69,4 +107,38 @@ class Plugin extends BasePlugin {
     $handler->setupLakeDropsProject();
   }
 
+  /**
+   * Helper function to read and decode default settings from a file.
+   *
+   * @param string $type
+   *   The type of information for status message.
+   * @param string $filename
+   *   The filename from where to read the data.
+   * @param \Composer\IO\IOInterface $io
+   *   The io service for messages.
+   *
+   * @return array
+   *   The read data.
+   *
+   * @throws \Exception
+   */
+  protected function readJson(string $type, string $filename, IOInterface $io): array {
+    $io->write('<info>Gathering ' . $type . ' from patch file.</info>');
+    $data = file_get_contents($filename);
+    $data = json_decode($data, TRUE);
+    $error = json_last_error();
+    if ($error !== 0) {
+      $msg = match ($error) {
+        JSON_ERROR_DEPTH => ' - Maximum stack depth exceeded',
+        JSON_ERROR_STATE_MISMATCH => ' - Underflow or the modes mismatch',
+        JSON_ERROR_CTRL_CHAR => ' - Unexpected control character found',
+        JSON_ERROR_SYNTAX => ' - Syntax error, malformed JSON',
+        JSON_ERROR_UTF8 => ' - Malformed UTF-8 characters, possibly incorrectly encoded',
+        default => ' - Unknown error',
+      };
+      throw new \Exception('There was an error in the supplied file:' . $msg);
+    }
+    return $data;
+  }
+
 }
-- 
GitLab