Procházet zdrojové kódy

Add support for mirrors in composer repos

Jordi Boggiano před 11 roky
rodič
revize
77163f66fc

+ 24 - 4
src/Composer/Downloader/FileDownloader.php

@@ -79,18 +79,38 @@ class FileDownloader implements DownloaderInterface
      */
     public function download(PackageInterface $package, $path)
     {
-        $url = $package->getDistUrl();
-        if (!$url) {
+        if (!$package->getDistUrl()) {
             throw new \InvalidArgumentException('The given package is missing url information');
         }
 
+        $this->io->write("  - Installing <info>" . $package->getName() . "</info> (<comment>" . VersionParser::formatVersion($package) . "</comment>)");
+
+        $urls = $package->getDistUrls();
+        while ($url = array_shift($urls)) {
+            try {
+                $this->doDownload($package, $path, $url);
+                break;
+            } catch (\Exception $e) {
+                if ($this->io->isDebug()) {
+                    $this->io->write('');
+                    $this->io->write('Failed: ['.get_class($e).'] '.$e->getMessage());
+                } elseif (count($urls)) {
+                    $this->io->write('');
+                    $this->io->write('    Failed, trying the next URL');
+                } else {
+                    throw $e;
+                }
+            }
+        }
+    }
+
+    protected function doDownload(PackageInterface $package, $path, $url)
+    {
         $this->filesystem->removeDirectory($path);
         $this->filesystem->ensureDirectoryExists($path);
 
         $fileName = $this->getFileName($package, $path);
 
-        $this->io->write("  - Installing <info>" . $package->getName() . "</info> (<comment>" . VersionParser::formatVersion($package) . "</comment>)");
-
         $processedUrl = $this->processUrl($package, $url);
         $hostname = parse_url($processedUrl, PHP_URL_HOST);
 

+ 7 - 7
src/Composer/Downloader/GitDownloader.php

@@ -26,7 +26,7 @@ class GitDownloader extends VcsDownloader
     /**
      * {@inheritDoc}
      */
-    public function doDownload(PackageInterface $package, $path)
+    public function doDownload(PackageInterface $package, $path, $url)
     {
         $this->cleanEnv();
         $path = $this->normalizePath($path);
@@ -40,8 +40,8 @@ class GitDownloader extends VcsDownloader
             return sprintf($command, escapeshellarg($url), escapeshellarg($path), escapeshellarg($ref));
         };
 
-        $this->runCommand($commandCallable, $package->getSourceUrl(), $path, true);
-        $this->setPushUrl($package, $path);
+        $this->runCommand($commandCallable, $url, $path, true);
+        $this->setPushUrl($path, $url);
 
         if ($newRef = $this->updateToCommit($path, $ref, $package->getPrettyVersion(), $package->getReleaseDate())) {
             if ($package->getDistReference() === $package->getSourceReference()) {
@@ -54,7 +54,7 @@ class GitDownloader extends VcsDownloader
     /**
      * {@inheritDoc}
      */
-    public function doUpdate(PackageInterface $initial, PackageInterface $target, $path)
+    public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
     {
         $this->cleanEnv();
         $path = $this->normalizePath($path);
@@ -76,7 +76,7 @@ class GitDownloader extends VcsDownloader
             return sprintf($command, escapeshellarg($url));
         };
 
-        $this->runCommand($commandCallable, $target->getSourceUrl(), $path);
+        $this->runCommand($commandCallable, $url, $path);
         if ($newRef =  $this->updateToCommit($path, $ref, $target->getPrettyVersion(), $target->getReleaseDate())) {
             if ($target->getDistReference() === $target->getSourceReference()) {
                 $target->setDistReference($newRef);
@@ -412,10 +412,10 @@ class GitDownloader extends VcsDownloader
         return preg_replace('{://([^@]+?):.+?@}', '://$1:***@', $message);
     }
 
-    protected function setPushUrl(PackageInterface $package, $path)
+    protected function setPushUrl($path, $url)
     {
         // set push url for github projects
-        if (preg_match('{^(?:https?|git)://'.$this->getGitHubDomainsRegex().'/([^/]+)/([^/]+?)(?:\.git)?$}', $package->getSourceUrl(), $match)) {
+        if (preg_match('{^(?:https?|git)://'.$this->getGitHubDomainsRegex().'/([^/]+)/([^/]+?)(?:\.git)?$}', $url, $match)) {
             $protocols = $this->config->get('github-protocols');
             $pushUrl = 'git@'.$match[1].':'.$match[2].'/'.$match[3].'.git';
             if ($protocols[0] !== 'git') {

+ 4 - 4
src/Composer/Downloader/HgDownloader.php

@@ -22,9 +22,9 @@ class HgDownloader extends VcsDownloader
     /**
      * {@inheritDoc}
      */
-    public function doDownload(PackageInterface $package, $path)
+    public function doDownload(PackageInterface $package, $path, $url)
     {
-        $url = escapeshellarg($package->getSourceUrl());
+        $url = escapeshellarg($url);
         $ref = escapeshellarg($package->getSourceReference());
         $this->io->write("    Cloning ".$package->getSourceReference());
         $command = sprintf('hg clone %s %s', $url, escapeshellarg($path));
@@ -40,9 +40,9 @@ class HgDownloader extends VcsDownloader
     /**
      * {@inheritDoc}
      */
-    public function doUpdate(PackageInterface $initial, PackageInterface $target, $path)
+    public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
     {
-        $url = escapeshellarg($target->getSourceUrl());
+        $url = escapeshellarg($url);
         $ref = escapeshellarg($target->getSourceReference());
         $this->io->write("    Updating to ".$target->getSourceReference());
 

+ 2 - 4
src/Composer/Downloader/SvnDownloader.php

@@ -24,10 +24,9 @@ class SvnDownloader extends VcsDownloader
     /**
      * {@inheritDoc}
      */
-    public function doDownload(PackageInterface $package, $path)
+    public function doDownload(PackageInterface $package, $path, $url)
     {
         SvnUtil::cleanEnv();
-        $url = $package->getSourceUrl();
         $ref = $package->getSourceReference();
 
         $this->io->write("    Checking out ".$package->getSourceReference());
@@ -37,10 +36,9 @@ class SvnDownloader extends VcsDownloader
     /**
      * {@inheritDoc}
      */
-    public function doUpdate(PackageInterface $initial, PackageInterface $target, $path)
+    public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
     {
         SvnUtil::cleanEnv();
-        $url = $target->getSourceUrl();
         $ref = $target->getSourceReference();
 
         if (!is_dir($path.'/.svn')) {

+ 40 - 11
src/Composer/Downloader/VcsDownloader.php

@@ -56,7 +56,23 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
 
         $this->io->write("  - Installing <info>" . $package->getName() . "</info> (<comment>" . VersionParser::formatVersion($package) . "</comment>)");
         $this->filesystem->removeDirectory($path);
-        $this->doDownload($package, $path);
+
+        $urls = $package->getSourceUrls();
+        while ($url = array_shift($urls)) {
+            try {
+                $this->doDownload($package, $path, $url);
+                break;
+            } catch (\Exception $e) {
+                if ($this->io->isDebug()) {
+                    $this->io->write('Failed: ['.get_class($e).'] '.$e->getMessage());
+                } elseif (count($urls)) {
+                    $this->io->write('    Failed, trying the next URL');
+                } else {
+                    throw $e;
+                }
+            }
+        }
+
         $this->io->write('');
     }
 
@@ -87,17 +103,28 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
         $this->io->write("  - Updating <info>" . $name . "</info> (<comment>" . $from . "</comment> => <comment>" . $to . "</comment>)");
 
         $this->cleanChanges($initial, $path, true);
-        try {
-            $this->doUpdate($initial, $target, $path);
-        } catch (\Exception $e) {
-            // in case of failed update, try to reapply the changes before aborting
-            $this->reapplyChanges($path);
-
-            throw $e;
+        $urls = $target->getSourceUrls();
+        while ($url = array_shift($urls)) {
+            try {
+                $this->doUpdate($initial, $target, $path, $url);
+                break;
+            } catch (\Exception $e) {
+                if ($this->io->isDebug()) {
+                    $this->io->write('Failed: ['.get_class($e).'] '.$e->getMessage());
+                } elseif (count($urls)) {
+                    $this->io->write('    Failed, trying the next URL');
+                } else {
+                    // in case of failed update, try to reapply the changes before aborting
+                    $this->reapplyChanges($path);
+
+                    throw $e;
+                }
+            }
         }
+
         $this->reapplyChanges($path);
 
-        //print the commit logs if in verbose mode
+        // print the commit logs if in verbose mode
         if ($this->io->isVerbose()) {
             $message = 'Pulling in changes:';
             $logs = $this->getCommitLogs($initial->getSourceReference(), $target->getSourceReference(), $path);
@@ -176,8 +203,9 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
      *
      * @param PackageInterface $package package instance
      * @param string           $path    download path
+     * @param string           $url     package url
      */
-    abstract protected function doDownload(PackageInterface $package, $path);
+    abstract protected function doDownload(PackageInterface $package, $path, $url);
 
     /**
      * Updates specific package in specific folder from initial to target version.
@@ -185,8 +213,9 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
      * @param PackageInterface $initial initial package
      * @param PackageInterface $target  updated package
      * @param string           $path    download path
+     * @param string           $url     package url
      */
-    abstract protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path);
+    abstract protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url);
 
     /**
      * Fetches the commit logs between two commits

+ 24 - 0
src/Composer/Package/AliasPackage.php

@@ -209,6 +209,10 @@ class AliasPackage extends BasePackage implements CompletePackageInterface
     {
         return $this->aliasOf->getSourceUrl();
     }
+    public function getSourceUrls()
+    {
+        return $this->aliasOf->getSourceUrls();
+    }
     public function getSourceReference()
     {
         return $this->aliasOf->getSourceReference();
@@ -217,6 +221,14 @@ class AliasPackage extends BasePackage implements CompletePackageInterface
     {
         return $this->aliasOf->setSourceReference($reference);
     }
+    public function setSourceMirrors($mirrors)
+    {
+        return $this->aliasOf->setSourceMirrors($mirrors);
+    }
+    public function getSourceMirrors()
+    {
+        return $this->aliasOf->getSourceMirrors();
+    }
     public function getDistType()
     {
         return $this->aliasOf->getDistType();
@@ -225,6 +237,10 @@ class AliasPackage extends BasePackage implements CompletePackageInterface
     {
         return $this->aliasOf->getDistUrl();
     }
+    public function getDistUrls()
+    {
+        return $this->aliasOf->getDistUrls();
+    }
     public function getDistReference()
     {
         return $this->aliasOf->getDistReference();
@@ -241,6 +257,14 @@ class AliasPackage extends BasePackage implements CompletePackageInterface
     {
         return $this->aliasOf->getTransportOptions();
     }
+    public function setDistMirrors($mirrors)
+    {
+        return $this->aliasOf->setDistMirrors($mirrors);
+    }
+    public function getDistMirrors()
+    {
+        return $this->aliasOf->getDistMirrors();
+    }
     public function getScripts()
     {
         return $this->aliasOf->getScripts();

+ 6 - 0
src/Composer/Package/Dumper/ArrayDumper.php

@@ -49,6 +49,9 @@ class ArrayDumper
             $data['source']['type'] = $package->getSourceType();
             $data['source']['url'] = $package->getSourceUrl();
             $data['source']['reference'] = $package->getSourceReference();
+            if ($mirrors = $package->getSourceMirrors()) {
+                $data['source']['mirrors'] = $mirrors;
+            }
         }
 
         if ($package->getDistType()) {
@@ -56,6 +59,9 @@ class ArrayDumper
             $data['dist']['url'] = $package->getDistUrl();
             $data['dist']['reference'] = $package->getDistReference();
             $data['dist']['shasum'] = $package->getDistSha1Checksum();
+            if ($mirrors = $package->getDistMirrors()) {
+                $data['dist']['mirrors'] = $mirrors;
+            }
         }
 
         if ($package->getArchiveExcludes()) {

+ 6 - 0
src/Composer/Package/Loader/ArrayLoader.php

@@ -87,6 +87,9 @@ class ArrayLoader implements LoaderInterface
             $package->setSourceType($config['source']['type']);
             $package->setSourceUrl($config['source']['url']);
             $package->setSourceReference($config['source']['reference']);
+            if (isset($config['source']['mirrors'])) {
+                $package->setSourceMirrors($config['source']['mirrors']);
+            }
         }
 
         if (isset($config['dist'])) {
@@ -103,6 +106,9 @@ class ArrayLoader implements LoaderInterface
             $package->setDistUrl($config['dist']['url']);
             $package->setDistReference(isset($config['dist']['reference']) ? $config['dist']['reference'] : null);
             $package->setDistSha1Checksum(isset($config['dist']['shasum']) ? $config['dist']['shasum'] : null);
+            if (isset($config['dist']['mirrors'])) {
+                $package->setDistMirrors($config['dist']['mirrors']);
+            }
         }
 
         foreach (Package\BasePackage::$supportedLinkTypes as $type => $opts) {

+ 68 - 0
src/Composer/Package/Package.php

@@ -27,10 +27,12 @@ class Package extends BasePackage
     protected $sourceType;
     protected $sourceUrl;
     protected $sourceReference;
+    protected $sourceMirrors;
     protected $distType;
     protected $distUrl;
     protected $distReference;
     protected $distSha1Checksum;
+    protected $distMirrors;
     protected $version;
     protected $prettyVersion;
     protected $releaseDate;
@@ -217,6 +219,30 @@ class Package extends BasePackage
         return $this->sourceReference;
     }
 
+    /**
+     * @param array|null $mirrors
+     */
+    public function setSourceMirrors($mirrors)
+    {
+        $this->sourceMirrors = $mirrors;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getSourceMirrors()
+    {
+        return $this->sourceMirrors;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getSourceUrls()
+    {
+        return $this->getUrls($this->sourceUrl, $this->sourceMirrors, $this->sourceReference, $this->sourceType);
+    }
+
     /**
      * @param string $type
      */
@@ -281,6 +307,30 @@ class Package extends BasePackage
         return $this->distSha1Checksum;
     }
 
+    /**
+     * @param array|null $mirrors
+     */
+    public function setDistMirrors($mirrors)
+    {
+        $this->distMirrors = $mirrors;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDistMirrors()
+    {
+        return $this->distMirrors;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDistUrls()
+    {
+        return $this->getUrls($this->distUrl, $this->distMirrors, $this->distReference, $this->distType);
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -528,4 +578,22 @@ class Package extends BasePackage
         $this->stability = VersionParser::parseStability($version);
         $this->dev = $this->stability === 'dev';
     }
+
+    protected function getUrls($url, $mirrors, $ref, $type)
+    {
+        $urls = array($url);
+        if ($mirrors) {
+            foreach ($mirrors as $mirror) {
+                $mirrorUrl = str_replace(
+                    array('%package%', '%version%', '%reference%', '%type%'),
+                    array($this->name, $this->version, $ref, $type),
+                    $mirror['url']
+                );
+                $func = $mirror['preferred'] ? 'array_unshift' : 'array_push';
+                $func($urls, $mirrorUrl);
+            }
+        }
+
+        return $urls;
+    }
 }

+ 28 - 0
src/Composer/Package/PackageInterface.php

@@ -115,6 +115,13 @@ interface PackageInterface
      */
     public function getSourceUrl();
 
+    /**
+     * Returns the repository urls of this package including mirrors, e.g. git://github.com/naderman/composer.git
+     *
+     * @return string
+     */
+    public function getSourceUrls();
+
     /**
      * Returns the repository reference of this package, e.g. master, 1.0.0 or a commit hash for git
      *
@@ -122,6 +129,13 @@ interface PackageInterface
      */
     public function getSourceReference();
 
+    /**
+     * Returns the source mirrors of this package
+     *
+     * @return array|null
+     */
+    public function getSourceMirrors();
+
     /**
      * Returns the type of the distribution archive of this version, e.g. zip, tarball
      *
@@ -136,6 +150,13 @@ interface PackageInterface
      */
     public function getDistUrl();
 
+    /**
+     * Returns the urls of the distribution archive of this version, including mirrors
+     *
+     * @return string
+     */
+    public function getDistUrls();
+
     /**
      * Returns the reference of the distribution archive of this version, e.g. master, 1.0.0 or a commit hash for git
      *
@@ -150,6 +171,13 @@ interface PackageInterface
      */
     public function getDistSha1Checksum();
 
+    /**
+     * Returns the dist mirrors of this package
+     *
+     * @return array|null
+     */
+    public function getDistMirrors();
+
     /**
      * Returns the version of this package
      *

+ 15 - 0
src/Composer/Repository/ComposerRepository.php

@@ -50,6 +50,8 @@ class ComposerRepository extends ArrayRepository implements StreamableRepository
     protected $rootAliases;
     protected $allowSslDowngrade = false;
     protected $eventDispatcher;
+    protected $sourceMirrors;
+    protected $distMirrors;
     private $rawData;
     private $minimalPackages;
     private $degradedMode = false;
@@ -434,6 +436,17 @@ class ComposerRepository extends ArrayRepository implements StreamableRepository
             $this->searchUrl = $this->canonicalizeUrl($data['search']);
         }
 
+        if (!empty($data['mirrors'])) {
+            foreach ($data['mirrors'] as $mirror) {
+                if (!empty($mirror['source-url'])) {
+                    $this->sourceMirrors[] = array('url' => $mirror['source-url'], 'preferred' => !empty($mirror['preferred']));
+                }
+                if (!empty($mirror['dist-url'])) {
+                    $this->distMirrors[] = array('url' => $mirror['dist-url'], 'preferred' => !empty($mirror['preferred']));
+                }
+            }
+        }
+
         if ($this->allowSslDowngrade) {
             $this->url = str_replace('https://', 'http://', $this->url);
         }
@@ -548,6 +561,8 @@ class ComposerRepository extends ArrayRepository implements StreamableRepository
             }
 
             $package = $this->loader->load($data, 'Composer\Package\CompletePackage');
+            $package->setSourceMirrors($this->sourceMirrors);
+            $package->setDistMirrors($this->distMirrors);
             $this->configurePackageTransportOptions($package);
 
             return $package;

+ 14 - 2
tests/Composer/Test/Downloader/FileDownloaderTest.php

@@ -48,6 +48,10 @@ class FileDownloaderTest extends \PHPUnit_Framework_TestCase
             ->method('getDistUrl')
             ->will($this->returnValue('url'))
         ;
+        $packageMock->expects($this->once())
+            ->method('getDistUrls')
+            ->will($this->returnValue(array('url')))
+        ;
 
         $path = tempnam(sys_get_temp_dir(), 'c');
 
@@ -87,7 +91,11 @@ class FileDownloaderTest extends \PHPUnit_Framework_TestCase
         $packageMock = $this->getMock('Composer\Package\PackageInterface');
         $packageMock->expects($this->any())
             ->method('getDistUrl')
-            ->will($this->returnValue('http://example.com/script.js'))
+            ->will($this->returnValue($distUrl = 'http://example.com/script.js'))
+        ;
+        $packageMock->expects($this->once())
+            ->method('getDistUrls')
+            ->will($this->returnValue(array($distUrl)))
         ;
         $packageMock->expects($this->atLeastOnce())
             ->method('getTransportOptions')
@@ -163,7 +171,7 @@ class FileDownloaderTest extends \PHPUnit_Framework_TestCase
         $packageMock = $this->getMock('Composer\Package\PackageInterface');
         $packageMock->expects($this->any())
             ->method('getDistUrl')
-            ->will($this->returnValue('http://example.com/script.js'))
+            ->will($this->returnValue($distUrl = 'http://example.com/script.js'))
         ;
         $packageMock->expects($this->atLeastOnce())
             ->method('getTransportOptions')
@@ -173,6 +181,10 @@ class FileDownloaderTest extends \PHPUnit_Framework_TestCase
             ->method('getDistSha1Checksum')
             ->will($this->returnValue('invalid'))
         ;
+        $packageMock->expects($this->once())
+            ->method('getDistUrls')
+            ->will($this->returnValue(array($distUrl)))
+        ;
         $filesystem = $this->getMock('Composer\Util\Filesystem');
 
         do {

+ 12 - 12
tests/Composer/Test/Downloader/GitDownloaderTest.php

@@ -51,8 +51,8 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
             ->method('getSourceReference')
             ->will($this->returnValue('1234567890123456789012345678901234567890'));
         $packageMock->expects($this->any())
-            ->method('getSourceUrl')
-            ->will($this->returnValue('https://example.com/composer/composer'));
+            ->method('getSourceUrls')
+            ->will($this->returnValue(array('https://example.com/composer/composer')));
         $packageMock->expects($this->any())
             ->method('getPrettyVersion')
             ->will($this->returnValue('dev-master'));
@@ -90,8 +90,8 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
             ->method('getSourceReference')
             ->will($this->returnValue('ref'));
         $packageMock->expects($this->any())
-            ->method('getSourceUrl')
-            ->will($this->returnValue('https://github.com/composer/composer'));
+            ->method('getSourceUrls')
+            ->will($this->returnValue(array('https://github.com/composer/composer')));
         $packageMock->expects($this->any())
             ->method('getPrettyVersion')
             ->will($this->returnValue('1.0.0'));
@@ -147,8 +147,8 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
             ->method('getSourceReference')
             ->will($this->returnValue('ref'));
         $packageMock->expects($this->any())
-            ->method('getSourceUrl')
-            ->will($this->returnValue('https://github.com/composer/composer'));
+            ->method('getSourceUrls')
+            ->will($this->returnValue(array('https://github.com/composer/composer')));
         $packageMock->expects($this->any())
             ->method('getPrettyVersion')
             ->will($this->returnValue('1.0.0'));
@@ -188,8 +188,8 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
             ->method('getSourceReference')
             ->will($this->returnValue('ref'));
         $packageMock->expects($this->any())
-            ->method('getSourceUrl')
-            ->will($this->returnValue('https://example.com/composer/composer'));
+            ->method('getSourceUrls')
+            ->will($this->returnValue(array('https://example.com/composer/composer')));
         $processExecutor = $this->getMock('Composer\Util\ProcessExecutor');
         $processExecutor->expects($this->at(0))
             ->method('execute')
@@ -227,8 +227,8 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
             ->method('getSourceReference')
             ->will($this->returnValue('ref'));
         $packageMock->expects($this->any())
-            ->method('getSourceUrl')
-            ->will($this->returnValue('https://github.com/composer/composer'));
+            ->method('getSourceUrls')
+            ->will($this->returnValue(array('https://github.com/composer/composer')));
         $packageMock->expects($this->any())
             ->method('getPrettyVersion')
             ->will($this->returnValue('1.0.0'));
@@ -273,8 +273,8 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
             ->method('getSourceReference')
             ->will($this->returnValue('ref'));
         $packageMock->expects($this->any())
-            ->method('getSourceUrl')
-            ->will($this->returnValue('https://github.com/composer/composer'));
+            ->method('getSourceUrls')
+            ->will($this->returnValue(array('https://github.com/composer/composer')));
         $processExecutor = $this->getMock('Composer\Util\ProcessExecutor');
         $processExecutor->expects($this->at(0))
             ->method('execute')

+ 4 - 4
tests/Composer/Test/Downloader/HgDownloaderTest.php

@@ -48,8 +48,8 @@ class HgDownloaderTest extends \PHPUnit_Framework_TestCase
             ->method('getSourceReference')
             ->will($this->returnValue('ref'));
         $packageMock->expects($this->once())
-            ->method('getSourceUrl')
-            ->will($this->returnValue('https://mercurial.dev/l3l0/composer'));
+            ->method('getSourceUrls')
+            ->will($this->returnValue(array('https://mercurial.dev/l3l0/composer')));
         $processExecutor = $this->getMock('Composer\Util\ProcessExecutor');
 
         $expectedGitCommand = $this->getCmd('hg clone \'https://mercurial.dev/l3l0/composer\' \'composerPath\'');
@@ -93,8 +93,8 @@ class HgDownloaderTest extends \PHPUnit_Framework_TestCase
             ->method('getSourceReference')
             ->will($this->returnValue('ref'));
         $packageMock->expects($this->any())
-            ->method('getSourceUrl')
-            ->will($this->returnValue('https://github.com/l3l0/composer'));
+            ->method('getSourceUrls')
+            ->will($this->returnValue(array('https://github.com/l3l0/composer')));
         $processExecutor = $this->getMock('Composer\Util\ProcessExecutor');
 
         $expectedHgCommand = $this->getCmd("hg st");

+ 5 - 1
tests/Composer/Test/Downloader/ZipDownloaderTest.php

@@ -28,7 +28,11 @@ class ZipDownloaderTest extends \PHPUnit_Framework_TestCase
         $packageMock = $this->getMock('Composer\Package\PackageInterface');
         $packageMock->expects($this->any())
             ->method('getDistUrl')
-            ->will($this->returnValue('file://'.__FILE__))
+            ->will($this->returnValue($distUrl = 'file://'.__FILE__))
+        ;
+        $packageMock->expects($this->any())
+            ->method('getDistUrls')
+            ->will($this->returnValue(array($distUrl)))
         ;
         $packageMock->expects($this->atLeastOnce())
             ->method('getTransportOptions')