Browse Source

Remove use of glob, fixes #3042

Jordi Boggiano 10 years ago
parent
commit
e890d1bc59

+ 22 - 17
src/Composer/Command/SelfUpdateCommand.php

@@ -21,6 +21,7 @@ use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Finder\Finder;
 
 /**
  * @author Igor Wiedler <igor@wiedler.ch>
@@ -113,15 +114,13 @@ EOT
 
         // remove saved installations of composer
         if ($input->getOption('clean-backups')) {
-            $files = $this->getOldInstallationFiles($rollbackDir);
+            $finder = $this->getOldInstallationFinder($rollbackDir);
 
-            if (!empty($files)) {
-                $fs = new Filesystem;
-
-                foreach ($files as $file) {
-                    $output->writeln('<info>Removing: '.$file.'</info>');
-                    $fs->remove($file);
-                }
+            $fs = new Filesystem;
+            foreach ($finder as $file) {
+                $file = (string) $file;
+                $output->writeln('<info>Removing: '.$file.'</info>');
+                $fs->remove($file);
             }
         }
 
@@ -201,19 +200,25 @@ EOT
 
     protected function getLastBackupVersion($rollbackDir)
     {
-        $files = $this->getOldInstallationFiles($rollbackDir);
-        if (empty($files)) {
-            return false;
-        }
+        $finder = $this->getOldInstallationFinder($rollbackDir);
+        $finder->sortByName();
+        $files = iterator_to_array($finder);
 
-        sort($files);
+        if (count($files)) {
+            return basename(end($files), self::OLD_INSTALL_EXT);
+        }
 
-        return basename(end($files), self::OLD_INSTALL_EXT);
+        return false;
     }
 
-    protected function getOldInstallationFiles($rollbackDir)
+    protected function getOldInstallationFinder($rollbackDir)
     {
-        $fs = new Filesystem;
-        return $fs->realpathGlob($rollbackDir . '/*' . self::OLD_INSTALL_EXT);
+        $finder = Finder::create()
+            ->depth(0)
+            ->files()
+            ->name('*' . self::OLD_INSTALL_EXT)
+            ->in($dir);
+
+        return $finder;
     }
 }

+ 10 - 6
src/Composer/Downloader/ArchiveDownloader.php

@@ -13,6 +13,7 @@
 namespace Composer\Downloader;
 
 use Composer\Package\PackageInterface;
+use Symfony\Component\Finder\Finder;
 
 /**
  * Base downloader for archives
@@ -52,12 +53,13 @@ abstract class ArchiveDownloader extends FileDownloader
                 $contentDir = $this->getFolderContent($temporaryDir);
 
                 // only one dir in the archive, extract its contents out of it
-                if (1 === count($contentDir) && is_dir($contentDir[0])) {
-                    $contentDir = $this->getFolderContent($contentDir[0]);
+                if (1 === count($contentDir) && is_dir(reset($contentDir))) {
+                    $contentDir = $this->getFolderContent((string) reset($contentDir));
                 }
 
                 // move files back out of the temp dir
                 foreach ($contentDir as $file) {
+                    $file = (string) $file;
                     $this->filesystem->rename($file, $path . '/' . basename($file));
                 }
 
@@ -133,10 +135,12 @@ abstract class ArchiveDownloader extends FileDownloader
      */
     private function getFolderContent($dir)
     {
-        $files = array_merge($this->filesystem->realpathGlob($dir . '/.*'), $this->filesystem->realpathGlob($dir . '/*'));
+        $finder = Finder::create()
+            ->ignoreVCS(false)
+            ->ignoreDotFiles(false)
+            ->depth(0)
+            ->in($dir);
 
-        return array_values(array_filter($files, function ($el) {
-            return basename($el) !== '.' && basename($el) !== '..';
-        }));
+        return iterator_to_array($finder);
     }
 }

+ 15 - 32
src/Composer/Util/Filesystem.php

@@ -14,6 +14,7 @@ namespace Composer\Util;
 
 use RecursiveDirectoryIterator;
 use RecursiveIteratorIterator;
+use Symfony\Component\Finder\Finder;
 
 /**
  * @author Jordi Boggiano <j.boggiano@seld.be>
@@ -41,29 +42,6 @@ class Filesystem
         return false;
     }
 
-    /**
-     * Force the results of a glob to be realpaths.
-     *
-     * @param  string $pattern
-     * @param  int    $flags   
-     * @return array
-     */
-    public function realpathGlob($pattern, $flags = 0)
-    {
-        $matches = glob($pattern, $flags);
-        if (!$matches) {
-            return array();
-        }
-
-        return array_map(function ($path) {
-            if (basename($path) === '.' || basename($path) === '..') {
-                return $path;
-            }
-
-            return realpath($path);
-        }, $matches);
-    }
-
     /**
      * Checks if a directory is empty
      *
@@ -72,9 +50,13 @@ class Filesystem
      */
     public function isDirEmpty($dir)
     {
-        $dir = rtrim($dir, '/\\');
+        $finder = Finder::create()
+            ->ignoreVCS(false)
+            ->ignoreDotFiles(false)
+            ->depth(0)
+            ->in($dir);
 
-        return count($this->realpathGlob($dir.'/*')) === 0 && count($this->realpathGlob($dir.'/.*')) === 2;
+        return count($finder) === 0;
     }
 
     public function emptyDirectory($dir, $ensureDirectoryExists = true)
@@ -84,13 +66,14 @@ class Filesystem
         }
 
         if (is_dir($dir)) {
-            foreach ($this->realpathGlob(rtrim($dir, '\\/').'/*') as $path) {
-                $this->remove($path);
-            }
-            foreach ($this->realpathGlob(rtrim($dir, '\\/').'/.*') as $path) {
-                if (basename($path) !== '..' && basename($path) !== '.') {
-                    $this->remove($path);
-                }
+            $finder = Finder::create()
+                ->ignoreVCS(false)
+                ->ignoreDotFiles(false)
+                ->depth(0)
+                ->in($dir);
+
+            foreach ($finder as $path) {
+                $this->remove((string) $path);
             }
         }
     }