1
0
Fork 0

Merge remote-tracking branch 'naderman/download-failover'

pull/2773/head
Jordi Boggiano 2014-02-25 13:25:27 +01:00
commit a612b2affe
7 changed files with 127 additions and 46 deletions

View File

@ -14,6 +14,7 @@ namespace Composer\Downloader;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Downloader\DownloaderInterface; use Composer\Downloader\DownloaderInterface;
use Composer\IO\IOInterface;
use Composer\Util\Filesystem; use Composer\Util\Filesystem;
/** /**
@ -23,6 +24,7 @@ use Composer\Util\Filesystem;
*/ */
class DownloadManager class DownloadManager
{ {
private $io;
private $preferDist = false; private $preferDist = false;
private $preferSource = false; private $preferSource = false;
private $filesystem; private $filesystem;
@ -31,11 +33,13 @@ class DownloadManager
/** /**
* Initializes download manager. * Initializes download manager.
* *
* @param IOInterface $io The Input Output Interface
* @param bool $preferSource prefer downloading from source * @param bool $preferSource prefer downloading from source
* @param Filesystem|null $filesystem custom Filesystem object * @param Filesystem|null $filesystem custom Filesystem object
*/ */
public function __construct($preferSource = false, Filesystem $filesystem = null) public function __construct(IOInterface $io, $preferSource = false, Filesystem $filesystem = null)
{ {
$this->io = $io;
$this->preferSource = $preferSource; $this->preferSource = $preferSource;
$this->filesystem = $filesystem ?: new Filesystem(); $this->filesystem = $filesystem ?: new Filesystem();
} }
@ -168,19 +172,44 @@ class DownloadManager
$sourceType = $package->getSourceType(); $sourceType = $package->getSourceType();
$distType = $package->getDistType(); $distType = $package->getDistType();
if ((!$package->isDev() || $this->preferDist || !$sourceType) && !($preferSource && $sourceType) && $distType) { $sources = array();
$package->setInstallationSource('dist'); if ($sourceType) {
} elseif ($sourceType) { $sources[] = 'source';
$package->setInstallationSource('source'); }
} else { if ($distType) {
$sources[] = 'dist';
}
if (empty($sources)) {
throw new \InvalidArgumentException('Package '.$package.' must have a source or dist specified'); throw new \InvalidArgumentException('Package '.$package.' must have a source or dist specified');
} }
if ((!$package->isDev() || $this->preferDist) && !$preferSource) {
$sources = array_reverse($sources);
}
$this->filesystem->ensureDirectoryExists($targetDir); $this->filesystem->ensureDirectoryExists($targetDir);
$downloader = $this->getDownloaderForInstalledPackage($package); foreach ($sources as $i => $source) {
if ($downloader) { $package->setInstallationSource($source);
$downloader->download($package, $targetDir); try {
$downloader = $this->getDownloaderForInstalledPackage($package);
if ($downloader) {
$downloader->download($package, $targetDir);
}
break;
} catch (\RuntimeException $e) {
if ($i == count($sources) - 1) {
throw $e;
}
$this->io->write(
'<warning>Caught an exception while trying to download '.
$package->getPrettyString().
': '.
$e->getMessage().'</warning>'
);
}
} }
} }

View File

@ -344,7 +344,7 @@ class Factory
$cache = new Cache($io, $config->get('cache-files-dir'), 'a-z0-9_./'); $cache = new Cache($io, $config->get('cache-files-dir'), 'a-z0-9_./');
} }
$dm = new Downloader\DownloadManager(); $dm = new Downloader\DownloadManager($io);
switch ($config->get('preferred-install')) { switch ($config->get('preferred-install')) {
case 'dist': case 'dist':
$dm->setPreferDist(true); $dm->setPreferDist(true);

View File

@ -122,10 +122,6 @@ class GitHubDriver extends VcsDriver
*/ */
public function getDist($identifier) public function getDist($identifier)
{ {
if ($this->gitDriver) {
return $this->gitDriver->getDist($identifier);
}
$url = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/zipball/'.$identifier; $url = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/zipball/'.$identifier;
return array('type' => 'zip', 'url' => $url, 'reference' => $identifier, 'shasum' => ''); return array('type' => 'zip', 'url' => $url, 'reference' => $identifier, 'shasum' => '');

View File

@ -47,7 +47,8 @@ class ComposerTest extends TestCase
public function testSetGetDownloadManager() public function testSetGetDownloadManager()
{ {
$composer = new Composer(); $composer = new Composer();
$manager = $this->getMock('Composer\Downloader\DownloadManager'); $io = $this->getMock('Composer\IO\IOInterface');
$manager = $this->getMock('Composer\Downloader\DownloadManager', array(), array($io));
$composer->setDownloadManager($manager); $composer->setDownloadManager($manager);
$this->assertSame($manager, $composer->getDownloadManager()); $this->assertSame($manager, $composer->getDownloadManager());

View File

@ -17,16 +17,18 @@ use Composer\Downloader\DownloadManager;
class DownloadManagerTest extends \PHPUnit_Framework_TestCase class DownloadManagerTest extends \PHPUnit_Framework_TestCase
{ {
protected $filesystem; protected $filesystem;
protected $io;
public function setUp() public function setUp()
{ {
$this->filesystem = $this->getMock('Composer\Util\Filesystem'); $this->filesystem = $this->getMock('Composer\Util\Filesystem');
$this->io = $this->getMock('Composer\IO\IOInterface');
} }
public function testSetGetDownloader() public function testSetGetDownloader()
{ {
$downloader = $this->createDownloaderMock(); $downloader = $this->createDownloaderMock();
$manager = new DownloadManager(false, $this->filesystem); $manager = new DownloadManager($this->io, false, $this->filesystem);
$manager->setDownloader('test', $downloader); $manager->setDownloader('test', $downloader);
$this->assertSame($downloader, $manager->getDownloader('test')); $this->assertSame($downloader, $manager->getDownloader('test'));
@ -43,7 +45,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->method('getInstallationSource') ->method('getInstallationSource')
->will($this->returnValue(null)); ->will($this->returnValue(null));
$manager = new DownloadManager(false, $this->filesystem); $manager = new DownloadManager($this->io, false, $this->filesystem);
$this->setExpectedException('InvalidArgumentException'); $this->setExpectedException('InvalidArgumentException');
@ -69,7 +71,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue('dist')); ->will($this->returnValue('dist'));
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloader')) ->setMethods(array('getDownloader'))
->getMock(); ->getMock();
@ -101,7 +103,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue('source')); ->will($this->returnValue('source'));
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloader')) ->setMethods(array('getDownloader'))
->getMock(); ->getMock();
@ -135,7 +137,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue('source')); ->will($this->returnValue('source'));
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloader')) ->setMethods(array('getDownloader'))
->getMock(); ->getMock();
@ -167,7 +169,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue('dist')); ->will($this->returnValue('dist'));
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloader')) ->setMethods(array('getDownloader'))
->getMock(); ->getMock();
@ -190,7 +192,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->method('getType') ->method('getType')
->will($this->returnValue('metapackage')); ->will($this->returnValue('metapackage'));
$manager = new DownloadManager(false, $this->filesystem); $manager = new DownloadManager($this->io, false, $this->filesystem);
$this->assertNull($manager->getDownloaderForInstalledPackage($package)); $this->assertNull($manager->getDownloaderForInstalledPackage($package));
} }
@ -219,7 +221,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->with($package, 'target_dir'); ->with($package, 'target_dir');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage')) ->setMethods(array('getDownloaderForInstalledPackage'))
->getMock(); ->getMock();
$manager $manager
@ -231,6 +233,62 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
$manager->download($package, 'target_dir'); $manager->download($package, 'target_dir');
} }
public function testFullPackageDownloadFailover()
{
$package = $this->createPackageMock();
$package
->expects($this->once())
->method('getSourceType')
->will($this->returnValue('git'));
$package
->expects($this->once())
->method('getDistType')
->will($this->returnValue('pear'));
$package
->expects($this->any())
->method('getPrettyString')
->will($this->returnValue('prettyPackage'));
$package
->expects($this->at(3))
->method('setInstallationSource')
->with('dist');
$package
->expects($this->at(5))
->method('setInstallationSource')
->with('source');
$downloaderFail = $this->createDownloaderMock();
$downloaderFail
->expects($this->once())
->method('download')
->with($package, 'target_dir')
->will($this->throwException(new \RuntimeException("Foo")));
$downloaderSuccess = $this->createDownloaderMock();
$downloaderSuccess
->expects($this->once())
->method('download')
->with($package, 'target_dir');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage'))
->getMock();
$manager
->expects($this->at(0))
->method('getDownloaderForInstalledPackage')
->with($package)
->will($this->returnValue($downloaderFail));
$manager
->expects($this->at(1))
->method('getDownloaderForInstalledPackage')
->with($package)
->will($this->returnValue($downloaderSuccess));
$manager->download($package, 'target_dir');
}
public function testBadPackageDownload() public function testBadPackageDownload()
{ {
$package = $this->createPackageMock(); $package = $this->createPackageMock();
@ -243,7 +301,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->method('getDistType') ->method('getDistType')
->will($this->returnValue(null)); ->will($this->returnValue(null));
$manager = new DownloadManager(false, $this->filesystem); $manager = new DownloadManager($this->io, false, $this->filesystem);
$this->setExpectedException('InvalidArgumentException'); $this->setExpectedException('InvalidArgumentException');
$manager->download($package, 'target_dir'); $manager->download($package, 'target_dir');
@ -273,7 +331,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->with($package, 'target_dir'); ->with($package, 'target_dir');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage')) ->setMethods(array('getDownloaderForInstalledPackage'))
->getMock(); ->getMock();
$manager $manager
@ -309,7 +367,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->with($package, 'target_dir'); ->with($package, 'target_dir');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage')) ->setMethods(array('getDownloaderForInstalledPackage'))
->getMock(); ->getMock();
$manager $manager
@ -339,7 +397,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->with('source'); ->with('source');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage')) ->setMethods(array('getDownloaderForInstalledPackage'))
->getMock(); ->getMock();
$manager $manager
@ -375,7 +433,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->with($package, 'target_dir'); ->with($package, 'target_dir');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage')) ->setMethods(array('getDownloaderForInstalledPackage'))
->getMock(); ->getMock();
$manager $manager
@ -412,7 +470,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->with($package, 'target_dir'); ->with($package, 'target_dir');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage')) ->setMethods(array('getDownloaderForInstalledPackage'))
->getMock(); ->getMock();
$manager $manager
@ -449,7 +507,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->with($package, 'target_dir'); ->with($package, 'target_dir');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage')) ->setMethods(array('getDownloaderForInstalledPackage'))
->getMock(); ->getMock();
$manager $manager
@ -474,7 +532,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->method('getDistType') ->method('getDistType')
->will($this->returnValue(null)); ->will($this->returnValue(null));
$manager = new DownloadManager(false, $this->filesystem); $manager = new DownloadManager($this->io, false, $this->filesystem);
$manager->setPreferSource(true); $manager->setPreferSource(true);
$this->setExpectedException('InvalidArgumentException'); $this->setExpectedException('InvalidArgumentException');
@ -510,7 +568,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->with($initial, $target, 'vendor/bundles/FOS/UserBundle'); ->with($initial, $target, 'vendor/bundles/FOS/UserBundle');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage')) ->setMethods(array('getDownloaderForInstalledPackage'))
->getMock(); ->getMock();
$manager $manager
@ -547,7 +605,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->with($initial, 'vendor/bundles/FOS/UserBundle'); ->with($initial, 'vendor/bundles/FOS/UserBundle');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage', 'download')) ->setMethods(array('getDownloaderForInstalledPackage', 'download'))
->getMock(); ->getMock();
$manager $manager
@ -588,7 +646,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->with($initial, $target, 'vendor/pkg'); ->with($initial, $target, 'vendor/pkg');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage', 'download')) ->setMethods(array('getDownloaderForInstalledPackage', 'download'))
->getMock(); ->getMock();
$manager $manager
@ -625,7 +683,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->with($initial, 'vendor/pkg'); ->with($initial, 'vendor/pkg');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage', 'download')) ->setMethods(array('getDownloaderForInstalledPackage', 'download'))
->getMock(); ->getMock();
$manager $manager
@ -647,7 +705,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
$target = $this->createPackageMock(); $target = $this->createPackageMock();
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage')) ->setMethods(array('getDownloaderForInstalledPackage'))
->getMock(); ->getMock();
$manager $manager
@ -670,7 +728,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
->with($package, 'vendor/bundles/FOS/UserBundle'); ->with($package, 'vendor/bundles/FOS/UserBundle');
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage')) ->setMethods(array('getDownloaderForInstalledPackage'))
->getMock(); ->getMock();
$manager $manager
@ -687,7 +745,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
$package = $this->createPackageMock(); $package = $this->createPackageMock();
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager') $manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
->setConstructorArgs(array(false, $this->filesystem)) ->setConstructorArgs(array($this->io, false, $this->filesystem))
->setMethods(array('getDownloaderForInstalledPackage')) ->setMethods(array('getDownloaderForInstalledPackage'))
->getMock(); ->getMock();
$manager $manager

View File

@ -51,7 +51,7 @@ class InstallerTest extends TestCase
{ {
$io = $this->getMock('Composer\IO\IOInterface'); $io = $this->getMock('Composer\IO\IOInterface');
$downloadManager = $this->getMock('Composer\Downloader\DownloadManager'); $downloadManager = $this->getMock('Composer\Downloader\DownloadManager', array(), array($io));
$config = $this->getMock('Composer\Config'); $config = $this->getMock('Composer\Config');
$repositoryManager = new RepositoryManager($io, $config); $repositoryManager = new RepositoryManager($io, $config);

View File

@ -283,19 +283,16 @@ class GitHubDriverTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('test_master', $gitHubDriver->getRootIdentifier()); $this->assertEquals('test_master', $gitHubDriver->getRootIdentifier());
// Dist is not available for GitDriver $dist = $gitHubDriver->getDist($sha);
$dist = $gitHubDriver->getDist($identifier); $this->assertEquals('zip', $dist['type']);
$this->assertNull($dist); $this->assertEquals('https://api.github.com/repos/composer/packagist/zipball/SOMESHA', $dist['url']);
$this->assertEquals($sha, $dist['reference']);
$source = $gitHubDriver->getSource($identifier); $source = $gitHubDriver->getSource($identifier);
$this->assertEquals('git', $source['type']); $this->assertEquals('git', $source['type']);
$this->assertEquals($repoSshUrl, $source['url']); $this->assertEquals($repoSshUrl, $source['url']);
$this->assertEquals($identifier, $source['reference']); $this->assertEquals($identifier, $source['reference']);
// Dist is not available for GitDriver
$dist = $gitHubDriver->getDist($sha);
$this->assertNull($dist);
$source = $gitHubDriver->getSource($sha); $source = $gitHubDriver->getSource($sha);
$this->assertEquals('git', $source['type']); $this->assertEquals('git', $source['type']);
$this->assertEquals($repoSshUrl, $source['url']); $this->assertEquals($repoSshUrl, $source['url']);