Fail over from source to dist and vice versa when downloads fail

Any RuntimeException descendent will be caught and cause another
download attempt using either source or dist depending on what was
attempted first.
main
Nils Adermann 10 years ago
parent aa74818fe0
commit 5ed18d9aa2

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

@ -344,7 +344,7 @@ class Factory
$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')) {
case 'dist':
$dm->setPreferDist(true);

@ -47,7 +47,8 @@ class ComposerTest extends TestCase
public function testSetGetDownloadManager()
{
$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);
$this->assertSame($manager, $composer->getDownloadManager());

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

@ -51,7 +51,7 @@ class InstallerTest extends TestCase
{
$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');
$repositoryManager = new RepositoryManager($io, $config);

Loading…
Cancel
Save