From 2476a5d82983f9674041d89cf0448bb7b23c863f Mon Sep 17 00:00:00 2001
From: phenaproxima <phenaproxima@205645.no-reply.drupal.org>
Date: Mon, 8 Nov 2021 18:25:26 +0000
Subject: [PATCH] Issue #3245996 by phenaproxima: Move basic exclusions and
 test coverage into Package Manager

---
 automatic_updates.services.yml                |   4 -
 package_manager/package_manager.services.yml  |   9 ++
 .../ExcludedPathsSubscriber.php               | 151 ++++++++++++++++++
 .../tests/fixtures/fake_site/composer.json    |   1 +
 .../fixtures/fake_site/private/ignore.txt     |   1 +
 .../fake_site/sites/default/services.yml      |   1 +
 .../sites/default/settings.local.php          |   6 +
 .../fake_site/sites/default/settings.php      |   6 +
 .../fake_site/sites/default/stage.txt         |   1 +
 .../sites/example.com/files/ignore.txt        |   1 +
 .../fake_site/sites/example.com/services.yml  |   1 +
 .../sites/example.com/settings.local.php      |   6 +
 .../fake_site/sites/example.com/settings.php  |   6 +
 .../fake_site/sites/simpletest/ignore.txt     |   1 +
 .../fixtures/fake_site/vendor/web.config      |   1 +
 .../package_manager_bypass.services.yml       |   9 --
 .../PackageManagerBypassServiceProvider.php   |  30 +++-
 .../src/Functional/ExcludedPathsTest.php      | 120 ++++++++++++++
 src/Event/ExcludedPathsSubscriber.php         | 133 +--------------
 19 files changed, 343 insertions(+), 145 deletions(-)
 create mode 100644 package_manager/src/EventSubscriber/ExcludedPathsSubscriber.php
 create mode 100644 package_manager/tests/fixtures/fake_site/composer.json
 create mode 100644 package_manager/tests/fixtures/fake_site/private/ignore.txt
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/default/services.yml
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/default/settings.local.php
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/default/settings.php
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/default/stage.txt
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/example.com/files/ignore.txt
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/example.com/services.yml
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/example.com/settings.local.php
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/example.com/settings.php
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/simpletest/ignore.txt
 create mode 100644 package_manager/tests/fixtures/fake_site/vendor/web.config
 delete mode 100644 package_manager/tests/modules/package_manager_bypass/package_manager_bypass.services.yml
 create mode 100644 package_manager/tests/src/Functional/ExcludedPathsTest.php

diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml
index 00d750a36e..d4f600641c 100644
--- a/automatic_updates.services.yml
+++ b/automatic_updates.services.yml
@@ -27,10 +27,6 @@ services:
   automatic_updates.excluded_paths_subscriber:
     class: Drupal\automatic_updates\Event\ExcludedPathsSubscriber
     arguments:
-      - '%app.root%'
-      - '%site.path%'
-      - '@file_system'
-      - '@stream_wrapper_manager'
       - '@extension.list.module'
     tags:
       - { name: event_subscriber }
diff --git a/package_manager/package_manager.services.yml b/package_manager/package_manager.services.yml
index 60a8d6d519..59bfe79c0e 100644
--- a/package_manager/package_manager.services.yml
+++ b/package_manager/package_manager.services.yml
@@ -124,3 +124,12 @@ services:
       - '@string_translation'
     tags:
       - { name: event_subscriber }
+  package_manager.excluded_paths_subscriber:
+    class: Drupal\package_manager\EventSubscriber\ExcludedPathsSubscriber
+    arguments:
+      - '%app.root%'
+      - '%site.path%'
+      - '@file_system'
+      - '@stream_wrapper_manager'
+    tags:
+      - { name: event_subscriber }
diff --git a/package_manager/src/EventSubscriber/ExcludedPathsSubscriber.php b/package_manager/src/EventSubscriber/ExcludedPathsSubscriber.php
new file mode 100644
index 0000000000..f7e601c3f0
--- /dev/null
+++ b/package_manager/src/EventSubscriber/ExcludedPathsSubscriber.php
@@ -0,0 +1,151 @@
+<?php
+
+namespace Drupal\package_manager\EventSubscriber;
+
+use Drupal\Core\File\FileSystemInterface;
+use Drupal\Core\StreamWrapper\LocalStream;
+use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
+use Drupal\package_manager\Event\PreApplyEvent;
+use Drupal\package_manager\Event\PreCreateEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Defines an event subscriber to exclude certain paths from staging areas.
+ */
+class ExcludedPathsSubscriber implements EventSubscriberInterface {
+
+  /**
+   * The Drupal root.
+   *
+   * @var string
+   */
+  protected $appRoot;
+
+  /**
+   * The current site path, relative to the Drupal root.
+   *
+   * @var string
+   */
+  protected $sitePath;
+
+  /**
+   * The file system service.
+   *
+   * @var \Drupal\Core\File\FileSystemInterface
+   */
+  protected $fileSystem;
+
+  /**
+   * The stream wrapper manager service.
+   *
+   * @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
+   */
+  protected $streamWrapperManager;
+
+  /**
+   * Constructs an UpdateSubscriber.
+   *
+   * @param string $app_root
+   *   The Drupal root.
+   * @param string $site_path
+   *   The current site path, relative to the Drupal root.
+   * @param \Drupal\Core\File\FileSystemInterface $file_system
+   *   The file system service.
+   * @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager
+   *   The stream wrapper manager service.
+   */
+  public function __construct(string $app_root, string $site_path, FileSystemInterface $file_system, StreamWrapperManagerInterface $stream_wrapper_manager) {
+    $this->appRoot = $app_root;
+    $this->sitePath = $site_path;
+    $this->fileSystem = $file_system;
+    $this->streamWrapperManager = $stream_wrapper_manager;
+  }
+
+  /**
+   * Reacts before staged changes are committed the active directory.
+   *
+   * @param \Drupal\package_manager\Event\PreApplyEvent $event
+   *   The event object.
+   */
+  public function preApply(PreApplyEvent $event): void {
+    // Don't copy anything from the staging area's sites/default.
+    // @todo Make this a lot smarter in https://www.drupal.org/i/3228955.
+    $event->excludePath('sites/default');
+
+    // If the core-vendor-hardening plugin (used in the legacy-project template)
+    // is present, it may have written a web.config file into the vendor
+    // directory. We don't want to copy that.
+    $event->excludePath('web.config');
+  }
+
+  /**
+   * Excludes paths from a staging area before it is created.
+   *
+   * @param \Drupal\package_manager\Event\PreCreateEvent $event
+   *   The event object.
+   */
+  public function preCreate(PreCreateEvent $event): void {
+    // Automated test site directories should never be staged.
+    $event->excludePath('sites/simpletest');
+
+    // Windows server configuration files, like web.config, should never be
+    // staged either. (These can be written in the vendor directory by the
+    // core-vendor-hardening plugin, which is used in the drupal/legacy-project
+    // template.)
+    $event->excludePath('web.config');
+
+    if ($public = $this->getFilesPath('public')) {
+      $event->excludePath($public);
+    }
+    if ($private = $this->getFilesPath('private')) {
+      $event->excludePath($private);
+    }
+
+    // Exclude site-specific settings files.
+    $settings_files = [
+      'settings.php',
+      'settings.local.php',
+      'services.yml',
+    ];
+    $default_site = 'sites' . DIRECTORY_SEPARATOR . 'default';
+
+    foreach ($settings_files as $settings_file) {
+      $event->excludePath($this->sitePath . DIRECTORY_SEPARATOR . $settings_file);
+      $event->excludePath($default_site . DIRECTORY_SEPARATOR . $settings_file);
+    }
+  }
+
+  /**
+   * Returns the storage path for a stream wrapper.
+   *
+   * This will only work for stream wrappers that extend
+   * \Drupal\Core\StreamWrapper\LocalStream, which includes the stream wrappers
+   * for public and private files.
+   *
+   * @param string $scheme
+   *   The stream wrapper scheme.
+   *
+   * @return string|null
+   *   The storage path for files using the given scheme, relative to the Drupal
+   *   root, or NULL if the stream wrapper does not extend
+   *   \Drupal\Core\StreamWrapper\LocalStream.
+   */
+  private function getFilesPath(string $scheme): ?string {
+    $wrapper = $this->streamWrapperManager->getViaScheme($scheme);
+    if ($wrapper instanceof LocalStream) {
+      return $wrapper->getDirectoryPath();
+    }
+    return NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    return [
+      PreCreateEvent::class => 'preCreate',
+      PreApplyEvent::class => 'preApply',
+    ];
+  }
+
+}
diff --git a/package_manager/tests/fixtures/fake_site/composer.json b/package_manager/tests/fixtures/fake_site/composer.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/composer.json
@@ -0,0 +1 @@
+{}
diff --git a/package_manager/tests/fixtures/fake_site/private/ignore.txt b/package_manager/tests/fixtures/fake_site/private/ignore.txt
new file mode 100644
index 0000000000..08874eba8b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/private/ignore.txt
@@ -0,0 +1 @@
+This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/sites/default/services.yml b/package_manager/tests/fixtures/fake_site/sites/default/services.yml
new file mode 100644
index 0000000000..e11552b41d
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/default/services.yml
@@ -0,0 +1 @@
+# This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/sites/default/settings.local.php b/package_manager/tests/fixtures/fake_site/sites/default/settings.local.php
new file mode 100644
index 0000000000..15b43d2812
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/default/settings.local.php
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * This file should never be staged.
+ */
diff --git a/package_manager/tests/fixtures/fake_site/sites/default/settings.php b/package_manager/tests/fixtures/fake_site/sites/default/settings.php
new file mode 100644
index 0000000000..15b43d2812
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/default/settings.php
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * This file should never be staged.
+ */
diff --git a/package_manager/tests/fixtures/fake_site/sites/default/stage.txt b/package_manager/tests/fixtures/fake_site/sites/default/stage.txt
new file mode 100644
index 0000000000..0087269e33
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/default/stage.txt
@@ -0,0 +1 @@
+This file should be staged.
diff --git a/package_manager/tests/fixtures/fake_site/sites/example.com/files/ignore.txt b/package_manager/tests/fixtures/fake_site/sites/example.com/files/ignore.txt
new file mode 100644
index 0000000000..08874eba8b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/example.com/files/ignore.txt
@@ -0,0 +1 @@
+This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/sites/example.com/services.yml b/package_manager/tests/fixtures/fake_site/sites/example.com/services.yml
new file mode 100644
index 0000000000..e11552b41d
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/example.com/services.yml
@@ -0,0 +1 @@
+# This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/sites/example.com/settings.local.php b/package_manager/tests/fixtures/fake_site/sites/example.com/settings.local.php
new file mode 100644
index 0000000000..15b43d2812
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/example.com/settings.local.php
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * This file should never be staged.
+ */
diff --git a/package_manager/tests/fixtures/fake_site/sites/example.com/settings.php b/package_manager/tests/fixtures/fake_site/sites/example.com/settings.php
new file mode 100644
index 0000000000..15b43d2812
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/example.com/settings.php
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * This file should never be staged.
+ */
diff --git a/package_manager/tests/fixtures/fake_site/sites/simpletest/ignore.txt b/package_manager/tests/fixtures/fake_site/sites/simpletest/ignore.txt
new file mode 100644
index 0000000000..08874eba8b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/simpletest/ignore.txt
@@ -0,0 +1 @@
+This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/vendor/web.config b/package_manager/tests/fixtures/fake_site/vendor/web.config
new file mode 100644
index 0000000000..08874eba8b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/vendor/web.config
@@ -0,0 +1 @@
+This file should never be staged.
diff --git a/package_manager/tests/modules/package_manager_bypass/package_manager_bypass.services.yml b/package_manager/tests/modules/package_manager_bypass/package_manager_bypass.services.yml
deleted file mode 100644
index 42e9234669..0000000000
--- a/package_manager/tests/modules/package_manager_bypass/package_manager_bypass.services.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-services:
-  package_manager_bypass.committer:
-    public: false
-    class: Drupal\package_manager_bypass\Committer
-    decorates: package_manager.committer
-    arguments:
-      - '@package_manager_bypass.committer.inner'
-    properties:
-      - { _serviceId: package_manager.committer }
diff --git a/package_manager/tests/modules/package_manager_bypass/src/PackageManagerBypassServiceProvider.php b/package_manager/tests/modules/package_manager_bypass/src/PackageManagerBypassServiceProvider.php
index 2e9ad4812b..3394cf4e15 100644
--- a/package_manager/tests/modules/package_manager_bypass/src/PackageManagerBypassServiceProvider.php
+++ b/package_manager/tests/modules/package_manager_bypass/src/PackageManagerBypassServiceProvider.php
@@ -4,6 +4,8 @@ namespace Drupal\package_manager_bypass;
 
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\ServiceProviderBase;
+use Drupal\Core\Site\Settings;
+use Symfony\Component\DependencyInjection\Reference;
 
 /**
  * Defines services to bypass Package Manager's core functionality.
@@ -16,10 +18,30 @@ class PackageManagerBypassServiceProvider extends ServiceProviderBase {
   public function alter(ContainerBuilder $container) {
     parent::alter($container);
 
-    $container->getDefinition('package_manager.beginner')
-      ->setClass(Beginner::class);
-    $container->getDefinition('package_manager.stager')
-      ->setClass(Stager::class);
+    // By default, bypass the Composer Stager library. This can be disabled for
+    // tests that want to use the real library, but only need to disable
+    // validators.
+    if (Settings::get('package_manager_bypass_stager', TRUE)) {
+      $container->getDefinition('package_manager.beginner')
+        ->setClass(Beginner::class);
+      $container->getDefinition('package_manager.stager')
+        ->setClass(Stager::class);
+
+      $container->register('package_manager_bypass.committer')
+        ->setClass(Committer::class)
+        ->setPublic(FALSE)
+        ->setDecoratedService('package_manager.committer')
+        ->setArguments([
+          new Reference('package_manager_bypass.committer.inner'),
+        ])
+        ->setProperty('_serviceId', 'package_manager.committer');
+    }
+
+    // Allow functional tests to disable specific validators as necessary.
+    // Kernel tests can override the ::register() method and modify the
+    // container directly.
+    $validators = Settings::get('package_manager_bypass_validators', []);
+    array_walk($validators, [$container, 'removeDefinition']);
   }
 
 }
diff --git a/package_manager/tests/src/Functional/ExcludedPathsTest.php b/package_manager/tests/src/Functional/ExcludedPathsTest.php
new file mode 100644
index 0000000000..3dae832352
--- /dev/null
+++ b/package_manager/tests/src/Functional/ExcludedPathsTest.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace Drupal\Tests\package_manager\Functional;
+
+use Drupal\Core\Site\Settings;
+use Drupal\package_manager\PathLocator;
+use Drupal\package_manager\Stage;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * @covers \Drupal\package_manager\EventSubscriber\ExcludedPathsSubscriber
+ *
+ * @group package_manager
+ */
+class ExcludedPathsTest extends BrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'package_manager',
+    'package_manager_bypass',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function prepareSettings() {
+    parent::prepareSettings();
+
+    // Disable the filesystem permissions validator, since we cannot guarantee
+    // that the current code base will be writable in all testing situations.
+    // We test this validator functionally in Automatic Updates' build tests,
+    // since those do give us control over the filesystem permissions.
+    // @see \Drupal\Tests\automatic_updates\Build\CoreUpdateTest::assertReadOnlyFileSystemError()
+    // @see \Drupal\Tests\package_manager\Kernel\WritableFileSystemValidatorTest
+    $this->writeSettings([
+      'settings' => [
+        'package_manager_bypass_stager' => (object) [
+          'value' => FALSE,
+          'required' => TRUE,
+        ],
+        'package_manager_bypass_validators' => (object) [
+          'value' => ['package_manager.validator.file_system'],
+          'required' => TRUE,
+        ],
+      ],
+    ]);
+  }
+
+  /**
+   * Tests that certain paths are excluded from staging areas.
+   */
+  public function testExcludedPaths(): void {
+    $active_dir = __DIR__ . '/../../fixtures/fake_site';
+    $stage_dir = $this->siteDirectory . '/stage';
+
+    $path_locator = $this->prophesize(PathLocator::class);
+    $path_locator->getActiveDirectory()->willReturn($active_dir);
+    $path_locator->getStageDirectory()->willReturn($stage_dir);
+
+    // Ensure that we are using directories within the fake site fixture for
+    // public and private files.
+    $settings = Settings::getAll();
+    $settings['file_public_path'] = 'sites/example.com/files';
+    $settings['file_private_path'] = 'private';
+    new Settings($settings);
+
+    /** @var \Drupal\package_manager\EventSubscriber\ExcludedPathsSubscriber $subscriber */
+    $subscriber = $this->container->get('package_manager.excluded_paths_subscriber');
+    $reflector = new \ReflectionObject($subscriber);
+    $property = $reflector->getProperty('sitePath');
+    $property->setAccessible(TRUE);
+    $property->setValue($subscriber, 'sites/example.com');
+
+    $stage = new Stage(
+      $path_locator->reveal(),
+      $this->container->get('package_manager.beginner'),
+      $this->container->get('package_manager.stager'),
+      $this->container->get('package_manager.committer'),
+      $this->container->get('package_manager.cleaner'),
+      $this->container->get('event_dispatcher')
+    );
+    $stage->create();
+
+    $this->assertDirectoryExists($stage_dir);
+    $this->assertDirectoryNotExists("$stage_dir/sites/simpletest");
+    $this->assertFileNotExists("$stage_dir/vendor/web.config");
+    $this->assertDirectoryNotExists("$stage_dir/sites/example.com/files");
+    $this->assertDirectoryNotExists("$stage_dir/private");
+    $this->assertFileNotExists("$stage_dir/sites/example.com/settings.php");
+    $this->assertFileNotExists("$stage_dir/sites/example.com/settings.local.php");
+    $this->assertFileNotExists("$stage_dir/sites/example.com/services.yml");
+    $this->assertFileNotExists("$stage_dir/sites/default/settings.php");
+    $this->assertFileNotExists("$stage_dir/sites/default/settings.local.php");
+    $this->assertFileNotExists("$stage_dir/sites/default/services.yml");
+    // A non-excluded file in the default site directory should be staged.
+    $this->assertFileExists("$stage_dir/sites/default/stage.txt");
+
+    $files = [
+      'sites/default/no-copy.txt',
+      'web.config',
+    ];
+    foreach ($files as $file) {
+      $file = "$stage_dir/$file";
+      touch($file);
+      $this->assertFileExists($file);
+    }
+    $stage->apply();
+    foreach ($files as $file) {
+      $this->assertFileNotExists("$active_dir/$file");
+    }
+  }
+
+}
diff --git a/src/Event/ExcludedPathsSubscriber.php b/src/Event/ExcludedPathsSubscriber.php
index e7cc8ec17d..bb0eda8087 100644
--- a/src/Event/ExcludedPathsSubscriber.php
+++ b/src/Event/ExcludedPathsSubscriber.php
@@ -2,11 +2,8 @@
 
 namespace Drupal\automatic_updates\Event;
 
+use Drupal\automatic_updates\Updater;
 use Drupal\Core\Extension\ModuleExtensionList;
-use Drupal\Core\File\FileSystemInterface;
-use Drupal\Core\StreamWrapper\LocalStream;
-use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
-use Drupal\package_manager\Event\PreApplyEvent;
 use Drupal\package_manager\Event\PreCreateEvent;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
@@ -15,34 +12,6 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  */
 class ExcludedPathsSubscriber implements EventSubscriberInterface {
 
-  /**
-   * The Drupal root.
-   *
-   * @var string
-   */
-  protected $appRoot;
-
-  /**
-   * The current site path, relative to the Drupal root.
-   *
-   * @var string
-   */
-  protected $sitePath;
-
-  /**
-   * The file system service.
-   *
-   * @var \Drupal\Core\File\FileSystemInterface
-   */
-  protected $fileSystem;
-
-  /**
-   * The stream wrapper manager service.
-   *
-   * @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
-   */
-  protected $streamWrapperManager;
-
   /**
    * The module list service.
    *
@@ -53,42 +22,13 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface {
   /**
    * Constructs an UpdateSubscriber.
    *
-   * @param string $app_root
-   *   The Drupal root.
-   * @param string $site_path
-   *   The current site path, relative to the Drupal root.
-   * @param \Drupal\Core\File\FileSystemInterface $file_system
-   *   The file system service.
-   * @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager
-   *   The stream wrapper manager service.
    * @param \Drupal\Core\Extension\ModuleExtensionList $module_list
    *   The module list service.
    */
-  public function __construct(string $app_root, string $site_path, FileSystemInterface $file_system, StreamWrapperManagerInterface $stream_wrapper_manager, ModuleExtensionList $module_list) {
-    $this->appRoot = $app_root;
-    $this->sitePath = $site_path;
-    $this->fileSystem = $file_system;
-    $this->streamWrapperManager = $stream_wrapper_manager;
+  public function __construct(ModuleExtensionList $module_list) {
     $this->moduleList = $module_list;
   }
 
-  /**
-   * Reacts before staged updates are committed the active directory.
-   *
-   * @param \Drupal\package_manager\Event\PreApplyEvent $event
-   *   The event object.
-   */
-  public function preApply(PreApplyEvent $event): void {
-    // Don't copy anything from the staging area's sites/default.
-    // @todo Make this a lot smarter in https://www.drupal.org/i/3228955.
-    $event->excludePath('sites/default');
-
-    // If the core-vendor-hardening plugin (used in the legacy-project template)
-    // is present, it may have written a web.config file into the vendor
-    // directory. We don't want to copy that.
-    $event->excludePath('web.config');
-  }
-
   /**
    * Reacts to the beginning of an update process.
    *
@@ -96,74 +36,12 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface {
    *   The event object.
    */
   public function preCreate(PreCreateEvent $event): void {
-    // Automated test site directories should never be staged.
-    $event->excludePath('sites/simpletest');
-
-    // Windows server configuration files, like web.config, should never be
-    // staged either. (These can be written in the vendor directory by the
-    // core-vendor-hardening plugin, which is used in the drupal/legacy-project
-    // template.)
-    $event->excludePath('web.config');
-
-    if ($public = $this->getFilesPath('public')) {
-      $event->excludePath($public);
-    }
-    if ($private = $this->getFilesPath('private')) {
-      $event->excludePath($private);
-    }
-    // If this module is a git clone, exclude it.
-    if (is_dir(__DIR__ . '/../../.git')) {
+    // If we are doing an automatic update and this module is a git clone,
+    // exclude it.
+    if ($event->getStage() instanceof Updater && is_dir(__DIR__ . '/../../.git')) {
       $dir = $this->moduleList->getPath('automatic_updates');
       $event->excludePath($dir);
     }
-
-    // Exclude site-specific settings files.
-    $settings_files = [
-      'settings.php',
-      'settings.local.php',
-      'services.yml',
-    ];
-    foreach ($settings_files as $settings_file) {
-      $file_path = implode(DIRECTORY_SEPARATOR, [
-        $this->appRoot,
-        $this->sitePath,
-        $settings_file,
-      ]);
-      $file_path = $this->fileSystem->realpath($file_path);
-      if (file_exists($file_path)) {
-        $event->excludePath($file_path);
-      }
-
-      $default_file_path = implode(DIRECTORY_SEPARATOR, [
-        'sites',
-        'default',
-        $settings_file,
-      ]);
-      $event->excludePath($default_file_path);
-    }
-  }
-
-  /**
-   * Returns the storage path for a stream wrapper.
-   *
-   * This will only work for stream wrappers that extend
-   * \Drupal\Core\StreamWrapper\LocalStream, which includes the stream wrappers
-   * for public and private files.
-   *
-   * @param string $scheme
-   *   The stream wrapper scheme.
-   *
-   * @return string|null
-   *   The storage path for files using the given scheme, relative to the Drupal
-   *   root, or NULL if the stream wrapper does not extend
-   *   \Drupal\Core\StreamWrapper\LocalStream.
-   */
-  private function getFilesPath(string $scheme): ?string {
-    $wrapper = $this->streamWrapperManager->getViaScheme($scheme);
-    if ($wrapper instanceof LocalStream) {
-      return $wrapper->getDirectoryPath();
-    }
-    return NULL;
   }
 
   /**
@@ -172,7 +50,6 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface {
   public static function getSubscribedEvents() {
     return [
       PreCreateEvent::class => 'preCreate',
-      PreApplyEvent::class => 'preApply',
     ];
   }
 
-- 
GitLab