Browse Source

Extract archives into temp dir to shorten paths and avoid issues on windows, fixes #1591

Jordi Boggiano 12 years ago
parent
commit
88ae6c023b
1 changed files with 15 additions and 17 deletions
  1. 15 17
      src/Composer/Downloader/ArchiveDownloader.php

+ 15 - 17
src/Composer/Downloader/ArchiveDownloader.php

@@ -34,9 +34,12 @@ abstract class ArchiveDownloader extends FileDownloader
         if ($this->io->isVerbose()) {
             $this->io->write('    Unpacking archive');
         }
+
+        $temporaryDir = sys_get_temp_dir().'/cmp'.substr(md5(time().mt_rand()), 0, 5);
         try {
+            $this->filesystem->ensureDirectoryExists($temporaryDir);
             try {
-                $this->extract($fileName, $path);
+                $this->extract($fileName, $temporaryDir);
             } catch (\Exception $e) {
                 // remove cache if the file was corrupted
                 parent::clearCache($package, $path);
@@ -49,31 +52,26 @@ abstract class ArchiveDownloader extends FileDownloader
             unlink($fileName);
 
             // If we have only a one dir inside it suppose to be a package itself
-            $contentDir = glob($path . '/*');
+            $contentDir = glob($temporaryDir . '/*');
             if (1 === count($contentDir)) {
                 $contentDir = $contentDir[0];
+            }
 
-                if (is_file($contentDir)) {
-                    $this->filesystem->rename($contentDir, $path . '/' . basename($contentDir));
-                } else {
-                    // Rename the content directory to avoid error when moving up
-                    // a child folder with the same name
-                    $temporaryDir = sys_get_temp_dir().'/'.md5(time().mt_rand());
-                    $this->filesystem->rename($contentDir, $temporaryDir);
-                    $contentDir = $temporaryDir;
-
-                    foreach (array_merge(glob($contentDir . '/.*'), glob($contentDir . '/*')) as $file) {
-                        if (trim(basename($file), '.')) {
-                            $this->filesystem->rename($file, $path . '/' . basename($file));
-                        }
+            if (is_file($contentDir)) {
+                $this->filesystem->rename($contentDir, $path . '/' . basename($contentDir));
+            } else {
+                foreach (array_merge(glob($contentDir . '/.*'), glob($contentDir . '/*')) as $file) {
+                    if ('' !== trim(basename($file), '.')) {
+                        $this->filesystem->rename($file, $path . '/' . basename($file));
                     }
-
-                    $this->filesystem->removeDirectory($contentDir);
                 }
             }
+
+            $this->filesystem->removeDirectory($temporaryDir);
         } catch (\Exception $e) {
             // clean up
             $this->filesystem->removeDirectory($path);
+            $this->filesystem->removeDirectory($temporaryDir);
             throw $e;
         }