From e8a2a6a96fe6fd01062f6a896707399a6b734f23 Mon Sep 17 00:00:00 2001
From: xjm <xjm@65776.no-reply.drupal.org>
Date: Sat, 20 Aug 2022 14:31:58 -0500
Subject: [PATCH] Issue #3304433 by lauriii, xjm, quietone, tim.plunkett, Wim
 Leers, mherchel, andy-blum: generate-theme scripts fails in a ddev
 environment

(cherry picked from commit 3d46d27b3071af8d32cc42f0ab38e4b2b9479445)
---
 .../lib/Drupal/Core/Command/GenerateTheme.php | 25 ++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/core/lib/Drupal/Core/Command/GenerateTheme.php b/core/lib/Drupal/Core/Command/GenerateTheme.php
index e613358f2b19..bb09d380aed4 100644
--- a/core/lib/Drupal/Core/Command/GenerateTheme.php
+++ b/core/lib/Drupal/Core/Command/GenerateTheme.php
@@ -252,9 +252,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
       }
     }
 
-    if (!rename($tmp_dir, $destination)) {
-      $io->getErrorStyle()->error("The theme could not be moved to the destination: $destination.");
-      return 1;
+    if (!@rename($tmp_dir, $destination)) {
+      // If rename fails, copy the files to the destination directory. This is
+      // expected to happen when the tmp directory is on a different file
+      // system.
+      $this->copyRecursive($tmp_dir, $destination);
+
+      // Renaming would not have left anything behind. Ensure that is still the
+      // case.
+      $this->rmRecursive($tmp_dir);
     }
 
     $output->writeln(sprintf('Theme generated successfully to %s', $destination));
@@ -262,6 +268,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int
     return 0;
   }
 
+  /**
+   * Removes a directory recursively.
+   *
+   * @param string $dir
+   *   A directory to be removed.
+   */
+  private function rmRecursive(string $dir): void {
+    $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST);
+    foreach ($files as $file) {
+      is_dir($file) ? rmdir($file) : unlink($file);
+    }
+  }
+
   /**
    * Copies files recursively.
    *
-- 
GitLab