Bläddra i källkod

Merge branch 'master' of https://github.com/composer/composer.git

Nicolas TONIAZZI 12 år sedan
förälder
incheckning
0d5bdf4986

+ 1 - 0
.travis.yml

@@ -4,6 +4,7 @@ php:
   - 5.3.3
   - 5.3
   - 5.4
+  - 5.5
 
 before_script: composer install
 

+ 12 - 0
doc/03-cli.md

@@ -78,6 +78,8 @@ resolution.
   `require-dev`.
 * **--no-scripts:** Skips execution of scripts defined in `composer.json`.
 * **--no-custom-installers:** Disables custom installers.
+* **--no-progress:** Removes the progress display that can mess with some
+  terminals or scripts which don't handle backspace characters.
 * **--optimize-autoloader (-o):** Convert PSR-0 autoloading to classmap to get a faster
   autoloader. This is recommended especially for production, but can take
   a bit of time to run so it is currently not done by default.
@@ -96,6 +98,10 @@ If you just want to update a few packages and not all, you can list them as such
 
     $ php composer.phar update vendor/package vendor/package2
 
+You can also use wildcards to update a bunch of packages at once:
+
+    $ php composer.phar update vendor/*
+
 ### Options
 
 * **--prefer-source:** Install packages from `source` when available.
@@ -104,6 +110,8 @@ If you just want to update a few packages and not all, you can list them as such
 * **--dev:** Install packages listed in `require-dev`.
 * **--no-scripts:** Skips execution of scripts defined in `composer.json`.
 * **--no-custom-installers:** Disables custom installers.
+* **--no-progress:** Removes the progress display that can mess with some
+  terminals or scripts which don't handle backspace characters.
 * **--optimize-autoloader (-o):** Convert PSR-0 autoloading to classmap to get a faster
   autoloader. This is recommended especially for production, but can take
   a bit of time to run so it is currently not done by default.
@@ -129,6 +137,8 @@ to the command.
 * **--prefer-dist:** Install packages from `dist` when available.
 * **--dev:** Add packages to `require-dev`.
 * **--no-update:** Disables the automatic update of the dependencies.
+* **--no-progress:** Removes the progress display that can mess with some
+  terminals or scripts which don't handle backspace characters.
 
 ## search
 
@@ -311,6 +321,8 @@ By default the command checks for the packages on packagist.org.
 * **--no-custom-installers:** Disables custom installers.
 * **--no-scripts:** Disables the execution of the scripts defined in the root
   package.
+* **--no-progress:** Removes the progress display that can mess with some
+  terminals or scripts which don't handle backspace characters.
 * **--keep-vcs:** Skip the deletion of the VCS metadata for the created
   project. This is mostly useful if you run the command in non-interactive
   mode.

+ 28 - 33
src/Composer/Autoload/AutoloadGenerator.php

@@ -178,18 +178,13 @@ EOF;
     public function buildPackageMap(InstallationManager $installationManager, PackageInterface $mainPackage, array $packages)
     {
         // build package => install path map
-        $packageMap = array();
-        array_unshift($packages, $mainPackage);
+        $packageMap = array(array($mainPackage, ''));
 
         foreach ($packages as $package) {
             if ($package instanceof AliasPackage) {
                 continue;
             }
 
-            if ($package === $mainPackage) {
-                $packageMap[] = array($mainPackage, '');
-                continue;
-            }
             $packageMap[] = array(
                 $package,
                 $installationManager->getInstallPath($package)
@@ -208,7 +203,10 @@ EOF;
      */
     public function parseAutoloads(array $packageMap, PackageInterface $mainPackage)
     {
+        $mainPackageMap = array_shift($packageMap);
         $sortedPackageMap = $this->sortPackageMap($packageMap);
+        $sortedPackageMap[] = $mainPackageMap;
+        array_unshift($packageMap, $mainPackageMap);
 
         $psr0 = $this->parseAutoloadsType($packageMap, 'psr-0', $mainPackage);
         $classmap = $this->parseAutoloadsType($sortedPackageMap, 'classmap', $mainPackage);
@@ -359,12 +357,12 @@ class ComposerAutoloaderInit$suffix
 
     public static function getLoader()
     {
-        if (null !== static::\$loader) {
-            return static::\$loader;
+        if (null !== self::\$loader) {
+            return self::\$loader;
         }
 
         spl_autoload_register(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'));
-        static::\$loader = \$loader = new \\Composer\\Autoload\\ClassLoader();
+        self::\$loader = \$loader = new \\Composer\\Autoload\\ClassLoader();
         spl_autoload_unregister(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'));
 
         \$vendorDir = $vendorPathCode;
@@ -434,6 +432,7 @@ FOOTER;
     protected function parseAutoloadsType(array $packageMap, $type, PackageInterface $mainPackage)
     {
         $autoloads = array();
+
         foreach ($packageMap as $item) {
             list($package, $installPath) = $item;
 
@@ -465,49 +464,45 @@ FOOTER;
 
     protected function sortPackageMap(array $packageMap)
     {
-        $groups = array();
+        $positions = array();
         $names = array();
-        foreach ($packageMap as $key => $item) {
-            $groups[$key] = array($item);
+        $indexes = array();
+
+        foreach ($packageMap as $position => $item) {
             $mainName = $item[0]->getName();
-            foreach ($item[0]->getNames() as $name) {
-                if (!isset($names[$name])) {
-                    $names[$name] = $name == $mainName ? $key : $mainName;
-                }
-            }
+            $names = array_merge(array_fill_keys($item[0]->getNames(), $mainName), $names);
+            $names[$mainName] = $mainName;
+            $indexes[$mainName] = $positions[$mainName] = $position;
         }
 
         foreach ($packageMap as $item) {
+            $position = $positions[$item[0]->getName()];
             foreach (array_merge($item[0]->getRequires(), $item[0]->getDevRequires()) as $link) {
                 $target = $link->getTarget();
                 if (!isset($names[$target])) {
                     continue;
                 }
 
-                $targetKey = $names[$target];
-                if (is_string($targetKey)) {
-                    if (!isset($names[$targetKey])) {
-                        continue;
-                    }
-                    $targetKey = $names[$targetKey];
-                }
-
-                $packageKey = $names[$item[0]->getName()];
-                if ($targetKey <= $packageKey || !isset($groups[$packageKey])) {
+                $target = $names[$target];
+                if ($positions[$target] <= $position) {
                     continue;
                 }
 
-                foreach ($groups[$packageKey] as $originalItem) {
-                    $groups[$targetKey][] = $originalItem;
-                    $names[$originalItem[0]->getName()] = $targetKey;
+                foreach ($positions as $key => $value) {
+                    if ($value >= $position) {
+                        break;
+                    }
+                    $positions[$key]--;
                 }
-                unset($groups[$packageKey]);
+
+                $positions[$target] = $position - 1;
             }
+            asort($positions);
         }
 
         $sortedPackageMap = array();
-        foreach ($groups as $group) {
-            $sortedPackageMap = array_merge($sortedPackageMap, $group);
+        foreach (array_keys($positions) as $packageName) {
+            $sortedPackageMap[] = $packageMap[$indexes[$packageName]];
         }
 
         return $sortedPackageMap;

+ 6 - 1
src/Composer/Autoload/ClassMapGenerator.php

@@ -121,7 +121,12 @@ class ClassMapGenerator
             $contents = preg_replace('{^.+?<\?}s', '<?', $contents);
         }
         // strip non-php blocks in the file
-        $contents = preg_replace('{\?>.*<\?}s', '', $contents);
+        $contents = preg_replace('{\?>.+<\?}s', '?><?', $contents);
+        // strip trailing non-php code if needed
+        $pos = strrpos($contents, '?>');
+        if (false !== $pos && false === strpos(substr($contents, $pos), '<?')) {
+            $contents = substr($contents, 0, $pos);
+        }
 
         preg_match_all('{
             (?:

+ 6 - 3
src/Composer/Command/CreateProjectCommand.php

@@ -60,6 +60,7 @@ class CreateProjectCommand extends Command
                 new InputOption('dev', null, InputOption::VALUE_NONE, 'Whether to install dependencies for development.'),
                 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'Whether to disable custom installers.'),
                 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Whether to prevent execution of all defined scripts in the root package.'),
+                new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
                 new InputOption('keep-vcs', null, InputOption::VALUE_NONE, 'Whether to prevent deletion vcs folder.'),
             ))
             ->setHelp(<<<EOT
@@ -102,11 +103,12 @@ EOT
             $input->getOption('repository-url'),
             $input->getOption('no-custom-installers'),
             $input->getOption('no-scripts'),
-            $input->getOption('keep-vcs')
+            $input->getOption('keep-vcs'),
+            $input->getOption('no-progress')
         );
     }
 
-    public function installProject(IOInterface $io, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositoryUrl = null, $disableCustomInstallers = false, $noScripts = false, $keepVcs = false)
+    public function installProject(IOInterface $io, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositoryUrl = null, $disableCustomInstallers = false, $noScripts = false, $keepVcs = false, $noProgress = false)
     {
         $config = Factory::createConfig();
 
@@ -177,7 +179,8 @@ EOT
 
         $dm = $this->createDownloadManager($io, $config);
         $dm->setPreferSource($preferSource)
-            ->setPreferDist($preferDist);
+            ->setPreferDist($preferDist)
+            ->setOutputProgress(!$noProgress);
 
         $projectInstaller = new ProjectInstaller($directory, $dm);
         $im = $this->createInstallationManager();

+ 5 - 0
src/Composer/Command/InitCommand.php

@@ -89,6 +89,11 @@ EOT
             unset($options['author']);
         }
 
+        if (isset($options['stability'])) {
+            $options['minimum-stability'] = $options['stability'];
+            unset($options['stability']);
+        }
+
         $options['require'] = isset($options['require']) ? $this->formatRequirements($options['require']) : new \stdClass;
         if (array() === $options['require']) {
             $options['require'] = new \stdClass;

+ 2 - 0
src/Composer/Command/InstallCommand.php

@@ -36,6 +36,7 @@ class InstallCommand extends Command
                 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of dev-require packages.'),
                 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'Disables all custom installers.'),
                 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
+                new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
                 new InputOption('verbose', 'v', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'),
                 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump')
             ))
@@ -55,6 +56,7 @@ EOT
     protected function execute(InputInterface $input, OutputInterface $output)
     {
         $composer = $this->getComposer();
+        $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
         $io = $this->getIO();
         $install = Installer::create($io, $composer);
 

+ 2 - 0
src/Composer/Command/RequireCommand.php

@@ -37,6 +37,7 @@ class RequireCommand extends InitCommand
                 new InputOption('dev', null, InputOption::VALUE_NONE, 'Add requirement to require-dev.'),
                 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
                 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
+                new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
                 new InputOption('no-update', null, InputOption::VALUE_NONE, 'Disables the automatic update of the dependencies.'),
             ))
             ->setHelp(<<<EOT
@@ -92,6 +93,7 @@ EOT
 
         // Update packages
         $composer = $this->getComposer();
+        $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
         $io = $this->getIO();
         $install = Installer::create($io, $composer);
 

+ 2 - 0
src/Composer/Command/UpdateCommand.php

@@ -36,6 +36,7 @@ class UpdateCommand extends Command
                 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of dev-require packages.'),
                 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'Disables all custom installers.'),
                 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
+                new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
                 new InputOption('verbose', 'v', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'),
                 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump')
             ))
@@ -58,6 +59,7 @@ EOT
     protected function execute(InputInterface $input, OutputInterface $output)
     {
         $composer = $this->getComposer();
+        $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
         $io = $this->getIO();
         $install = Installer::create($io, $composer);
 

+ 16 - 0
src/Composer/Downloader/DownloadManager.php

@@ -64,6 +64,22 @@ class DownloadManager
         return $this;
     }
 
+    /**
+     * Sets whether to output download progress information for all registered
+     * downloaders
+     *
+     * @param  bool            $outputProgress
+     * @return DownloadManager
+     */
+    public function setOutputProgress($outputProgress)
+    {
+        foreach ($this->downloaders as $downloader) {
+            $downloader->setOutputProgress($outputProgress);
+        }
+
+        return $this;
+    }
+
     /**
      * Sets installer downloader for a specific installation type.
      *

+ 8 - 0
src/Composer/Downloader/DownloaderInterface.php

@@ -53,4 +53,12 @@ interface DownloaderInterface
      * @param string           $path    download path
      */
     public function remove(PackageInterface $package, $path);
+
+    /**
+     * Sets whether to output download progress information or not
+     *
+     * @param  bool                $outputProgress
+     * @return DownloaderInterface
+     */
+    public function setOutputProgress($outputProgress);
 }

+ 18 - 2
src/Composer/Downloader/FileDownloader.php

@@ -36,6 +36,7 @@ class FileDownloader implements DownloaderInterface
     protected $rfs;
     protected $filesystem;
     protected $cache;
+    protected $outputProgress = true;
 
     /**
      * Constructor.
@@ -94,10 +95,15 @@ class FileDownloader implements DownloaderInterface
         try {
             try {
                 if (!$this->cache || !$this->cache->copyTo($this->getCacheKey($package), $fileName)) {
-                    $this->rfs->copy($hostname, $processedUrl, $fileName);
+                    $this->rfs->copy($hostname, $processedUrl, $fileName, $this->outputProgress);
+                    if (!$this->outputProgress) {
+                        $this->io->write('    Downloading');
+                    }
                     if ($this->cache) {
                         $this->cache->copyFrom($this->getCacheKey($package), $fileName);
                     }
+                } else {
+                    $this->io->write('    Loading from cache');
                 }
             } catch (TransportException $e) {
                 if (404 === $e->getCode() && 'github.com' === $hostname) {
@@ -108,7 +114,7 @@ class FileDownloader implements DownloaderInterface
                     ) {
                         throw $e;
                     }
-                    $this->rfs->copy($hostname, $processedUrl, $fileName);
+                    $this->rfs->copy($hostname, $processedUrl, $fileName, $this->outputProgress);
                 } else {
                     throw $e;
                 }
@@ -131,6 +137,16 @@ class FileDownloader implements DownloaderInterface
         }
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    public function setOutputProgress($outputProgress)
+    {
+        $this->outputProgress = $outputProgress;
+
+        return $this;
+    }
+
     protected function clearCache(PackageInterface $package, $path)
     {
         if ($this->cache) {

+ 9 - 0
src/Composer/Downloader/VcsDownloader.php

@@ -132,6 +132,15 @@ abstract class VcsDownloader implements DownloaderInterface
         }
     }
 
+    /**
+     * Download progress information is not available for all VCS downloaders.
+     * {@inheritDoc}
+     */
+    public function setOutputProgress($outputProgress)
+    {
+        return $this;
+    }
+
     /**
      * Prompt the user to check if changes should be stashed/removed or the operation aborted
      *

+ 9 - 1
src/Composer/Installer.php

@@ -624,7 +624,15 @@ class Installer
             throw new \LogicException('isUpdateable should only be called when a whitelist is present');
         }
 
-        return isset($this->updateWhitelist[$package->getName()]);
+        foreach ($this->updateWhitelist as $whiteListedPattern => $void) {
+            $cleanedWhiteListedPattern = str_replace('\\*', '.*', preg_quote($whiteListedPattern));
+
+            if (preg_match("{^".$cleanedWhiteListedPattern."$}i", $package->getName())) {
+                return true;
+            }
+        }
+
+        return false;
     }
 
     /**

+ 4 - 1
src/Composer/Script/EventDispatcher.php

@@ -140,7 +140,10 @@ class EventDispatcher
         }
 
         $generator = new AutoloadGenerator;
-        $packages = $this->composer->getRepositoryManager()->getLocalRepository()->getPackages();
+        $packages = array_merge(
+            $this->composer->getRepositoryManager()->getLocalRepository()->getPackages(),
+            $this->composer->getRepositoryManager()->getLocalDevRepository()->getPackages()
+        );
         $packageMap = $generator->buildPackageMap($this->composer->getInstallationManager(), $package, $packages);
         $map = $generator->parseAutoloads($packageMap, $package);
         $this->loader = $generator->createLoader($map);

+ 2 - 0
src/Composer/Util/RemoteFilesystem.php

@@ -229,6 +229,8 @@ class RemoteFilesystem
 
             case STREAM_NOTIFY_AUTH_RESULT:
                 if (403 === $messageCode) {
+                    $message = "The '" . $this->fileUrl . "' URL could not be accessed: " . $message;
+
                     throw new TransportException($message, 403);
                 }
                 break;

+ 33 - 2
tests/Composer/Test/Autoload/AutoloadGeneratorTest.php

@@ -338,23 +338,26 @@ class AutoloadGeneratorTest extends TestCase
         $package = new Package('a', '1.0', '1.0');
         $package->setAutoload(array('files' => array('root.php')));
         $package->setRequires(array(new Link('a', 'z/foo')));
+        $package->setRequires(array(new Link('a', 'd/d')));
+        $package->setRequires(array(new Link('a', 'e/e')));
 
         $packages = array();
         $packages[] = $z = new Package('z/foo', '1.0', '1.0');
         $packages[] = $b = new Package('b/bar', '1.0', '1.0');
-        $packages[] = $c = new Package('c/lorem', '1.0', '1.0');
         $packages[] = $d = new Package('d/d', '1.0', '1.0');
+        $packages[] = $c = new Package('c/lorem', '1.0', '1.0');
         $packages[] = $e = new Package('e/e', '1.0', '1.0');
 
         $z->setAutoload(array('files' => array('testA.php')));
         $z->setRequires(array(new Link('z/foo', 'c/lorem')));
 
         $b->setAutoload(array('files' => array('testB.php')));
-        $b->setRequires(array(new Link('b/bar', 'c/lorem')));
+        $b->setRequires(array(new Link('b/bar', 'c/lorem'), new Link('b/bar', 'd/d')));
 
         $c->setAutoload(array('files' => array('testC.php')));
 
         $d->setAutoload(array('files' => array('testD.php')));
+        $d->setRequires(array(new Link('d/d', 'c/lorem')));
 
         $e->setAutoload(array('files' => array('testE.php')));
         $e->setRequires(array(new Link('e/e', 'c/lorem')));
@@ -521,6 +524,34 @@ EOF;
         set_include_path($oldIncludePath);
     }
 
+    public function testIncludePathsInMainPackage()
+    {
+        $package = new Package('a', '1.0', '1.0');
+        $package->setIncludePaths(array('/lib', '/src'));
+
+        $packages = array($a = new Package("a/a", "1.0", "1.0"));
+        $a->setIncludePaths(array("lib/"));
+
+        $this->repository->expects($this->once())
+            ->method("getPackages")
+            ->will($this->returnValue($packages));
+
+        mkdir($this->vendorDir."/composer", 0777, true);
+
+        $this->generator->dump($this->config, $this->repository, $package, $this->im, "composer", false, '_12');
+
+        $oldIncludePath = get_include_path();
+
+        require $this->vendorDir."/autoload.php";
+
+        $this->assertEquals(
+            $this->workingDir."/lib".PATH_SEPARATOR.$this->workingDir."/src".PATH_SEPARATOR.$this->vendorDir."/a/a/lib".PATH_SEPARATOR.$oldIncludePath,
+            get_include_path()
+        );
+
+        set_include_path($oldIncludePath);
+    }
+
     public function testIncludePathFileWithoutPathsIsSkipped()
     {
         $package = new Package('a', '1.0', '1.0');

+ 5 - 5
tests/Composer/Test/Autoload/Fixtures/autoload_real_files_by_dependency.php

@@ -15,12 +15,12 @@ class ComposerAutoloaderInitFilesAutoloadOrder
 
     public static function getLoader()
     {
-        if (null !== static::$loader) {
-            return static::$loader;
+        if (null !== self::$loader) {
+            return self::$loader;
         }
 
         spl_autoload_register(array('ComposerAutoloaderInitFilesAutoloadOrder', 'loadClassLoader'));
-        static::$loader = $loader = new \Composer\Autoload\ClassLoader();
+        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
         spl_autoload_unregister(array('ComposerAutoloaderInitFilesAutoloadOrder', 'loadClassLoader'));
 
         $vendorDir = dirname(__DIR__);
@@ -40,10 +40,10 @@ class ComposerAutoloaderInitFilesAutoloadOrder
 
         require $vendorDir . '/c/lorem/testC.php';
         require $vendorDir . '/z/foo/testA.php';
-        require $baseDir . '/root.php';
-        require $vendorDir . '/b/bar/testB.php';
         require $vendorDir . '/d/d/testD.php';
+        require $vendorDir . '/b/bar/testB.php';
         require $vendorDir . '/e/e/testE.php';
+        require $baseDir . '/root.php';
 
         return $loader;
     }

+ 4 - 4
tests/Composer/Test/Autoload/Fixtures/autoload_real_functions.php

@@ -15,12 +15,12 @@ class ComposerAutoloaderInitFilesAutoload
 
     public static function getLoader()
     {
-        if (null !== static::$loader) {
-            return static::$loader;
+        if (null !== self::$loader) {
+            return self::$loader;
         }
 
         spl_autoload_register(array('ComposerAutoloaderInitFilesAutoload', 'loadClassLoader'));
-        static::$loader = $loader = new \Composer\Autoload\ClassLoader();
+        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
         spl_autoload_unregister(array('ComposerAutoloaderInitFilesAutoload', 'loadClassLoader'));
 
         $vendorDir = dirname(__DIR__);
@@ -38,9 +38,9 @@ class ComposerAutoloaderInitFilesAutoload
 
         $loader->register();
 
-        require $baseDir . '/root.php';
         require $vendorDir . '/a/a/test.php';
         require $vendorDir . '/b/b/test2.php';
+        require $baseDir . '/root.php';
 
         return $loader;
     }

+ 3 - 3
tests/Composer/Test/Autoload/Fixtures/autoload_real_target_dir.php

@@ -15,12 +15,12 @@ class ComposerAutoloaderInitTargetDir
 
     public static function getLoader()
     {
-        if (null !== static::$loader) {
-            return static::$loader;
+        if (null !== self::$loader) {
+            return self::$loader;
         }
 
         spl_autoload_register(array('ComposerAutoloaderInitTargetDir', 'loadClassLoader'));
-        static::$loader = $loader = new \Composer\Autoload\ClassLoader();
+        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
         spl_autoload_unregister(array('ComposerAutoloaderInitTargetDir', 'loadClassLoader'));
 
         $vendorDir = dirname(__DIR__);

+ 10 - 0
tests/Composer/Test/Autoload/Fixtures/template/template_3.php

@@ -0,0 +1,10 @@
+
+class leading { }
+
+<?php echo $queryClass ?>
+
+class inner { }
+
+<?php echo $defaultLocale ?>
+
+class trailing { }

+ 48 - 0
tests/Composer/Test/Fixtures/installer/update-whitelist-patterns.test

@@ -0,0 +1,48 @@
+--TEST--
+Update with a package whitelist only updates those corresponding to the pattern
+--COMPOSER--
+{
+    "repositories": [
+        {
+            "type": "package",
+            "package": [
+                { "name": "vendor/Test-Package", "version": "2.0" },
+                { "name": "vendor/NotMe", "version": "2.0" },
+                { "name": "exact/Test-Package", "version": "2.0" },
+                { "name": "notexact/TestPackage", "version": "2.0" },
+                { "name": "all/Package1", "version": "2.0" },
+                { "name": "all/Package2", "version": "2.0" },
+                { "name": "another/another", "version": "2.0" },
+                { "name": "no/regexp", "version": "2.0" }
+            ]
+        }
+    ],
+    "require": {
+        "vendor/Test-Package": "*.*",
+        "vendor/NotMe": "*.*",
+        "exact/Test-Package": "*.*",
+        "notexact/TestPackage": "*.*",
+        "all/Package1": "*.*",
+        "all/Package2": "*.*",
+        "another/another": "*.*",
+        "no/regexp": "*.*"
+    }
+}
+--INSTALLED--
+[
+    { "name": "vendor/Test-Package", "version": "1.0" },
+    { "name": "vendor/NotMe", "version": "1.0" },
+    { "name": "exact/Test-Package", "version": "1.0" },
+    { "name": "notexact/TestPackage", "version": "1.0" },
+    { "name": "all/Package1", "version": "1.0" },
+    { "name": "all/Package2", "version": "1.0" },
+    { "name": "another/another", "version": "1.0" },
+    { "name": "no/regexp", "version": "1.0" }
+]
+--RUN--
+update vendor/Test* exact/Test-Package notexact/Test all/* no/reg?xp
+--EXPECT--
+Updating vendor/Test-Package (1.0) to vendor/Test-Package (2.0)
+Updating exact/Test-Package (1.0) to exact/Test-Package (2.0)
+Updating all/Package1 (1.0) to all/Package1 (2.0)
+Updating all/Package2 (1.0) to all/Package2 (2.0)