diff --git a/core/lib/Drupal/Core/Command/GenerateTheme.php b/core/lib/Drupal/Core/Command/GenerateTheme.php index e613358f2b19cfa09d7787a37bb9b9d5e84dd869..bb09d380aed4f4911496c4f7ab96425980a7a695 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. *