From 4c15e96da3eb3737c9ea7a60a0c81983f4da9b2c Mon Sep 17 00:00:00 2001
From: omkar podey <58183-omkar.podey@users.noreply.drupalcode.org>
Date: Wed, 19 Apr 2023 11:45:02 +0000
Subject: [PATCH] Issue #3341469 by omkar.podey, Wim Leers: Create
 StageBase::stageDirectoryExists() for improved DX to see if stage directory
 exists

---
 package_manager/package_manager.api.php          |  6 ++++++
 package_manager/src/StageBase.php                | 16 ++++++++++++++++
 .../src/Validator/StagedDBUpdateValidator.php    |  8 ++------
 .../src/Validator/SymlinkValidator.php           |  6 ++----
 .../tests/src/Kernel/StageBaseTest.php           | 10 ++++++++++
 5 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/package_manager/package_manager.api.php b/package_manager/package_manager.api.php
index 51da677192..009a49edb5 100644
--- a/package_manager/package_manager.api.php
+++ b/package_manager/package_manager.api.php
@@ -143,6 +143,12 @@
  *   post-destroy events. It is possible to destroy the stage without having
  *   claimed it first, but this shouldn't be done unless absolutely necessary.
  *
+ * - \Drupal\package_manager\StageBase::stageDirectoryExists()
+ *   Determines if the stage directory exists and returns a boolean accordingly.
+ *   This allows validators to directly know if the stage directory exists
+ *   without using \Drupal\package_manager\StageBase::getStageDirectory(), which
+ *   throws an exception if the stage directory does not exist.
+ *
  * @section sec_stage_exceptions Stage life cycle exceptions
  * If problems occur during any point of the stage life cycle, a
  * \Drupal\package_manager\Exception\StageException is thrown. If problems are
diff --git a/package_manager/src/StageBase.php b/package_manager/src/StageBase.php
index 44ac4bb846..17929ca387 100644
--- a/package_manager/src/StageBase.php
+++ b/package_manager/src/StageBase.php
@@ -738,6 +738,22 @@ abstract class StageBase implements LoggerAwareInterface {
     return $dir;
   }
 
+  /**
+   * Determines if the stage directory exists.
+   *
+   * @return bool
+   *   TRUE if the directory exists, otherwise FALSE.
+   */
+  public function stageDirectoryExists(): bool {
+    try {
+      $this->getStageDirectory();
+      return TRUE;
+    }
+    catch (\LogicException $e) {
+      return FALSE;
+    }
+  }
+
   /**
    * Checks if staged changes are being applied to the active directory.
    *
diff --git a/package_manager/src/Validator/StagedDBUpdateValidator.php b/package_manager/src/Validator/StagedDBUpdateValidator.php
index 7b2a56094a..bdbce0acb6 100644
--- a/package_manager/src/Validator/StagedDBUpdateValidator.php
+++ b/package_manager/src/Validator/StagedDBUpdateValidator.php
@@ -47,14 +47,10 @@ class StagedDBUpdateValidator implements EventSubscriberInterface {
    *   The event object.
    */
   public function checkForStagedDatabaseUpdates(StatusCheckEvent $event): void {
-    try {
-      $stage_dir = $event->stage->getStageDirectory();
-    }
-    catch (\LogicException) {
-      // Stage directory can't be determined, so there's nothing to validate.
+    if (!$event->stage->stageDirectoryExists()) {
       return;
     }
-
+    $stage_dir = $event->stage->getStageDirectory();
     $extensions_with_updates = $this->getExtensionsWithDatabaseUpdates($stage_dir);
     if ($extensions_with_updates) {
       $extensions_with_updates = array_map($this->t(...), $extensions_with_updates);
diff --git a/package_manager/src/Validator/SymlinkValidator.php b/package_manager/src/Validator/SymlinkValidator.php
index 0eb93e911d..901c20ede4 100644
--- a/package_manager/src/Validator/SymlinkValidator.php
+++ b/package_manager/src/Validator/SymlinkValidator.php
@@ -53,12 +53,10 @@ class SymlinkValidator implements EventSubscriberInterface {
     // that contains this file, which contains only a few files and no symlinks,
     // as the stage directory. The precondition itself doesn't care if the
     // directory actually exists or not.
-    try {
+    $stage_dir = __DIR__;
+    if ($event->stage->stageDirectoryExists()) {
       $stage_dir = $event->stage->getStageDirectory();
     }
-    catch (\LogicException) {
-      $stage_dir = __DIR__;
-    }
     $stage_dir = $this->pathFactory->create($stage_dir);
 
     $excluded_paths = $event->getExcludedPaths();
diff --git a/package_manager/tests/src/Kernel/StageBaseTest.php b/package_manager/tests/src/Kernel/StageBaseTest.php
index 67a80a5bef..5e25765dcc 100644
--- a/package_manager/tests/src/Kernel/StageBaseTest.php
+++ b/package_manager/tests/src/Kernel/StageBaseTest.php
@@ -651,6 +651,16 @@ class StageBaseTest extends PackageManagerKernelTestBase {
     $stage->apply();
   }
 
+  /**
+   * @covers ::stageDirectoryExists
+   */
+  public function testStageDirectoryExists(): void {
+    $stage = $this->createStage();
+    $this->assertFalse($stage->stageDirectoryExists());
+    $stage->create();
+    $this->assertTrue($stage->stageDirectoryExists());
+  }
+
 }
 
 /**
-- 
GitLab