From 713bc4de1d506a83f341e033569ded22bff7d228 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 31 Oct 2018 12:44:54 +0100 Subject: [PATCH] Minor fixes and updated the rest of the code/tests to use HttpDownloader --- doc/articles/plugins.md | 4 +- src/Composer/Command/ArchiveCommand.php | 2 +- src/Composer/Downloader/FileDownloader.php | 4 +- src/Composer/Downloader/GzipDownloader.php | 4 +- src/Composer/Downloader/RarDownloader.php | 4 +- src/Composer/Downloader/XzDownloader.php | 4 +- src/Composer/Downloader/ZipDownloader.php | 4 +- src/Composer/Factory.php | 32 +++--- src/Composer/Package/Loader/ArrayLoader.php | 3 +- .../Repository/ComposerRepository.php | 17 ++- .../Repository/Pear/BaseChannelReader.php | 16 ++- .../Repository/Pear/ChannelReader.php | 10 +- .../Repository/Pear/ChannelRest10Reader.php | 5 +- .../Repository/Pear/ChannelRest11Reader.php | 6 +- src/Composer/Repository/PearRepository.php | 10 +- src/Composer/Repository/RepositoryFactory.php | 6 +- src/Composer/Repository/RepositoryManager.php | 8 +- .../Repository/Vcs/BitbucketDriver.php | 25 +++-- .../Repository/Vcs/GitBitbucketDriver.php | 2 +- src/Composer/Repository/Vcs/GitHubDriver.php | 53 +++++---- src/Composer/Repository/Vcs/GitLabDriver.php | 55 ++++----- .../Repository/Vcs/HgBitbucketDriver.php | 2 +- src/Composer/Repository/Vcs/VcsDriver.php | 17 +-- src/Composer/Util/Bitbucket.php | 12 +- src/Composer/Util/GitHub.php | 10 +- src/Composer/Util/GitLab.php | 12 +- src/Composer/Util/Http/Response.php | 3 + src/Composer/Util/HttpDownloader.php | 10 +- src/Composer/Util/RemoteFilesystem.php | 4 +- .../Test/Downloader/ArchiveDownloaderTest.php | 6 +- .../Test/Downloader/FileDownloaderTest.php | 6 +- .../Test/Downloader/XzDownloaderTest.php | 4 +- .../Test/Downloader/ZipDownloaderTest.php | 38 +++---- tests/Composer/Test/InstallerTest.php | 5 +- ...esystemMock.php => HttpDownloaderMock.php} | 12 +- .../Package/Archiver/ArchiveManagerTest.php | 9 +- .../Repository/ComposerRepositoryTest.php | 32 ++++-- .../Test/Repository/PathRepositoryTest.php | 2 +- .../Repository/Pear/ChannelReaderTest.php | 10 +- .../Pear/ChannelRest10ReaderTest.php | 4 +- .../Pear/ChannelRest11ReaderTest.php | 4 +- .../Test/Repository/PearRepositoryTest.php | 4 +- .../Test/Repository/RepositoryFactoryTest.php | 4 +- .../Test/Repository/RepositoryManagerTest.php | 6 +- .../Repository/Vcs/GitBitbucketDriverTest.php | 68 ++++++----- .../Test/Repository/Vcs/GitHubDriverTest.php | 85 +++++++------- .../Test/Repository/Vcs/GitLabDriverTest.php | 106 +++++++----------- .../Repository/Vcs/PerforceDriverTest.php | 14 +-- tests/Composer/Test/Util/BitbucketTest.php | 72 ++++++------ tests/Composer/Test/Util/GitHubTest.php | 31 +++-- tests/Composer/Test/Util/GitLabTest.php | 31 +++-- 51 files changed, 461 insertions(+), 436 deletions(-) rename tests/Composer/Test/Mock/{RemoteFilesystemMock.php => HttpDownloaderMock.php} (73%) diff --git a/doc/articles/plugins.md b/doc/articles/plugins.md index 228cbac9e..59e2a2f15 100644 --- a/doc/articles/plugins.md +++ b/doc/articles/plugins.md @@ -176,8 +176,8 @@ class AwsPlugin implements PluginInterface, EventSubscriberInterface if ($protocol === 's3') { $awsClient = new AwsClient($this->io, $this->composer->getConfig()); - $s3RemoteFilesystem = new S3RemoteFilesystem($this->io, $event->getRemoteFilesystem()->getOptions(), $awsClient); - $event->setRemoteFilesystem($s3RemoteFilesystem); + $s3Downloader = new S3Downloader($this->io, $event->getRemoteFilesystem()->getOptions(), $awsClient); + $event->setHttpdownloader($s3Downloader); } } } diff --git a/src/Composer/Command/ArchiveCommand.php b/src/Composer/Command/ArchiveCommand.php index 29858c6fc..f893ed679 100644 --- a/src/Composer/Command/ArchiveCommand.php +++ b/src/Composer/Command/ArchiveCommand.php @@ -104,7 +104,7 @@ EOT $archiveManager = $composer->getArchiveManager(); } else { $factory = new Factory; - $downloadManager = $factory->createDownloadManager($io, $config); + $downloadManager = $factory->createDownloadManager($io, $config, $factory->createHttpDownloader($io, $config)); $archiveManager = $factory->createArchiveManager($config, $downloadManager); } diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index 6b1349bb8..8b196e60c 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -51,12 +51,12 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface * * @param IOInterface $io The IO instance * @param Config $config The config + * @param HttpDownloader $httpDownloader The remote filesystem * @param EventDispatcher $eventDispatcher The event dispatcher * @param Cache $cache Cache instance - * @param HttpDownloader $httpDownloader The remote filesystem * @param Filesystem $filesystem The filesystem */ - public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher, Cache $cache, HttpDownloader $httpDownloader, Filesystem $filesystem = null) + public function __construct(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, Filesystem $filesystem = null) { $this->io = $io; $this->config = $config; diff --git a/src/Composer/Downloader/GzipDownloader.php b/src/Composer/Downloader/GzipDownloader.php index bb86f6267..f65fcf27d 100644 --- a/src/Composer/Downloader/GzipDownloader.php +++ b/src/Composer/Downloader/GzipDownloader.php @@ -30,10 +30,10 @@ class GzipDownloader extends ArchiveDownloader { protected $process; - public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, HttpDownloader $downloader = null) + public function __construct(IOInterface $io, Config $config, HttpDownloader $downloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null) { $this->process = $process ?: new ProcessExecutor($io); - parent::__construct($io, $config, $eventDispatcher, $cache, $downloader); + parent::__construct($io, $config, $downloader, $eventDispatcher, $cache); } protected function extract($file, $path) diff --git a/src/Composer/Downloader/RarDownloader.php b/src/Composer/Downloader/RarDownloader.php index c1ed8d60b..6fe4cf27c 100644 --- a/src/Composer/Downloader/RarDownloader.php +++ b/src/Composer/Downloader/RarDownloader.php @@ -33,10 +33,10 @@ class RarDownloader extends ArchiveDownloader { protected $process; - public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, HttpDownloader $downloader = null) + public function __construct(IOInterface $io, Config $config, HttpDownloader $downloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null) { $this->process = $process ?: new ProcessExecutor($io); - parent::__construct($io, $config, $eventDispatcher, $cache, $downloader); + parent::__construct($io, $config, $downloader, $eventDispatcher, $cache); } protected function extract($file, $path) diff --git a/src/Composer/Downloader/XzDownloader.php b/src/Composer/Downloader/XzDownloader.php index 1f5947997..bd7b028e2 100644 --- a/src/Composer/Downloader/XzDownloader.php +++ b/src/Composer/Downloader/XzDownloader.php @@ -30,11 +30,11 @@ class XzDownloader extends ArchiveDownloader { protected $process; - public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, HttpDownloader $downloader = null) + public function __construct(IOInterface $io, Config $config, HttpDownloader $downloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null) { $this->process = $process ?: new ProcessExecutor($io); - parent::__construct($io, $config, $eventDispatcher, $cache, $downloader); + parent::__construct($io, $config, $downloader, $eventDispatcher, $cache); } protected function extract($file, $path) diff --git a/src/Composer/Downloader/ZipDownloader.php b/src/Composer/Downloader/ZipDownloader.php index 10518e026..9eceab250 100644 --- a/src/Composer/Downloader/ZipDownloader.php +++ b/src/Composer/Downloader/ZipDownloader.php @@ -36,10 +36,10 @@ class ZipDownloader extends ArchiveDownloader protected $process; private $zipArchiveObject; - public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, HttpDownloader $downloader = null) + public function __construct(IOInterface $io, Config $config, HttpDownloader $downloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null) { $this->process = $process ?: new ProcessExecutor($io); - parent::__construct($io, $config, $eventDispatcher, $cache, $downloader); + parent::__construct($io, $config, $downloader, $eventDispatcher, $cache); } /** diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 97d507b10..00aa499d0 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -325,14 +325,14 @@ class Factory $io->loadConfiguration($config); } - $rfs = self::createHttpDownloader($io, $config); + $httpDownloader = self::createHttpDownloader($io, $config); // initialize event dispatcher $dispatcher = new EventDispatcher($composer, $io); $composer->setEventDispatcher($dispatcher); // initialize repository manager - $rm = RepositoryFactory::manager($io, $config, $dispatcher, $rfs); + $rm = RepositoryFactory::manager($io, $config, $httpDownloader, $dispatcher); $composer->setRepositoryManager($rm); // load local repository @@ -357,7 +357,7 @@ class Factory if ($fullLoad) { // initialize download manager - $dm = $this->createDownloadManager($io, $config, $dispatcher, $rfs); + $dm = $this->createDownloadManager($io, $config, $httpDownloader, $dispatcher); $composer->setDownloadManager($dm); // initialize autoload generator @@ -451,7 +451,7 @@ class Factory * @param EventDispatcher $eventDispatcher * @return Downloader\DownloadManager */ - public function createDownloadManager(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, HttpDownloader $rfs = null) + public function createDownloadManager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null) { $cache = null; if ($config->get('cache-files-ttl') > 0) { @@ -484,14 +484,14 @@ class Factory $dm->setDownloader('fossil', new Downloader\FossilDownloader($io, $config, $executor, $fs)); $dm->setDownloader('hg', new Downloader\HgDownloader($io, $config, $executor, $fs)); $dm->setDownloader('perforce', new Downloader\PerforceDownloader($io, $config)); - $dm->setDownloader('zip', new Downloader\ZipDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs)); - $dm->setDownloader('rar', new Downloader\RarDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs)); - $dm->setDownloader('tar', new Downloader\TarDownloader($io, $config, $eventDispatcher, $cache, $rfs)); - $dm->setDownloader('gzip', new Downloader\GzipDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs)); - $dm->setDownloader('xz', new Downloader\XzDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs)); - $dm->setDownloader('phar', new Downloader\PharDownloader($io, $config, $eventDispatcher, $cache, $rfs)); - $dm->setDownloader('file', new Downloader\FileDownloader($io, $config, $eventDispatcher, $cache, $rfs)); - $dm->setDownloader('path', new Downloader\PathDownloader($io, $config, $eventDispatcher, $cache, $rfs)); + $dm->setDownloader('zip', new Downloader\ZipDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $executor)); + $dm->setDownloader('rar', new Downloader\RarDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $executor)); + $dm->setDownloader('tar', new Downloader\TarDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache)); + $dm->setDownloader('gzip', new Downloader\GzipDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $executor)); + $dm->setDownloader('xz', new Downloader\XzDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $executor)); + $dm->setDownloader('phar', new Downloader\PharDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache)); + $dm->setDownloader('file', new Downloader\FileDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache)); + $dm->setDownloader('path', new Downloader\PathDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache)); return $dm; } @@ -501,14 +501,8 @@ class Factory * @param Downloader\DownloadManager $dm Manager use to download sources * @return Archiver\ArchiveManager */ - public function createArchiveManager(Config $config, Downloader\DownloadManager $dm = null) + public function createArchiveManager(Config $config, Downloader\DownloadManager $dm) { - if (null === $dm) { - $io = new IO\NullIO(); - $io->loadConfiguration($config); - $dm = $this->createDownloadManager($io, $config); - } - $am = new Archiver\ArchiveManager($dm); $am->addArchiver(new Archiver\ZipArchiver); $am->addArchiver(new Archiver\PharArchiver); diff --git a/src/Composer/Package/Loader/ArrayLoader.php b/src/Composer/Package/Loader/ArrayLoader.php index 303cc3c13..49ba45aa8 100644 --- a/src/Composer/Package/Loader/ArrayLoader.php +++ b/src/Composer/Package/Loader/ArrayLoader.php @@ -18,7 +18,6 @@ use Composer\Package\Link; use Composer\Package\RootAliasPackage; use Composer\Package\RootPackageInterface; use Composer\Package\Version\VersionParser; -use Composer\Semver\VersionParser as SemverVersionParser; /** * @author Konstantin Kudryashiv @@ -29,7 +28,7 @@ class ArrayLoader implements LoaderInterface protected $versionParser; protected $loadOptions; - public function __construct(SemverVersionParser $parser = null, $loadOptions = false) + public function __construct(VersionParser $parser = null, $loadOptions = false) { if (!$parser) { $parser = new VersionParser; diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index c4a570c75..a0036e4fd 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -102,7 +102,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $this->versionParser = new VersionParser(); $this->loader = new ArrayLoader($this->versionParser); if ($httpDownloader && $this->options) { - // TODO solve this somehow - should be sent a request time not on the instance + // TODO solve this somehow - should be sent at request time not on the instance $httpDownloader = clone $httpDownloader; $httpDownloader->setOptions($this->options); } @@ -543,6 +543,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $response = $contents; } + if (!isset($response['packages'][$name])) { + return; + } + $uniqKeys = array('version', 'version_normalized', 'source', 'dist', 'time'); foreach ($response['packages'][$name] as $version) { if (isset($version['versions'])) { @@ -566,6 +570,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito }, function ($e) { // TODO use ->done() above instead with react/promise 2.0 var_dump('Uncaught Ex', $e->getMessage()); + throw $e; }); } } @@ -644,6 +649,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $this->hasProviders = true; } + // TODO this is for testing only, remove once packagist reports v2 protocol support + if (preg_match('{^https?://repo\.packagist\.org/?$}i', $this->url)) { + $this->repoConfig['force-lazy-providers'] = true; + } + // force values for packagist if (preg_match('{^https?://repo\.packagist\.org/?$}i', $this->url) && !empty($this->repoConfig['force-lazy-providers'])) { $this->url = 'https://repo.packagist.org'; @@ -927,6 +937,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $degradedMode =& $this->degradedMode; $accept = function ($response) use ($io, $url, $cache, $cacheKey) { + // package not found is acceptable for a v2 protocol repository + if ($response->getStatusCode() === 404) { + return array('packages' => array()); + } + $json = $response->getBody(); if ($json === '' && $response->getStatusCode() === 304) { return true; diff --git a/src/Composer/Repository/Pear/BaseChannelReader.php b/src/Composer/Repository/Pear/BaseChannelReader.php index 9b26eb9db..b778bf08b 100644 --- a/src/Composer/Repository/Pear/BaseChannelReader.php +++ b/src/Composer/Repository/Pear/BaseChannelReader.php @@ -12,7 +12,7 @@ namespace Composer\Repository\Pear; -use Composer\Util\RemoteFilesystem; +use Composer\Util\HttpDownloader; /** * Base PEAR Channel reader. @@ -33,12 +33,12 @@ abstract class BaseChannelReader const ALL_RELEASES_NS = 'http://pear.php.net/dtd/rest.allreleases'; const PACKAGE_INFO_NS = 'http://pear.php.net/dtd/rest.package'; - /** @var RemoteFilesystem */ - private $rfs; + /** @var HttpDownloader */ + private $httpDownloader; - protected function __construct(RemoteFilesystem $rfs) + protected function __construct(HttpDownloader $httpDownloader) { - $this->rfs = $rfs; + $this->httpDownloader = $httpDownloader; } /** @@ -52,7 +52,11 @@ abstract class BaseChannelReader protected function requestContent($origin, $path) { $url = rtrim($origin, '/') . '/' . ltrim($path, '/'); - $content = $this->rfs->getContents($origin, $url, false); + try { + $content = $this->httpDownloader->get($url)->getBody(); + } catch (\Exception $e) { + throw new \UnexpectedValueException('The PEAR channel at ' . $url . ' did not respond.', 0, $e); + } if (!$content) { throw new \UnexpectedValueException('The PEAR channel at ' . $url . ' did not respond.'); } diff --git a/src/Composer/Repository/Pear/ChannelReader.php b/src/Composer/Repository/Pear/ChannelReader.php index 73cc9152e..14d48ad86 100644 --- a/src/Composer/Repository/Pear/ChannelReader.php +++ b/src/Composer/Repository/Pear/ChannelReader.php @@ -12,7 +12,7 @@ namespace Composer\Repository\Pear; -use Composer\Util\RemoteFilesystem; +use Composer\Util\HttpDownloader; /** * PEAR Channel package reader. @@ -26,12 +26,12 @@ class ChannelReader extends BaseChannelReader /** @var array of ('xpath test' => 'rest implementation') */ private $readerMap; - public function __construct(RemoteFilesystem $rfs) + public function __construct(HttpDownloader $httpDownloader) { - parent::__construct($rfs); + parent::__construct($httpDownloader); - $rest10reader = new ChannelRest10Reader($rfs); - $rest11reader = new ChannelRest11Reader($rfs); + $rest10reader = new ChannelRest10Reader($httpDownloader); + $rest11reader = new ChannelRest11Reader($httpDownloader); $this->readerMap = array( 'REST1.3' => $rest11reader, diff --git a/src/Composer/Repository/Pear/ChannelRest10Reader.php b/src/Composer/Repository/Pear/ChannelRest10Reader.php index 489914d5d..93969043a 100644 --- a/src/Composer/Repository/Pear/ChannelRest10Reader.php +++ b/src/Composer/Repository/Pear/ChannelRest10Reader.php @@ -13,6 +13,7 @@ namespace Composer\Repository\Pear; use Composer\Downloader\TransportException; +use Composer\Util\HttpDownloader; /** * Read PEAR packages using REST 1.0 interface @@ -29,9 +30,9 @@ class ChannelRest10Reader extends BaseChannelReader { private $dependencyReader; - public function __construct($rfs) + public function __construct(HttpDownloader $httpDownloader) { - parent::__construct($rfs); + parent::__construct($httpDownloader); $this->dependencyReader = new PackageDependencyParser(); } diff --git a/src/Composer/Repository/Pear/ChannelRest11Reader.php b/src/Composer/Repository/Pear/ChannelRest11Reader.php index f9e05f5be..18b1b10f3 100644 --- a/src/Composer/Repository/Pear/ChannelRest11Reader.php +++ b/src/Composer/Repository/Pear/ChannelRest11Reader.php @@ -12,6 +12,8 @@ namespace Composer\Repository\Pear; +use Composer\Util\HttpDownloader; + /** * Read PEAR packages using REST 1.1 interface * @@ -25,9 +27,9 @@ class ChannelRest11Reader extends BaseChannelReader { private $dependencyReader; - public function __construct($rfs) + public function __construct(HttpDownloader $httpDownloader) { - parent::__construct($rfs); + parent::__construct($httpDownloader); $this->dependencyReader = new PackageDependencyParser(); } diff --git a/src/Composer/Repository/PearRepository.php b/src/Composer/Repository/PearRepository.php index c4f0b83e7..aef5c0381 100644 --- a/src/Composer/Repository/PearRepository.php +++ b/src/Composer/Repository/PearRepository.php @@ -21,7 +21,7 @@ use Composer\Repository\Pear\ChannelInfo; use Composer\EventDispatcher\EventDispatcher; use Composer\Package\Link; use Composer\Semver\Constraint\Constraint; -use Composer\Util\RemoteFilesystem; +use Composer\Util\HttpDownloader; use Composer\Config; use Composer\Factory; @@ -38,7 +38,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn { private $url; private $io; - private $rfs; + private $httpDownloader; private $versionParser; private $repoConfig; @@ -47,7 +47,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn */ private $vendorAlias; - public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher = null, RemoteFilesystem $rfs = null) + public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher, HttpDownloader $httpDownloader) { parent::__construct(); if (!preg_match('{^https?://}', $repoConfig['url'])) { @@ -61,7 +61,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn $this->url = rtrim($repoConfig['url'], '/'); $this->io = $io; - $this->rfs = $rfs ?: Factory::createRemoteFilesystem($this->io, $config); + $this->httpDownloader = $httpDownloader; $this->vendorAlias = isset($repoConfig['vendor-alias']) ? $repoConfig['vendor-alias'] : null; $this->versionParser = new VersionParser(); $this->repoConfig = $repoConfig; @@ -78,7 +78,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn $this->io->writeError('Initializing PEAR repository '.$this->url); - $reader = new ChannelReader($this->rfs); + $reader = new ChannelReader($this->httpDownloader); try { $channelInfo = $reader->read($this->url); } catch (\Exception $e) { diff --git a/src/Composer/Repository/RepositoryFactory.php b/src/Composer/Repository/RepositoryFactory.php index 5737a5359..515908f64 100644 --- a/src/Composer/Repository/RepositoryFactory.php +++ b/src/Composer/Repository/RepositoryFactory.php @@ -108,12 +108,12 @@ class RepositoryFactory * @param IOInterface $io * @param Config $config * @param EventDispatcher $eventDispatcher - * @param HttpDownloader $rfs + * @param HttpDownloader $httpDownloader * @return RepositoryManager */ - public static function manager(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, HttpDownloader $rfs = null) + public static function manager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null) { - $rm = new RepositoryManager($io, $config, $eventDispatcher, $rfs); + $rm = new RepositoryManager($io, $config, $eventDispatcher, $httpDownloader); $rm->setRepositoryClass('composer', 'Composer\Repository\ComposerRepository'); $rm->setRepositoryClass('vcs', 'Composer\Repository\VcsRepository'); $rm->setRepositoryClass('package', 'Composer\Repository\PackageRepository'); diff --git a/src/Composer/Repository/RepositoryManager.php b/src/Composer/Repository/RepositoryManager.php index 64568514c..8fc01cb08 100644 --- a/src/Composer/Repository/RepositoryManager.php +++ b/src/Composer/Repository/RepositoryManager.php @@ -33,14 +33,14 @@ class RepositoryManager private $io; private $config; private $eventDispatcher; - private $rfs; + private $httpDownloader; - public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, HttpDownloader $rfs = null) + public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher, HttpDownloader $httpDownloader) { $this->io = $io; $this->config = $config; $this->eventDispatcher = $eventDispatcher; - $this->rfs = $rfs; + $this->httpDownloader = $httpDownloader; } /** @@ -128,7 +128,7 @@ class RepositoryManager $reflMethod = new \ReflectionMethod($class, '__construct'); $params = $reflMethod->getParameters(); if (isset($params[4]) && $params[4]->getClass() && $params[4]->getClass()->getName() === 'Composer\Util\HttpDownloader') { - return new $class($config, $this->io, $this->config, $this->eventDispatcher, $this->rfs); + return new $class($config, $this->io, $this->config, $this->eventDispatcher, $this->httpDownloader); } return new $class($config, $this->io, $this->config, $this->eventDispatcher); diff --git a/src/Composer/Repository/Vcs/BitbucketDriver.php b/src/Composer/Repository/Vcs/BitbucketDriver.php index 24a4af4dd..bde4fc1b7 100644 --- a/src/Composer/Repository/Vcs/BitbucketDriver.php +++ b/src/Composer/Repository/Vcs/BitbucketDriver.php @@ -16,6 +16,7 @@ use Composer\Cache; use Composer\Downloader\TransportException; use Composer\Json\JsonFile; use Composer\Util\Bitbucket; +use Composer\Util\Http\Response; abstract class BitbucketDriver extends VcsDriver { @@ -92,7 +93,7 @@ abstract class BitbucketDriver extends VcsDriver ) ); - $repoData = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource, true), $resource); + $repoData = $this->fetchWithOAuthCredentials($resource, true)->decodeJson(); if ($this->fallbackDriver) { return false; } @@ -204,7 +205,7 @@ abstract class BitbucketDriver extends VcsDriver $file ); - return $this->getContentsWithOAuthCredentials($resource); + return $this->fetchWithOAuthCredentials($resource)->getBody(); } /** @@ -222,7 +223,7 @@ abstract class BitbucketDriver extends VcsDriver $this->repository, $identifier ); - $commit = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource); + $commit = $this->fetchWithOAuthCredentials($resource)->decodeJson(); return new \DateTime($commit['date']); } @@ -284,7 +285,7 @@ abstract class BitbucketDriver extends VcsDriver ); $hasNext = true; while ($hasNext) { - $tagsData = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource); + $tagsData = $this->fetchWithOAuthCredentials($resource)->decodeJson(); foreach ($tagsData['values'] as $data) { $this->tags[$data['name']] = $data['target']['hash']; } @@ -328,7 +329,7 @@ abstract class BitbucketDriver extends VcsDriver ); $hasNext = true; while ($hasNext) { - $branchData = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource); + $branchData = $this->fetchWithOAuthCredentials($resource)->decodeJson(); foreach ($branchData['values'] as $data) { // skip headless branches which seem to be deleted branches that bitbucket nevertheless returns in the API if ($this->vcsType === 'hg' && empty($data['heads'])) { @@ -354,14 +355,14 @@ abstract class BitbucketDriver extends VcsDriver * @param string $url The URL of content * @param bool $fetchingRepoData * - * @return mixed The result + * @return Response The result */ - protected function getContentsWithOAuthCredentials($url, $fetchingRepoData = false) + protected function fetchWithOAuthCredentials($url, $fetchingRepoData = false) { try { return parent::getContents($url); } catch (TransportException $e) { - $bitbucketUtil = new Bitbucket($this->io, $this->config, $this->process, $this->remoteFilesystem); + $bitbucketUtil = new Bitbucket($this->io, $this->config, $this->process, $this->httpDownloader); if (403 === $e->getCode() || (401 === $e->getCode() && strpos($e->getMessage(), 'Could not authenticate against') === 0)) { if (!$this->io->hasAuthentication($this->originUrl) @@ -371,7 +372,9 @@ abstract class BitbucketDriver extends VcsDriver } if (!$this->io->isInteractive() && $fetchingRepoData) { - return $this->attemptCloneFallback(); + if ($this->attemptCloneFallback()) { + return new Response(array('url' => 'dummy'), 200, array(), 'null'); + } } } @@ -390,6 +393,8 @@ abstract class BitbucketDriver extends VcsDriver { try { $this->setupFallbackDriver($this->generateSshUrl()); + + return true; } catch (\RuntimeException $e) { $this->fallbackDriver = null; @@ -433,7 +438,7 @@ abstract class BitbucketDriver extends VcsDriver $this->repository ); - $data = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource); + $data = $this->fetchWithOAuthCredentials($resource)->decodeJson(); if (isset($data['mainbranch'])) { return $data['mainbranch']; } diff --git a/src/Composer/Repository/Vcs/GitBitbucketDriver.php b/src/Composer/Repository/Vcs/GitBitbucketDriver.php index c8a5c9905..dd69e753a 100644 --- a/src/Composer/Repository/Vcs/GitBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/GitBitbucketDriver.php @@ -76,7 +76,7 @@ class GitBitbucketDriver extends BitbucketDriver $this->io, $this->config, $this->process, - $this->remoteFilesystem + $this->httpDownloader ); $this->fallbackDriver->initialize(); } diff --git a/src/Composer/Repository/Vcs/GitHubDriver.php b/src/Composer/Repository/Vcs/GitHubDriver.php index d0b721af9..f1ad253d8 100644 --- a/src/Composer/Repository/Vcs/GitHubDriver.php +++ b/src/Composer/Repository/Vcs/GitHubDriver.php @@ -18,6 +18,8 @@ use Composer\Json\JsonFile; use Composer\Cache; use Composer\IO\IOInterface; use Composer\Util\GitHub; +use Composer\Util\Http\Response; +use Composer\Util\RemoteFilesystem; /** * @author Jordi Boggiano @@ -184,7 +186,7 @@ class GitHubDriver extends VcsDriver } $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/contents/' . $file . '?ref='.urlencode($identifier); - $resource = JsonFile::parseJson($this->getContents($resource)); + $resource = $this->getContents($resource)->decodeJson(); if (empty($resource['content']) || $resource['encoding'] !== 'base64' || !($content = base64_decode($resource['content']))) { throw new \RuntimeException('Could not retrieve ' . $file . ' for '.$identifier); } @@ -202,7 +204,7 @@ class GitHubDriver extends VcsDriver } $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/commits/'.urlencode($identifier); - $commit = JsonFile::parseJson($this->getContents($resource), $resource); + $commit = $this->getContents($resource)->decodeJson(); return new \DateTime($commit['commit']['committer']['date']); } @@ -220,12 +222,13 @@ class GitHubDriver extends VcsDriver $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/tags?per_page=100'; do { - $tagsData = JsonFile::parseJson($this->getContents($resource), $resource); + $response = $this->getContents($resource); + $tagsData = $response->decodeJson(); foreach ($tagsData as $tag) { $this->tags[$tag['name']] = $tag['commit']['sha']; } - $resource = $this->getNextPage(); + $resource = $this->getNextPage($response); } while ($resource); } @@ -247,7 +250,8 @@ class GitHubDriver extends VcsDriver $branchBlacklist = array('gh-pages'); do { - $branchData = JsonFile::parseJson($this->getContents($resource), $resource); + $response = $this->getContents($resource); + $branchData = $response->decodeJson(); foreach ($branchData as $branch) { $name = substr($branch['ref'], 11); if (!in_array($name, $branchBlacklist)) { @@ -255,7 +259,7 @@ class GitHubDriver extends VcsDriver } } - $resource = $this->getNextPage(); + $resource = $this->getNextPage($response); } while ($resource); } @@ -315,7 +319,7 @@ class GitHubDriver extends VcsDriver try { return parent::getContents($url); } catch (TransportException $e) { - $gitHubUtil = new GitHub($this->io, $this->config, $this->process, $this->remoteFilesystem); + $gitHubUtil = new GitHub($this->io, $this->config, $this->process, $this->httpDownloader); switch ($e->getCode()) { case 401: @@ -330,16 +334,18 @@ class GitHubDriver extends VcsDriver } if (!$this->io->isInteractive()) { - return $this->attemptCloneFallback(); + if ($this->attemptCloneFallback()) { + return new Response(array('url' => 'dummy'), 200, array(), 'null'); + } } $scopesIssued = array(); $scopesNeeded = array(); if ($headers = $e->getHeaders()) { - if ($scopes = $this->remoteFilesystem->findHeaderValue($headers, 'X-OAuth-Scopes')) { + if ($scopes = RemoteFilesystem::findHeaderValue($headers, 'X-OAuth-Scopes')) { $scopesIssued = explode(' ', $scopes); } - if ($scopes = $this->remoteFilesystem->findHeaderValue($headers, 'X-Accepted-OAuth-Scopes')) { + if ($scopes = RemoteFilesystem::findHeaderValue($headers, 'X-Accepted-OAuth-Scopes')) { $scopesNeeded = explode(' ', $scopes); } } @@ -358,7 +364,9 @@ class GitHubDriver extends VcsDriver } if (!$this->io->isInteractive() && $fetchingRepoData) { - return $this->attemptCloneFallback(); + if ($this->attemptCloneFallback()) { + return new Response(array('url' => 'dummy'), 200, array(), 'null'); + } } $rateLimited = $gitHubUtil->isRateLimited($e->getHeaders()); @@ -404,7 +412,7 @@ class GitHubDriver extends VcsDriver $repoDataUrl = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository; - $this->repoData = JsonFile::parseJson($this->getContents($repoDataUrl, true), $repoDataUrl); + $this->repoData = $this->getContents($repoDataUrl, true)->decodeJson(); if (null === $this->repoData && null !== $this->gitDriver) { return; } @@ -434,7 +442,7 @@ class GitHubDriver extends VcsDriver // are not interactive) then we fallback to GitDriver. $this->setupGitDriver($this->generateSshUrl()); - return; + return true; } catch (\RuntimeException $e) { $this->gitDriver = null; @@ -450,22 +458,19 @@ class GitHubDriver extends VcsDriver $this->io, $this->config, $this->process, - $this->remoteFilesystem + $this->httpDownloader ); $this->gitDriver->initialize(); } - protected function getNextPage() + protected function getNextPage(Response $response) { - $headers = $this->remoteFilesystem->getLastHeaders(); - foreach ($headers as $header) { - if (preg_match('{^link:\s*(.+?)\s*$}i', $header, $match)) { - $links = explode(',', $match[1]); - foreach ($links as $link) { - if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) { - return $match[1]; - } - } + $header = $response->getHeader('link'); + + $links = explode(',', $header); + foreach ($links as $link) { + if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) { + return $match[1]; } } } diff --git a/src/Composer/Repository/Vcs/GitLabDriver.php b/src/Composer/Repository/Vcs/GitLabDriver.php index 2044ff702..6a1aa8ac2 100644 --- a/src/Composer/Repository/Vcs/GitLabDriver.php +++ b/src/Composer/Repository/Vcs/GitLabDriver.php @@ -17,8 +17,9 @@ use Composer\Cache; use Composer\IO\IOInterface; use Composer\Json\JsonFile; use Composer\Downloader\TransportException; -use Composer\Util\RemoteFilesystem; +use Composer\Util\HttpDownloader; use Composer\Util\GitLab; +use Composer\Util\Http\Response; /** * Driver for GitLab API, use the Git driver for local checkouts. @@ -110,14 +111,14 @@ class GitLabDriver extends VcsDriver } /** - * Updates the RemoteFilesystem instance. + * Updates the HttpDownloader instance. * Mainly useful for tests. * * @internal */ - public function setRemoteFilesystem(RemoteFilesystem $remoteFilesystem) + public function setHttpDownloader(HttpDownloader $httpDownloader) { - $this->remoteFilesystem = $remoteFilesystem; + $this->httpDownloader = $httpDownloader; } /** @@ -140,7 +141,7 @@ class GitLabDriver extends VcsDriver $resource = $this->getApiUrl().'/repository/files/'.$this->urlEncodeAll($file).'/raw?ref='.$identifier; try { - $content = $this->getContents($resource); + $content = $this->getContents($resource)->getBody(); } catch (TransportException $e) { if ($e->getCode() !== 404) { throw $e; @@ -297,7 +298,8 @@ class GitLabDriver extends VcsDriver $references = array(); do { - $data = JsonFile::parseJson($this->getContents($resource), $resource); + $response = $this->getContents($resource); + $data = $response->decodeJson(); foreach ($data as $datum) { $references[$datum['name']] = $datum['commit']['id']; @@ -308,7 +310,7 @@ class GitLabDriver extends VcsDriver } if (count($data) >= $perPage) { - $resource = $this->getNextPage(); + $resource = $this->getNextPage($response); } else { $resource = false; } @@ -321,7 +323,7 @@ class GitLabDriver extends VcsDriver { // we need to fetch the default branch from the api $resource = $this->getApiUrl(); - $this->project = JsonFile::parseJson($this->getContents($resource, true), $resource); + $this->project = $this->getContents($resource, true)->decodeJson(); if (isset($this->project['visibility'])) { $this->isPrivate = $this->project['visibility'] !== 'public'; } else { @@ -344,7 +346,7 @@ class GitLabDriver extends VcsDriver // are not interactive) then we fallback to GitDriver. $this->setupGitDriver($url); - return; + return true; } catch (\RuntimeException $e) { $this->gitDriver = null; @@ -375,7 +377,7 @@ class GitLabDriver extends VcsDriver $this->io, $this->config, $this->process, - $this->remoteFilesystem + $this->httpDownloader ); $this->gitDriver->initialize(); } @@ -386,10 +388,10 @@ class GitLabDriver extends VcsDriver protected function getContents($url, $fetchingRepoData = false) { try { - $res = parent::getContents($url); + $response = parent::getContents($url); if ($fetchingRepoData) { - $json = JsonFile::parseJson($res, $url); + $json = $response->decodeJson(); // force auth as the unauthenticated version of the API is broken if (!isset($json['default_branch'])) { @@ -401,9 +403,9 @@ class GitLabDriver extends VcsDriver } } - return $res; + return $response; } catch (TransportException $e) { - $gitLabUtil = new GitLab($this->io, $this->config, $this->process, $this->remoteFilesystem); + $gitLabUtil = new GitLab($this->io, $this->config, $this->process, $this->httpDownloader); switch ($e->getCode()) { case 401: @@ -418,7 +420,9 @@ class GitLabDriver extends VcsDriver } if (!$this->io->isInteractive()) { - return $this->attemptCloneFallback(); + if ($this->attemptCloneFallback()) { + return new Response(array('url' => 'dummy'), 200, array(), 'null'); + } } $this->io->writeError('Failed to download ' . $this->namespace . '/' . $this->repository . ':' . $e->getMessage() . ''); $gitLabUtil->authorizeOAuthInteractively($this->scheme, $this->originUrl, 'Your credentials are required to fetch private repository metadata ('.$this->url.')'); @@ -431,7 +435,9 @@ class GitLabDriver extends VcsDriver } if (!$this->io->isInteractive() && $fetchingRepoData) { - return $this->attemptCloneFallback(); + if ($this->attemptCloneFallback()) { + return new Response(array('url' => 'dummy'), 200, array(), 'null'); + } } throw $e; @@ -471,17 +477,14 @@ class GitLabDriver extends VcsDriver return true; } - private function getNextPage() + protected function getNextPage(Response $response) { - $headers = $this->remoteFilesystem->getLastHeaders(); - foreach ($headers as $header) { - if (preg_match('{^link:\s*(.+?)\s*$}i', $header, $match)) { - $links = explode(',', $match[1]); - foreach ($links as $link) { - if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) { - return $match[1]; - } - } + $header = $response->getHeader('link'); + + $links = explode(',', $header); + foreach ($links as $link) { + if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) { + return $match[1]; } } } diff --git a/src/Composer/Repository/Vcs/HgBitbucketDriver.php b/src/Composer/Repository/Vcs/HgBitbucketDriver.php index 8324f22ac..4a00f2da0 100644 --- a/src/Composer/Repository/Vcs/HgBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/HgBitbucketDriver.php @@ -76,7 +76,7 @@ class HgBitbucketDriver extends BitbucketDriver $this->io, $this->config, $this->process, - $this->remoteFilesystem + $this->httpDownloader ); $this->fallbackDriver->initialize(); } diff --git a/src/Composer/Repository/Vcs/VcsDriver.php b/src/Composer/Repository/Vcs/VcsDriver.php index 5227630f6..17ed706d2 100644 --- a/src/Composer/Repository/Vcs/VcsDriver.php +++ b/src/Composer/Repository/Vcs/VcsDriver.php @@ -19,8 +19,9 @@ use Composer\Factory; use Composer\IO\IOInterface; use Composer\Json\JsonFile; use Composer\Util\ProcessExecutor; -use Composer\Util\RemoteFilesystem; +use Composer\Util\HttpDownloader; use Composer\Util\Filesystem; +use Composer\Util\Http\Response; /** * A driver implementation for driver with authentication interaction. @@ -41,8 +42,8 @@ abstract class VcsDriver implements VcsDriverInterface protected $config; /** @var ProcessExecutor */ protected $process; - /** @var RemoteFilesystem */ - protected $remoteFilesystem; + /** @var HttpDownloader */ + protected $httpDownloader; /** @var array */ protected $infoCache = array(); /** @var Cache */ @@ -55,9 +56,9 @@ abstract class VcsDriver implements VcsDriverInterface * @param IOInterface $io The IO instance * @param Config $config The composer configuration * @param ProcessExecutor $process Process instance, injectable for mocking - * @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking + * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking */ - final public function __construct(array $repoConfig, IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null) + final public function __construct(array $repoConfig, IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null) { if (Filesystem::isLocalPath($repoConfig['url'])) { $repoConfig['url'] = Filesystem::getPlatformPath($repoConfig['url']); @@ -69,7 +70,7 @@ abstract class VcsDriver implements VcsDriverInterface $this->io = $io; $this->config = $config; $this->process = $process ?: new ProcessExecutor($io); - $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config); + $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config); } /** @@ -156,13 +157,13 @@ abstract class VcsDriver implements VcsDriverInterface * * @param string $url The URL of content * - * @return mixed The result + * @return Response */ protected function getContents($url) { $options = isset($this->repoConfig['options']) ? $this->repoConfig['options'] : array(); - return $this->remoteFilesystem->getContents($this->originUrl, $url, false, $options); + return $this->httpDownloader->get($url, $options); } /** diff --git a/src/Composer/Util/Bitbucket.php b/src/Composer/Util/Bitbucket.php index 1fc286ac4..d9f569b1b 100644 --- a/src/Composer/Util/Bitbucket.php +++ b/src/Composer/Util/Bitbucket.php @@ -25,7 +25,7 @@ class Bitbucket private $io; private $config; private $process; - private $remoteFilesystem; + private $httpDownloader; private $token = array(); private $time; @@ -37,15 +37,15 @@ class Bitbucket * @param IOInterface $io The IO instance * @param Config $config The composer configuration * @param ProcessExecutor $process Process instance, injectable for mocking - * @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking + * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking * @param int $time Timestamp, injectable for mocking */ - public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null, $time = null) + public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null, $time = null) { $this->io = $io; $this->config = $config; $this->process = $process ?: new ProcessExecutor($io); - $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config); + $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config); $this->time = $time; } @@ -90,7 +90,7 @@ class Bitbucket private function requestAccessToken($originUrl) { try { - $json = $this->remoteFilesystem->getContents($originUrl, self::OAUTH2_ACCESS_TOKEN_URL, false, array( + $response = $this->httpDownloader->get(self::OAUTH2_ACCESS_TOKEN_URL, array( 'retry-auth-failure' => false, 'http' => array( 'method' => 'POST', @@ -98,7 +98,7 @@ class Bitbucket ), )); - $this->token = json_decode($json, true); + $this->token = $response->decodeJson(); } catch (TransportException $e) { if ($e->getCode() === 400) { $this->io->writeError('Invalid OAuth consumer provided.'); diff --git a/src/Composer/Util/GitHub.php b/src/Composer/Util/GitHub.php index 1eca1a9bb..c3046cb77 100644 --- a/src/Composer/Util/GitHub.php +++ b/src/Composer/Util/GitHub.php @@ -25,7 +25,7 @@ class GitHub protected $io; protected $config; protected $process; - protected $remoteFilesystem; + protected $httpDownloader; /** * Constructor. @@ -33,14 +33,14 @@ class GitHub * @param IOInterface $io The IO instance * @param Config $config The composer configuration * @param ProcessExecutor $process Process instance, injectable for mocking - * @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking + * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking */ - public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null) + public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null) { $this->io = $io; $this->config = $config; $this->process = $process ?: new ProcessExecutor($io); - $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config); + $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config); } /** @@ -104,7 +104,7 @@ class GitHub try { $apiUrl = ('github.com' === $originUrl) ? 'api.github.com/' : $originUrl . '/api/v3/'; - $this->remoteFilesystem->getContents($originUrl, 'https://'. $apiUrl, false, array( + $this->httpDownloader->get('https://'. $apiUrl, array( 'retry-auth-failure' => false, )); } catch (TransportException $e) { diff --git a/src/Composer/Util/GitLab.php b/src/Composer/Util/GitLab.php index 475c5e7ee..2a4867954 100644 --- a/src/Composer/Util/GitLab.php +++ b/src/Composer/Util/GitLab.php @@ -26,7 +26,7 @@ class GitLab protected $io; protected $config; protected $process; - protected $remoteFilesystem; + protected $httpDownloader; /** * Constructor. @@ -34,14 +34,14 @@ class GitLab * @param IOInterface $io The IO instance * @param Config $config The composer configuration * @param ProcessExecutor $process Process instance, injectable for mocking - * @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking + * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking */ - public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null) + public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null) { $this->io = $io; $this->config = $config; $this->process = $process ?: new ProcessExecutor($io); - $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config); + $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config); } /** @@ -154,10 +154,10 @@ class GitLab ), ); - $json = $this->remoteFilesystem->getContents($originUrl, $scheme.'://'.$apiUrl.'/oauth/token', false, $options); + $token = $this->httpDownloader->get($scheme.'://'.$apiUrl.'/oauth/token', $options)->decodeJson(); $this->io->writeError('Token successfully created'); - return JsonFile::parseJson($json); + return $token; } } diff --git a/src/Composer/Util/Http/Response.php b/src/Composer/Util/Http/Response.php index ff48fdb40..f76057f3e 100644 --- a/src/Composer/Util/Http/Response.php +++ b/src/Composer/Util/Http/Response.php @@ -23,6 +23,9 @@ class Response public function __construct(array $request, $code, array $headers, $body) { + if (!isset($request['url'])) { + throw new \LogicException('url key missing from request array'); + } $this->request = $request; $this->code = $code; $this->headers = $headers; diff --git a/src/Composer/Util/HttpDownloader.php b/src/Composer/Util/HttpDownloader.php index 31c615e0c..631c0df7d 100644 --- a/src/Composer/Util/HttpDownloader.php +++ b/src/Composer/Util/HttpDownloader.php @@ -117,8 +117,8 @@ class HttpDownloader $origin = $this->getOrigin($job['request']['url']); - // TODO only send http/https through curl - if ($curl) { + // TODO experiment with allowing file:// through curl too + if ($curl && preg_match('{^https?://}i', $job['request']['url'])) { $resolver = function ($resolve, $reject) use (&$job, $curl, $origin) { // start job $url = $job['request']['url']; @@ -141,11 +141,7 @@ class HttpDownloader $job['status'] = HttpDownloader::STATUS_STARTED; if ($job['request']['copyTo']) { - if ($curl) { - $result = $curl->download($origin, $url, $options, $job['request']['copyTo']); - } else { - $result = $rfs->copy($origin, $url, $job['request']['copyTo'], false /* TODO progress */, $options); - } + $result = $rfs->copy($origin, $url, $job['request']['copyTo'], false /* TODO progress */, $options); $resolve($result); } else { diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php index f4a211acb..00fe35294 100644 --- a/src/Composer/Util/RemoteFilesystem.php +++ b/src/Composer/Util/RemoteFilesystem.php @@ -147,7 +147,7 @@ class RemoteFilesystem * @param string $name header name (case insensitive) * @return string|null */ - public function findHeaderValue(array $headers, $name) + public static function findHeaderValue(array $headers, $name) { $value = null; foreach ($headers as $header) { @@ -167,7 +167,7 @@ class RemoteFilesystem * @param array $headers array of returned headers like from getLastHeaders() * @return int|null */ - public function findStatusCode(array $headers) + public static function findStatusCode(array $headers) { $value = null; foreach ($headers as $header) { diff --git a/tests/Composer/Test/Downloader/ArchiveDownloaderTest.php b/tests/Composer/Test/Downloader/ArchiveDownloaderTest.php index 68852d8e0..ddf21c64b 100644 --- a/tests/Composer/Test/Downloader/ArchiveDownloaderTest.php +++ b/tests/Composer/Test/Downloader/ArchiveDownloaderTest.php @@ -156,7 +156,11 @@ class ArchiveDownloaderTest extends TestCase { return $this->getMockForAbstractClass( 'Composer\Downloader\ArchiveDownloader', - array($this->getMockBuilder('Composer\IO\IOInterface')->getMock(), $this->getMockBuilder('Composer\Config')->getMock()) + array( + $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(), + $config = $this->getMockBuilder('Composer\Config')->getMock(), + new \Composer\Util\HttpDownloader($io, $config), + ) ); } } diff --git a/tests/Composer/Test/Downloader/FileDownloaderTest.php b/tests/Composer/Test/Downloader/FileDownloaderTest.php index 476b9a8f7..12edfe19d 100644 --- a/tests/Composer/Test/Downloader/FileDownloaderTest.php +++ b/tests/Composer/Test/Downloader/FileDownloaderTest.php @@ -18,13 +18,13 @@ use Composer\Util\Filesystem; class FileDownloaderTest extends TestCase { - protected function getDownloader($io = null, $config = null, $eventDispatcher = null, $cache = null, $rfs = null, $filesystem = null) + protected function getDownloader($io = null, $config = null, $eventDispatcher = null, $cache = null, $httpDownloader = null, $filesystem = null) { $io = $io ?: $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); $config = $config ?: $this->getMockBuilder('Composer\Config')->getMock(); - $rfs = $rfs ?: $this->getMockBuilder('Composer\Util\RemoteFilesystem')->disableOriginalConstructor()->getMock(); + $httpDownloader = $httpDownloader ?: $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(); - return new FileDownloader($io, $config, $eventDispatcher, $cache, $rfs, $filesystem); + return new FileDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $filesystem); } /** diff --git a/tests/Composer/Test/Downloader/XzDownloaderTest.php b/tests/Composer/Test/Downloader/XzDownloaderTest.php index 6df782ddb..451592d37 100644 --- a/tests/Composer/Test/Downloader/XzDownloaderTest.php +++ b/tests/Composer/Test/Downloader/XzDownloaderTest.php @@ -16,7 +16,7 @@ use Composer\Downloader\XzDownloader; use Composer\Test\TestCase; use Composer\Util\Filesystem; use Composer\Util\Platform; -use Composer\Util\RemoteFilesystem; +use Composer\Util\HttpDownloader; class XzDownloaderTest extends TestCase { @@ -66,7 +66,7 @@ class XzDownloaderTest extends TestCase ->method('get') ->with('vendor-dir') ->will($this->returnValue($this->testDir)); - $downloader = new XzDownloader($io, $config, null, null, null, new RemoteFilesystem($io)); + $downloader = new XzDownloader($io, $config, new HttpDownloader($io, $this->getMockBuilder('Composer\Config')->getMock()), null, null, null); try { $downloader->download($packageMock, $this->getUniqueTmpDirectory()); diff --git a/tests/Composer/Test/Downloader/ZipDownloaderTest.php b/tests/Composer/Test/Downloader/ZipDownloaderTest.php index 466fd35c7..0c1311427 100644 --- a/tests/Composer/Test/Downloader/ZipDownloaderTest.php +++ b/tests/Composer/Test/Downloader/ZipDownloaderTest.php @@ -16,6 +16,7 @@ use Composer\Downloader\ZipDownloader; use Composer\Package\PackageInterface; use Composer\Test\TestCase; use Composer\Util\Filesystem; +use Composer\Util\HttpDownloader; class ZipDownloaderTest extends TestCase { @@ -32,6 +33,8 @@ class ZipDownloaderTest extends TestCase $this->testDir = $this->getUniqueTmpDirectory(); $this->io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); $this->config = $this->getMockBuilder('Composer\Config')->getMock(); + $dlConfig = $this->getMockBuilder('Composer\Config')->getMock(); + $this->httpDownloader = new HttpDownloader($this->io, $dlConfig); } public function tearDown() @@ -64,18 +67,6 @@ class ZipDownloaderTest extends TestCase } $this->config->expects($this->at(0)) - ->method('get') - ->with('disable-tls') - ->will($this->returnValue(false)); - $this->config->expects($this->at(1)) - ->method('get') - ->with('cafile') - ->will($this->returnValue(null)); - $this->config->expects($this->at(2)) - ->method('get') - ->with('capath') - ->will($this->returnValue(null)); - $this->config->expects($this->at(3)) ->method('get') ->with('vendor-dir') ->will($this->returnValue($this->testDir)); @@ -94,7 +85,7 @@ class ZipDownloaderTest extends TestCase ->will($this->returnValue(array())) ; - $downloader = new ZipDownloader($this->io, $this->config); + $downloader = new ZipDownloader($this->io, $this->config, $this->httpDownloader); $this->setPrivateProperty('hasSystemUnzip', false); @@ -118,8 +109,7 @@ class ZipDownloaderTest extends TestCase $this->setPrivateProperty('hasSystemUnzip', false); $this->setPrivateProperty('hasZipArchive', true); - $downloader = new MockedZipDownloader($this->io, $this->config); - + $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader); $zipArchive = $this->getMockBuilder('ZipArchive')->getMock(); $zipArchive->expects($this->at(0)) ->method('open') @@ -144,8 +134,7 @@ class ZipDownloaderTest extends TestCase $this->setPrivateProperty('hasSystemUnzip', false); $this->setPrivateProperty('hasZipArchive', true); - $downloader = new MockedZipDownloader($this->io, $this->config); - + $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader); $zipArchive = $this->getMockBuilder('ZipArchive')->getMock(); $zipArchive->expects($this->at(0)) ->method('open') @@ -169,8 +158,7 @@ class ZipDownloaderTest extends TestCase $this->setPrivateProperty('hasSystemUnzip', false); $this->setPrivateProperty('hasZipArchive', true); - $downloader = new MockedZipDownloader($this->io, $this->config); - + $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader); $zipArchive = $this->getMockBuilder('ZipArchive')->getMock(); $zipArchive->expects($this->at(0)) ->method('open') @@ -200,7 +188,7 @@ class ZipDownloaderTest extends TestCase ->method('execute') ->will($this->returnValue(1)); - $downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor); + $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor); $downloader->extract('testfile.zip', 'vendor/dir'); } @@ -217,7 +205,7 @@ class ZipDownloaderTest extends TestCase ->method('execute') ->will($this->returnValue(0)); - $downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor); + $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor); $downloader->extract('testfile.zip', 'vendor/dir'); } @@ -244,7 +232,7 @@ class ZipDownloaderTest extends TestCase ->method('extractTo') ->will($this->returnValue(true)); - $downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor); + $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor); $this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader); $downloader->extract('testfile.zip', 'vendor/dir'); } @@ -276,7 +264,7 @@ class ZipDownloaderTest extends TestCase ->method('extractTo') ->will($this->returnValue(false)); - $downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor); + $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor); $this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader); $downloader->extract('testfile.zip', 'vendor/dir'); } @@ -304,7 +292,7 @@ class ZipDownloaderTest extends TestCase ->method('extractTo') ->will($this->returnValue(false)); - $downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor); + $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor); $this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader); $downloader->extract('testfile.zip', 'vendor/dir'); } @@ -336,7 +324,7 @@ class ZipDownloaderTest extends TestCase ->method('extractTo') ->will($this->returnValue(false)); - $downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor); + $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor); $this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader); $downloader->extract('testfile.zip', 'vendor/dir'); } diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index f21007281..2e7d70639 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -63,7 +63,9 @@ class InstallerTest extends TestCase ->getMock(); $config = $this->getMockBuilder('Composer\Config')->getMock(); - $repositoryManager = new RepositoryManager($io, $config); + $eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(); + $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(); + $repositoryManager = new RepositoryManager($io, $config, $eventDispatcher, $httpDownloader); $repositoryManager->setLocalRepository(new InstalledArrayRepository()); if (!is_array($repositories)) { @@ -76,7 +78,6 @@ class InstallerTest extends TestCase $locker = $this->getMockBuilder('Composer\Package\Locker')->disableOriginalConstructor()->getMock(); $installationManager = new InstallationManagerMock(); - $eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(); $autoloadGenerator = $this->getMockBuilder('Composer\Autoload\AutoloadGenerator')->disableOriginalConstructor()->getMock(); $installer = new Installer($io, $config, clone $rootPackage, $downloadManager, $repositoryManager, $locker, $installationManager, $eventDispatcher, $autoloadGenerator); diff --git a/tests/Composer/Test/Mock/RemoteFilesystemMock.php b/tests/Composer/Test/Mock/HttpDownloaderMock.php similarity index 73% rename from tests/Composer/Test/Mock/RemoteFilesystemMock.php rename to tests/Composer/Test/Mock/HttpDownloaderMock.php index 5d4f52e54..1e2774af0 100644 --- a/tests/Composer/Test/Mock/RemoteFilesystemMock.php +++ b/tests/Composer/Test/Mock/HttpDownloaderMock.php @@ -12,13 +12,11 @@ namespace Composer\Test\Mock; -use Composer\Util\RemoteFilesystem; +use Composer\Util\HttpDownloader; +use Composer\Util\Http\Response; use Composer\Downloader\TransportException; -/** - * Remote filesystem mock - */ -class RemoteFilesystemMock extends RemoteFilesystem +class HttpDownloaderMock extends HttpDownloader { protected $contentMap; @@ -30,10 +28,10 @@ class RemoteFilesystemMock extends RemoteFilesystem $this->contentMap = $contentMap; } - public function getContents($originUrl, $fileUrl, $progress = true, $options = array()) + public function get($fileUrl, $options = array()) { if (!empty($this->contentMap[$fileUrl])) { - return $this->contentMap[$fileUrl]; + return new Response(array('url' => $fileUrl), 200, array(), $this->contentMap[$fileUrl]); } throw new TransportException('The "'.$fileUrl.'" file could not be downloaded (NOT FOUND)', 404); diff --git a/tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php b/tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php index f9fe308fa..b9f08e693 100644 --- a/tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php +++ b/tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php @@ -12,9 +12,11 @@ namespace Composer\Test\Package\Archiver; +use Composer\IO\NullIO; use Composer\Factory; use Composer\Package\Archiver\ArchiveManager; use Composer\Package\PackageInterface; +use Composer\Test\Mock\FactoryMock; class ArchiveManagerTest extends ArchiverTest { @@ -30,7 +32,12 @@ class ArchiveManagerTest extends ArchiverTest parent::setUp(); $factory = new Factory(); - $this->manager = $factory->createArchiveManager($factory->createConfig()); + $dm = $factory->createDownloadManager( + $io = new NullIO, + $config = FactoryMock::createConfig(), + $factory->createHttpDownloader($io, $config) + ); + $this->manager = $factory->createArchiveManager($factory->createConfig(), $dm); $this->targetDir = $this->testDir.'/composer_archiver_tests'; } diff --git a/tests/Composer/Test/Repository/ComposerRepositoryTest.php b/tests/Composer/Test/Repository/ComposerRepositoryTest.php index 05e1afada..1fe60f589 100644 --- a/tests/Composer/Test/Repository/ComposerRepositoryTest.php +++ b/tests/Composer/Test/Repository/ComposerRepositoryTest.php @@ -18,7 +18,7 @@ use Composer\Repository\RepositoryInterface; use Composer\Test\Mock\FactoryMock; use Composer\Test\TestCase; use Composer\Package\Loader\ArrayLoader; -use Composer\Semver\VersionParser; +use Composer\Package\Version\VersionParser; class ComposerRepositoryTest extends TestCase { @@ -37,6 +37,8 @@ class ComposerRepositoryTest extends TestCase $repoConfig, new NullIO, FactoryMock::createConfig(), + $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(), + $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock() )) ->getMock(); @@ -179,21 +181,29 @@ class ComposerRepositoryTest extends TestCase ), ); - $rfs = $this->getMockBuilder('Composer\Util\RemoteFilesystem') + $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader') + ->disableOriginalConstructor() + ->getMock(); + $eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher') ->disableOriginalConstructor() ->getMock(); - $rfs->expects($this->at(0)) - ->method('getContents') - ->with('example.org', 'http://example.org/packages.json', false) - ->willReturn(json_encode(array('search' => '/search.json?q=%query%&type=%type%'))); + $httpDownloader->expects($this->at(0)) + ->method('get') + ->with($url = 'http://example.org/packages.json') + ->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode(array('search' => '/search.json?q=%query%&type=%type%')))); - $rfs->expects($this->at(1)) - ->method('getContents') - ->with('example.org', 'http://example.org/search.json?q=foo&type=composer-plugin', false) - ->willReturn(json_encode($result)); + $httpDownloader->expects($this->at(1)) + ->method('get') + ->with($url = 'http://example.org/search.json?q=foo&type=composer-plugin') + ->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode($result))); - $repository = new ComposerRepository($repoConfig, new NullIO, FactoryMock::createConfig(), null, $rfs); + $httpDownloader->expects($this->at(2)) + ->method('get') + ->with($url = 'http://example.org/search.json?q=foo&type=library') + ->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode(array()))); + + $repository = new ComposerRepository($repoConfig, new NullIO, FactoryMock::createConfig(), $eventDispatcher, $httpDownloader); $this->assertSame( array(array('name' => 'foo', 'description' => null)), diff --git a/tests/Composer/Test/Repository/PathRepositoryTest.php b/tests/Composer/Test/Repository/PathRepositoryTest.php index a9594257c..abe6063f4 100644 --- a/tests/Composer/Test/Repository/PathRepositoryTest.php +++ b/tests/Composer/Test/Repository/PathRepositoryTest.php @@ -14,8 +14,8 @@ namespace Composer\Test\Repository; use Composer\Package\Loader\ArrayLoader; use Composer\Repository\PathRepository; -use Composer\Semver\VersionParser; use Composer\Test\TestCase; +use Composer\Package\Version\VersionParser; class PathRepositoryTest extends TestCase { diff --git a/tests/Composer/Test/Repository/Pear/ChannelReaderTest.php b/tests/Composer/Test/Repository/Pear/ChannelReaderTest.php index e766065a7..7ad30825d 100644 --- a/tests/Composer/Test/Repository/Pear/ChannelReaderTest.php +++ b/tests/Composer/Test/Repository/Pear/ChannelReaderTest.php @@ -22,13 +22,13 @@ use Composer\Semver\VersionParser; use Composer\Semver\Constraint\Constraint; use Composer\Package\Link; use Composer\Package\CompletePackage; -use Composer\Test\Mock\RemoteFilesystemMock; +use Composer\Test\Mock\HttpDownloaderMock; class ChannelReaderTest extends TestCase { public function testShouldBuildPackagesFromPearSchema() { - $rfs = new RemoteFilesystemMock(array( + $rfs = new HttpDownloaderMock(array( 'http://pear.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.1.xml'), 'http://test.loc/rest11/c/categories.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/categories.xml'), 'http://test.loc/rest11/c/Default/packagesinfo.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/packagesinfo.xml'), @@ -50,11 +50,15 @@ class ChannelReaderTest extends TestCase public function testShouldSelectCorrectReader() { - $rfs = new RemoteFilesystemMock(array( + $rfs = new HttpDownloaderMock(array( 'http://pear.1.0.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.0.xml'), 'http://test.loc/rest10/p/packages.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/packages.xml'), 'http://test.loc/rest10/p/http_client/info.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_info.xml'), + 'http://test.loc/rest10/r/http_client/allreleases.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_allreleases.xml'), + 'http://test.loc/rest10/r/http_client/deps.1.2.1.txt' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_deps.1.2.1.txt'), 'http://test.loc/rest10/p/http_request/info.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_request_info.xml'), + 'http://test.loc/rest10/r/http_request/allreleases.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_request_allreleases.xml'), + 'http://test.loc/rest10/r/http_request/deps.1.4.0.txt' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_request_deps.1.4.0.txt'), 'http://pear.1.1.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.1.xml'), 'http://test.loc/rest11/c/categories.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/categories.xml'), 'http://test.loc/rest11/c/Default/packagesinfo.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/packagesinfo.xml'), diff --git a/tests/Composer/Test/Repository/Pear/ChannelRest10ReaderTest.php b/tests/Composer/Test/Repository/Pear/ChannelRest10ReaderTest.php index 4aa7bbba2..5a40915e1 100644 --- a/tests/Composer/Test/Repository/Pear/ChannelRest10ReaderTest.php +++ b/tests/Composer/Test/Repository/Pear/ChannelRest10ReaderTest.php @@ -13,13 +13,13 @@ namespace Composer\Test\Repository\Pear; use Composer\Test\TestCase; -use Composer\Test\Mock\RemoteFilesystemMock; +use Composer\Test\Mock\HttpDownloaderMock; class ChannelRest10ReaderTest extends TestCase { public function testShouldBuildPackagesFromPearSchema() { - $rfs = new RemoteFilesystemMock(array( + $rfs = new HttpDownloaderMock(array( 'http://test.loc/rest10/p/packages.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/packages.xml'), 'http://test.loc/rest10/p/http_client/info.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_info.xml'), 'http://test.loc/rest10/r/http_client/allreleases.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_allreleases.xml'), diff --git a/tests/Composer/Test/Repository/Pear/ChannelRest11ReaderTest.php b/tests/Composer/Test/Repository/Pear/ChannelRest11ReaderTest.php index 04e48426e..08c3a2998 100644 --- a/tests/Composer/Test/Repository/Pear/ChannelRest11ReaderTest.php +++ b/tests/Composer/Test/Repository/Pear/ChannelRest11ReaderTest.php @@ -13,13 +13,13 @@ namespace Composer\Test\Repository\Pear; use Composer\Test\TestCase; -use Composer\Test\Mock\RemoteFilesystemMock; +use Composer\Test\Mock\HttpDownloaderMock; class ChannelRest11ReaderTest extends TestCase { public function testShouldBuildPackagesFromPearSchema() { - $rfs = new RemoteFilesystemMock(array( + $rfs = new HttpDownloaderMock(array( 'http://pear.1.1.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.1.xml'), 'http://test.loc/rest11/c/categories.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/categories.xml'), 'http://test.loc/rest11/c/Default/packagesinfo.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/packagesinfo.xml'), diff --git a/tests/Composer/Test/Repository/PearRepositoryTest.php b/tests/Composer/Test/Repository/PearRepositoryTest.php index b1a3c0b5e..6046fefb4 100644 --- a/tests/Composer/Test/Repository/PearRepositoryTest.php +++ b/tests/Composer/Test/Repository/PearRepositoryTest.php @@ -133,7 +133,7 @@ class PearRepositoryTest extends TestCase $config = new \Composer\Config(); - $this->remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem') + $this->httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader') ->disableOriginalConstructor() ->getMock(); @@ -143,6 +143,6 @@ class PearRepositoryTest extends TestCase protected function tearDown() { $this->repository = null; - $this->remoteFilesystem = null; + $this->httpDownloader = null; } } diff --git a/tests/Composer/Test/Repository/RepositoryFactoryTest.php b/tests/Composer/Test/Repository/RepositoryFactoryTest.php index e54624415..e0a854d46 100644 --- a/tests/Composer/Test/Repository/RepositoryFactoryTest.php +++ b/tests/Composer/Test/Repository/RepositoryFactoryTest.php @@ -21,7 +21,9 @@ class RepositoryFactoryTest extends TestCase { $manager = RepositoryFactory::manager( $this->getMockBuilder('Composer\IO\IOInterface')->getMock(), - $this->getMockBuilder('Composer\Config')->getMock() + $this->getMockBuilder('Composer\Config')->getMock(), + $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(), + $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock() ); $ref = new \ReflectionProperty($manager, 'repositoryClasses'); diff --git a/tests/Composer/Test/Repository/RepositoryManagerTest.php b/tests/Composer/Test/Repository/RepositoryManagerTest.php index 3774dd268..c4f09de87 100644 --- a/tests/Composer/Test/Repository/RepositoryManagerTest.php +++ b/tests/Composer/Test/Repository/RepositoryManagerTest.php @@ -38,7 +38,8 @@ class RepositoryManagerTest extends TestCase $rm = new RepositoryManager( $this->getMockBuilder('Composer\IO\IOInterface')->getMock(), $this->getMockBuilder('Composer\Config')->getMock(), - $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock() + $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(), + $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock() ); $repository1 = $this->getMockBuilder('Composer\Repository\RepositoryInterface')->getMock(); @@ -61,7 +62,8 @@ class RepositoryManagerTest extends TestCase $rm = new RepositoryManager( $this->getMockBuilder('Composer\IO\IOInterface')->getMock(), $config = $this->getMockBuilder('Composer\Config')->setMethods(array('get'))->getMock(), - $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock() + $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(), + $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock() ); $tmpdir = $this->tmpdir; diff --git a/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php index 8d711e8f0..a3a9219d9 100644 --- a/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php @@ -16,6 +16,7 @@ use Composer\Config; use Composer\Repository\Vcs\GitBitbucketDriver; use Composer\Test\TestCase; use Composer\Util\Filesystem; +use Composer\Util\Http\Response; /** * @group bitbucket @@ -26,8 +27,8 @@ class GitBitbucketDriverTest extends TestCase private $io; /** @type \Composer\Config */ private $config; - /** @type \Composer\Util\RemoteFilesystem|\PHPUnit_Framework_MockObject_MockObject */ - private $rfs; + /** @type \Composer\Util\HttpDownloader|\PHPUnit_Framework_MockObject_MockObject */ + private $httpDownloader; /** @type string */ private $home; /** @type string */ @@ -46,7 +47,7 @@ class GitBitbucketDriverTest extends TestCase ), )); - $this->rfs = $this->getMockBuilder('Composer\Util\RemoteFilesystem') + $this->httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader') ->disableOriginalConstructor() ->getMock(); } @@ -68,7 +69,7 @@ class GitBitbucketDriverTest extends TestCase $this->io, $this->config, null, - $this->rfs + $this->httpDownloader ); $driver->initialize(); @@ -83,15 +84,14 @@ class GitBitbucketDriverTest extends TestCase 'https://bitbucket.org/user/repo.git does not appear to be a git repository, use https://bitbucket.org/user/repo if this is a mercurial bitbucket repository' ); - $this->rfs->expects($this->once()) - ->method('getContents') + $this->httpDownloader->expects($this->once()) + ->method('get') ->with( - $this->originUrl, - 'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner', - false + $url = 'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner', + array() ) ->willReturn( - '{"scm":"hg","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo","name":"https"},{"href":"ssh:\/\/hg@bitbucket.org\/user\/repo","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}' + new Response(array('url' => $url), 200, array(), '{"scm":"hg","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo","name":"https"},{"href":"ssh:\/\/hg@bitbucket.org\/user\/repo","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}') ); $driver = $this->getDriver(array('url' => 'https://bitbucket.org/user/repo.git')); @@ -103,47 +103,43 @@ class GitBitbucketDriverTest extends TestCase { $driver = $this->getDriver(array('url' => 'https://bitbucket.org/user/repo.git')); - $this->rfs->expects($this->any()) - ->method('getContents') + $urls = array( + 'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner', + 'https://api.bitbucket.org/2.0/repositories/user/repo?fields=mainbranch', + 'https://api.bitbucket.org/2.0/repositories/user/repo/refs/tags?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cnext&sort=-target.date', + 'https://api.bitbucket.org/2.0/repositories/user/repo/refs/branches?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cvalues.heads%2Cnext&sort=-target.date', + 'https://api.bitbucket.org/2.0/repositories/user/repo/src/master/composer.json', + 'https://api.bitbucket.org/2.0/repositories/user/repo/commit/master?fields=date', + ); + $this->httpDownloader->expects($this->any()) + ->method('get') ->withConsecutive( array( - $this->originUrl, - 'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner', - false, + $urls[0], array() ), array( - $this->originUrl, - 'https://api.bitbucket.org/2.0/repositories/user/repo?fields=mainbranch', - false, + $urls[1], array() ), array( - $this->originUrl, - 'https://api.bitbucket.org/2.0/repositories/user/repo/refs/tags?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cnext&sort=-target.date', - false, + $urls[2], array() ), array( - $this->originUrl, - 'https://api.bitbucket.org/2.0/repositories/user/repo/refs/branches?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cvalues.heads%2Cnext&sort=-target.date', - false, + $urls[3], array() ), array( - $this->originUrl, - 'https://api.bitbucket.org/2.0/repositories/user/repo/src/master/composer.json', - false, + $urls[4], array() ), array( - $this->originUrl, - 'https://api.bitbucket.org/2.0/repositories/user/repo/commit/master?fields=date', - false, + $urls[5], array() ) ) ->willReturnOnConsecutiveCalls( - '{"scm":"git","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo.git","name":"https"},{"href":"ssh:\/\/git@bitbucket.org\/user\/repo.git","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}', - '{"mainbranch": {"name": "master"}}', - '{"values":[{"name":"1.0.1","target":{"hash":"9b78a3932143497c519e49b8241083838c8ff8a1"}},{"name":"1.0.0","target":{"hash":"d3393d514318a9267d2f8ebbf463a9aaa389f8eb"}}]}', - '{"values":[{"name":"master","target":{"hash":"937992d19d72b5116c3e8c4a04f960e5fa270b22"}}]}', - '{"name": "user/repo","description": "test repo","license": "GPL","authors": [{"name": "Name","email": "local@domain.tld"}],"require": {"creator/package": "^1.0"},"require-dev": {"phpunit/phpunit": "~4.8"}}', - '{"date": "2016-05-17T13:19:52+00:00"}' + new Response(array('url' => $urls[0]), 200, array(), '{"scm":"git","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo.git","name":"https"},{"href":"ssh:\/\/git@bitbucket.org\/user\/repo.git","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}'), + new Response(array('url' => $urls[1]), 200, array(), '{"mainbranch": {"name": "master"}}'), + new Response(array('url' => $urls[2]), 200, array(), '{"values":[{"name":"1.0.1","target":{"hash":"9b78a3932143497c519e49b8241083838c8ff8a1"}},{"name":"1.0.0","target":{"hash":"d3393d514318a9267d2f8ebbf463a9aaa389f8eb"}}]}'), + new Response(array('url' => $urls[3]), 200, array(), '{"values":[{"name":"master","target":{"hash":"937992d19d72b5116c3e8c4a04f960e5fa270b22"}}]}'), + new Response(array('url' => $urls[4]), 200, array(), '{"name": "user/repo","description": "test repo","license": "GPL","authors": [{"name": "Name","email": "local@domain.tld"}],"require": {"creator/package": "^1.0"},"require-dev": {"phpunit/phpunit": "~4.8"}}'), + new Response(array('url' => $urls[5]), 200, array(), '{"date": "2016-05-17T13:19:52+00:00"}') ); $this->assertEquals( diff --git a/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php index ba9c6d4f7..1f721a4c7 100644 --- a/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php @@ -16,6 +16,7 @@ use Composer\Downloader\TransportException; use Composer\Repository\Vcs\GitHubDriver; use Composer\Test\TestCase; use Composer\Util\Filesystem; +use Composer\Util\Http\Response; use Composer\Config; class GitHubDriverTest extends TestCase @@ -53,8 +54,8 @@ class GitHubDriverTest extends TestCase ->method('isInteractive') ->will($this->returnValue(true)); - $remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem') - ->setConstructorArgs(array($io)) + $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader') + ->setConstructorArgs(array($io, $this->config)) ->getMock(); $process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock(); @@ -62,9 +63,9 @@ class GitHubDriverTest extends TestCase ->method('execute') ->will($this->returnValue(1)); - $remoteFilesystem->expects($this->at(0)) - ->method('getContents') - ->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false)) + $httpDownloader->expects($this->at(0)) + ->method('get') + ->with($this->equalTo($repoApiUrl)) ->will($this->throwException(new TransportException('HTTP/1.1 404 Not Found', 404))); $io->expects($this->once()) @@ -76,15 +77,15 @@ class GitHubDriverTest extends TestCase ->method('setAuthentication') ->with($this->equalTo('github.com'), $this->matchesRegularExpression('{sometoken}'), $this->matchesRegularExpression('{x-oauth-basic}')); - $remoteFilesystem->expects($this->at(1)) - ->method('getContents') - ->with($this->equalTo('github.com'), $this->equalTo('https://api.github.com/'), $this->equalTo(false)) - ->will($this->returnValue('{}')); + $httpDownloader->expects($this->at(1)) + ->method('get') + ->with($this->equalTo($url = 'https://api.github.com/')) + ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{}'))); - $remoteFilesystem->expects($this->at(2)) - ->method('getContents') - ->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false)) - ->will($this->returnValue('{"master_branch": "test_master", "private": true, "owner": {"login": "composer"}, "name": "packagist"}')); + $httpDownloader->expects($this->at(2)) + ->method('get') + ->with($this->equalTo($url = $repoApiUrl)) + ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{"master_branch": "test_master", "private": true, "owner": {"login": "composer"}, "name": "packagist"}'))); $configSource = $this->getMockBuilder('Composer\Config\ConfigSourceInterface')->getMock(); $authConfigSource = $this->getMockBuilder('Composer\Config\ConfigSourceInterface')->getMock(); @@ -95,7 +96,7 @@ class GitHubDriverTest extends TestCase 'url' => $repoUrl, ); - $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $remoteFilesystem); + $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $httpDownloader); $gitHubDriver->initialize(); $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha)); @@ -124,21 +125,21 @@ class GitHubDriverTest extends TestCase ->method('isInteractive') ->will($this->returnValue(true)); - $remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem') - ->setConstructorArgs(array($io)) + $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader') + ->setConstructorArgs(array($io, $this->config)) ->getMock(); - $remoteFilesystem->expects($this->at(0)) - ->method('getContents') - ->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false)) - ->will($this->returnValue('{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}')); + $httpDownloader->expects($this->at(0)) + ->method('get') + ->with($this->equalTo($repoApiUrl)) + ->will($this->returnValue(new Response(array('url' => $repoApiUrl), 200, array(), '{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}'))); $repoConfig = array( 'url' => $repoUrl, ); $repoUrl = 'https://github.com/composer/packagist.git'; - $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $remoteFilesystem); + $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $httpDownloader); $gitHubDriver->initialize(); $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha)); @@ -167,31 +168,31 @@ class GitHubDriverTest extends TestCase ->method('isInteractive') ->will($this->returnValue(true)); - $remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem') - ->setConstructorArgs(array($io)) + $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader') + ->setConstructorArgs(array($io, $this->config)) ->getMock(); - $remoteFilesystem->expects($this->at(0)) - ->method('getContents') - ->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false)) - ->will($this->returnValue('{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}')); + $httpDownloader->expects($this->at(0)) + ->method('get') + ->with($this->equalTo($url = $repoApiUrl)) + ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}'))); - $remoteFilesystem->expects($this->at(1)) - ->method('getContents') - ->with($this->equalTo('github.com'), $this->equalTo('https://api.github.com/repos/composer/packagist/contents/composer.json?ref=feature%2F3.2-foo'), $this->equalTo(false)) - ->will($this->returnValue('{"encoding":"base64","content":"'.base64_encode('{"support": {"source": "'.$repoUrl.'" }}').'"}')); + $httpDownloader->expects($this->at(1)) + ->method('get') + ->with($this->equalTo($url = 'https://api.github.com/repos/composer/packagist/contents/composer.json?ref=feature%2F3.2-foo')) + ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{"encoding":"base64","content":"'.base64_encode('{"support": {"source": "'.$repoUrl.'" }}').'"}'))); - $remoteFilesystem->expects($this->at(2)) - ->method('getContents') - ->with($this->equalTo('github.com'), $this->equalTo('https://api.github.com/repos/composer/packagist/commits/feature%2F3.2-foo'), $this->equalTo(false)) - ->will($this->returnValue('{"commit": {"committer":{ "date": "2012-09-10"}}}')); + $httpDownloader->expects($this->at(2)) + ->method('get') + ->with($this->equalTo($url = 'https://api.github.com/repos/composer/packagist/commits/feature%2F3.2-foo')) + ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{"commit": {"committer":{ "date": "2012-09-10"}}}'))); $repoConfig = array( 'url' => $repoUrl, ); $repoUrl = 'https://github.com/composer/packagist.git'; - $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $remoteFilesystem); + $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $httpDownloader); $gitHubDriver->initialize(); $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha)); @@ -227,13 +228,13 @@ class GitHubDriverTest extends TestCase ->method('isInteractive') ->will($this->returnValue(false)); - $remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem') - ->setConstructorArgs(array($io)) + $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader') + ->setConstructorArgs(array($io, $this->config)) ->getMock(); - $remoteFilesystem->expects($this->at(0)) - ->method('getContents') - ->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false)) + $httpDownloader->expects($this->at(0)) + ->method('get') + ->with($this->equalTo($repoApiUrl)) ->will($this->throwException(new TransportException('HTTP/1.1 404 Not Found', 404))); // clean local clone if present @@ -278,7 +279,7 @@ class GitHubDriverTest extends TestCase 'url' => $repoUrl, ); - $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $remoteFilesystem); + $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $httpDownloader); $gitHubDriver->initialize(); $this->assertEquals('test_master', $gitHubDriver->getRootIdentifier()); diff --git a/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php index a5eb799f2..f940733ae 100644 --- a/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php @@ -17,6 +17,7 @@ use Composer\Config; use Composer\Test\TestCase; use Composer\Util\Filesystem; use Prophecy\Argument; +use Composer\Util\Http\Response; /** * @author Jérôme Tamarelle @@ -27,7 +28,7 @@ class GitLabDriverTest extends TestCase private $config; private $io; private $process; - private $remoteFilesystem; + private $httpDownloader; public function setUp() { @@ -47,7 +48,7 @@ class GitLabDriverTest extends TestCase $this->io = $this->prophesize('Composer\IO\IOInterface'); $this->process = $this->prophesize('Composer\Util\ProcessExecutor'); - $this->remoteFilesystem = $this->prophesize('Composer\Util\RemoteFilesystem'); + $this->httpDownloader = $this->prophesize('Composer\Util\HttpDownloader'); } public function tearDown() @@ -87,13 +88,11 @@ class GitLabDriverTest extends TestCase } JSON; - $this->remoteFilesystem - ->getContents('gitlab.com', $apiUrl, false, array()) - ->willReturn($projectData) + $this->mockResponse($apiUrl, array(), $projectData) ->shouldBeCalledTimes(1) ; - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -126,13 +125,11 @@ JSON; } JSON; - $this->remoteFilesystem - ->getContents('gitlab.com', $apiUrl, false, array()) - ->willReturn($projectData) + $this->mockResponse($apiUrl, array(), $projectData) ->shouldBeCalledTimes(1) ; - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -164,13 +161,11 @@ JSON; } JSON; - $this->remoteFilesystem - ->getContents('gitlab.com', $apiUrl, false, array()) - ->willReturn($projectData) + $this->mockResponse($apiUrl, array(), $projectData) ->shouldBeCalledTimes(1) ; - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -206,12 +201,10 @@ JSON; } JSON; - $this->remoteFilesystem - ->getContents($domain, $apiUrl, false, array()) - ->willReturn(sprintf($projectData, $domain, $port, $namespace)) + $this->mockResponse($apiUrl, array(), sprintf($projectData, $domain, $port, $namespace)) ->shouldBeCalledTimes(1); - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -289,15 +282,11 @@ JSON; ] JSON; - $this->remoteFilesystem - ->getContents('gitlab.com', $apiUrl, false, array()) - ->willReturn($tagData) + $this->mockResponse($apiUrl, array(), $tagData) ->shouldBeCalledTimes(1) ; - $this->remoteFilesystem->getLastHeaders() - ->willReturn(array()); - $driver->setRemoteFilesystem($this->remoteFilesystem->reveal()); + $driver->setHttpDownloader($this->httpDownloader->reveal()); $expected = array( 'v1.0.0' => '092ed2c762bbae331e3f51d4a17f67310bf99a81', @@ -344,26 +333,20 @@ JSON; $branchData = json_encode($branchData); - $this->remoteFilesystem - ->getContents('gitlab.com', $apiUrl, false, array()) - ->willReturn($branchData) - ->shouldBeCalledTimes(1) - ; + $headers = array('Link: ; rel="next", ; rel="first", ; rel="last"'); + $this->httpDownloader + ->get($apiUrl, array()) + ->willReturn(new Response(array('url' => $apiUrl), 200, $headers, $branchData)) + ->shouldBeCalledTimes(1); - $this->remoteFilesystem - ->getContents('gitlab.com', "http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20", false, array()) - ->willReturn($branchData) - ->shouldBeCalledTimes(1) - ; + $apiUrl = "http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20"; + $headers = array('Link: ; rel="prev", ; rel="first", ; rel="last"'); + $this->httpDownloader + ->get($apiUrl, array()) + ->willReturn(new Response(array('url' => $apiUrl), 200, $headers, $branchData)) + ->shouldBeCalledTimes(1); - $this->remoteFilesystem->getLastHeaders() - ->willReturn( - array('Link: ; rel="next", ; rel="first", ; rel="last"'), - array('Link: ; rel="prev", ; rel="first", ; rel="last"') - ) - ->shouldBeCalledTimes(2); - - $driver->setRemoteFilesystem($this->remoteFilesystem->reveal()); + $driver->setHttpDownloader($this->httpDownloader->reveal()); $expected = array( 'mymaster' => '97eda36b5c1dd953a3792865c222d4e85e5f302e', @@ -401,15 +384,11 @@ JSON; ] JSON; - $this->remoteFilesystem - ->getContents('gitlab.com', $apiUrl, false, array()) - ->willReturn($branchData) + $this->mockResponse($apiUrl, array(), $branchData) ->shouldBeCalledTimes(1) ; - $this->remoteFilesystem->getLastHeaders() - ->willReturn(array()); - $driver->setRemoteFilesystem($this->remoteFilesystem->reveal()); + $driver->setHttpDownloader($this->httpDownloader->reveal()); $expected = array( 'mymaster' => '97eda36b5c1dd953a3792865c222d4e85e5f302e', @@ -474,13 +453,11 @@ JSON; } JSON; - $this->remoteFilesystem - ->getContents('mycompany.com/gitlab', $apiUrl, false, array()) - ->willReturn($projectData) + $this->mockResponse($apiUrl, array(), $projectData) ->shouldBeCalledTimes(1) ; - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -507,13 +484,11 @@ JSON; } JSON; - $this->remoteFilesystem - ->getContents('gitlab.com', $apiUrl, false, array()) - ->willReturn($projectData) + $this->mockResponse($apiUrl, array(), $projectData) ->shouldBeCalledTimes(1) ; - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -540,13 +515,11 @@ JSON; } JSON; - $this->remoteFilesystem - ->getContents('mycompany.com/gitlab', $apiUrl, false, array()) - ->willReturn($projectData) + $this->mockResponse($apiUrl, array(), $projectData) ->shouldBeCalledTimes(1) ; - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -575,9 +548,7 @@ JSON; } JSON; - $this->remoteFilesystem - ->getContents(Argument::cetera(), $options) - ->willReturn($projectData) + $this->mockResponse(Argument::cetera(), $options, $projectData) ->shouldBeCalled(); $driver = new GitLabDriver( @@ -585,8 +556,15 @@ JSON; $this->io->reveal(), $this->config, $this->process->reveal(), - $this->remoteFilesystem->reveal() + $this->httpDownloader->reveal() ); $driver->initialize(); } + + private function mockResponse($url, $options, $return) + { + return $this->httpDownloader + ->get($url, $options) + ->willReturn(new Response(array('url' => $url), 200, array(), $return)); + } } diff --git a/tests/Composer/Test/Repository/Vcs/PerforceDriverTest.php b/tests/Composer/Test/Repository/Vcs/PerforceDriverTest.php index a5e5d4b4c..8225a4a54 100644 --- a/tests/Composer/Test/Repository/Vcs/PerforceDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/PerforceDriverTest.php @@ -26,7 +26,7 @@ class PerforceDriverTest extends TestCase protected $config; protected $io; protected $process; - protected $remoteFileSystem; + protected $httpDownloader; protected $testPath; protected $driver; protected $repoConfig; @@ -43,9 +43,9 @@ class PerforceDriverTest extends TestCase $this->repoConfig = $this->getTestRepoConfig(); $this->io = $this->getMockIOInterface(); $this->process = $this->getMockProcessExecutor(); - $this->remoteFileSystem = $this->getMockRemoteFilesystem(); + $this->httpDownloader = $this->getMockHttpDownloader(); $this->perforce = $this->getMockPerforce(); - $this->driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->remoteFileSystem); + $this->driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->httpDownloader); $this->overrideDriverInternalPerforce($this->perforce); } @@ -56,7 +56,7 @@ class PerforceDriverTest extends TestCase $fs->removeDirectory($this->testPath); $this->driver = null; $this->perforce = null; - $this->remoteFileSystem = null; + $this->httpDownloader = null; $this->process = null; $this->io = null; $this->repoConfig = null; @@ -99,9 +99,9 @@ class PerforceDriverTest extends TestCase return $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock(); } - protected function getMockRemoteFilesystem() + protected function getMockHttpDownloader() { - return $this->getMockBuilder('Composer\Util\RemoteFilesystem')->disableOriginalConstructor()->getMock(); + return $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(); } protected function getMockPerforce() @@ -113,7 +113,7 @@ class PerforceDriverTest extends TestCase public function testInitializeCapturesVariablesFromRepoConfig() { - $driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->remoteFileSystem); + $driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->httpDownloader); $driver->initialize(); $this->assertEquals(self::TEST_URL, $driver->getUrl()); $this->assertEquals(self::TEST_DEPOT, $driver->getDepot()); diff --git a/tests/Composer/Test/Util/BitbucketTest.php b/tests/Composer/Test/Util/BitbucketTest.php index 4323a15f5..f50bdd818 100644 --- a/tests/Composer/Test/Util/BitbucketTest.php +++ b/tests/Composer/Test/Util/BitbucketTest.php @@ -13,6 +13,7 @@ namespace Composer\Test\Util; use Composer\Util\Bitbucket; +use Composer\Util\Http\Response; use PHPUnit\Framework\TestCase; /** @@ -30,8 +31,8 @@ class BitbucketTest extends TestCase /** @type \Composer\IO\ConsoleIO|\PHPUnit_Framework_MockObject_MockObject */ private $io; - /** @type \Composer\Util\RemoteFilesystem|\PHPUnit_Framework_MockObject_MockObject */ - private $rfs; + /** @type \Composer\Util\HttpDownloader|\PHPUnit_Framework_MockObject_MockObject */ + private $httpDownloader; /** @type \Composer\Config|\PHPUnit_Framework_MockObject_MockObject */ private $config; /** @type Bitbucket */ @@ -47,8 +48,8 @@ class BitbucketTest extends TestCase ->getMock() ; - $this->rfs = $this - ->getMockBuilder('Composer\Util\RemoteFilesystem') + $this->httpDownloader = $this + ->getMockBuilder('Composer\Util\HttpDownloader') ->disableOriginalConstructor() ->getMock() ; @@ -57,7 +58,7 @@ class BitbucketTest extends TestCase $this->time = time(); - $this->bitbucket = new Bitbucket($this->io, $this->config, null, $this->rfs, $this->time); + $this->bitbucket = new Bitbucket($this->io, $this->config, null, $this->httpDownloader, $this->time); } public function testRequestAccessTokenWithValidOAuthConsumer() @@ -66,12 +67,10 @@ class BitbucketTest extends TestCase ->method('setAuthentication') ->with($this->origin, $this->consumer_key, $this->consumer_secret); - $this->rfs->expects($this->once()) - ->method('getContents') + $this->httpDownloader->expects($this->once()) + ->method('get') ->with( - $this->origin, Bitbucket::OAUTH2_ACCESS_TOKEN_URL, - false, array( 'retry-auth-failure' => false, 'http' => array( @@ -81,9 +80,14 @@ class BitbucketTest extends TestCase ) ) ->willReturn( - sprintf( - '{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refreshtoken", "token_type": "bearer"}', - $this->token + new Response( + array('url' => Bitbucket::OAUTH2_ACCESS_TOKEN_URL), + 200, + array(), + sprintf( + '{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refreshtoken", "token_type": "bearer"}', + $this->token + ) ) ); @@ -142,12 +146,10 @@ class BitbucketTest extends TestCase ->method('setAuthentication') ->with($this->origin, $this->consumer_key, $this->consumer_secret); - $this->rfs->expects($this->once()) - ->method('getContents') + $this->httpDownloader->expects($this->once()) + ->method('get') ->with( - $this->origin, Bitbucket::OAUTH2_ACCESS_TOKEN_URL, - false, array( 'retry-auth-failure' => false, 'http' => array( @@ -157,9 +159,14 @@ class BitbucketTest extends TestCase ) ) ->willReturn( - sprintf( - '{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refreshtoken", "token_type": "bearer"}', - $this->token + new Response( + array('url' => Bitbucket::OAUTH2_ACCESS_TOKEN_URL), + 200, + array(), + sprintf( + '{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refreshtoken", "token_type": "bearer"}', + $this->token + ) ) ); @@ -186,12 +193,10 @@ class BitbucketTest extends TestCase array('2. You are using an OAuth consumer, but didn\'t configure a (dummy) callback url') ); - $this->rfs->expects($this->once()) - ->method('getContents') + $this->httpDownloader->expects($this->once()) + ->method('get') ->with( - $this->origin, Bitbucket::OAUTH2_ACCESS_TOKEN_URL, - false, array( 'retry-auth-failure' => false, 'http' => array( @@ -234,21 +239,24 @@ class BitbucketTest extends TestCase ) ->willReturnOnConsecutiveCalls($this->consumer_key, $this->consumer_secret); - $this->rfs + $this->httpDownloader ->expects($this->once()) - ->method('getContents') + ->method('get') ->with( - $this->equalTo($this->origin), - $this->equalTo(sprintf('https://%s/site/oauth2/access_token', $this->origin)), - $this->isFalse(), + $this->equalTo($url = sprintf('https://%s/site/oauth2/access_token', $this->origin)), $this->anything() ) ->willReturn( - sprintf( - '{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refresh_token", "token_type": "bearer"}', - $this->token + new Response( + array('url' => $url), + 200, + array(), + sprintf( + '{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refresh_token", "token_type": "bearer"}', + $this->token + ) ) - ) + ); ; $this->setExpectationsForStoringAccessToken(true); diff --git a/tests/Composer/Test/Util/GitHubTest.php b/tests/Composer/Test/Util/GitHubTest.php index 28d00ce69..1893486e0 100644 --- a/tests/Composer/Test/Util/GitHubTest.php +++ b/tests/Composer/Test/Util/GitHubTest.php @@ -14,6 +14,7 @@ namespace Composer\Test\Util; use Composer\Downloader\TransportException; use Composer\Util\GitHub; +use Composer\Util\Http\Response; use PHPUnit\Framework\TestCase; use RecursiveArrayIterator; use RecursiveIteratorIterator; @@ -45,17 +46,15 @@ class GitHubTest extends TestCase ->willReturn($this->password) ; - $rfs = $this->getRemoteFilesystemMock(); - $rfs + $httpDownloader = $this->getHttpDownloaderMock(); + $httpDownloader ->expects($this->once()) - ->method('getContents') + ->method('get') ->with( - $this->equalTo($this->origin), - $this->equalTo(sprintf('https://api.%s/', $this->origin)), - $this->isFalse(), + $this->equalTo($url = sprintf('https://api.%s/', $this->origin)), $this->anything() ) - ->willReturn('{}') + ->willReturn(new Response(array('url' => $url), 200, array(), '{}')); ; $config = $this->getConfigMock(); @@ -70,7 +69,7 @@ class GitHubTest extends TestCase ->willReturn($this->getConfJsonMock()) ; - $github = new GitHub($io, $config, null, $rfs); + $github = new GitHub($io, $config, null, $httpDownloader); $this->assertTrue($github->authorizeOAuthInteractively($this->origin, $this->message)); } @@ -85,10 +84,10 @@ class GitHubTest extends TestCase ->willReturn($this->password) ; - $rfs = $this->getRemoteFilesystemMock(); - $rfs + $httpDownloader = $this->getHttpDownloaderMock(); + $httpDownloader ->expects($this->exactly(1)) - ->method('getContents') + ->method('get') ->will($this->throwException(new TransportException('', 401))) ; @@ -99,7 +98,7 @@ class GitHubTest extends TestCase ->willReturn($this->getAuthJsonMock()) ; - $github = new GitHub($io, $config, null, $rfs); + $github = new GitHub($io, $config, null, $httpDownloader); $this->assertFalse($github->authorizeOAuthInteractively($this->origin)); } @@ -120,15 +119,15 @@ class GitHubTest extends TestCase return $this->getMockBuilder('Composer\Config')->getMock(); } - private function getRemoteFilesystemMock() + private function getHttpDownloaderMock() { - $rfs = $this - ->getMockBuilder('Composer\Util\RemoteFilesystem') + $httpDownloader = $this + ->getMockBuilder('Composer\Util\HttpDownloader') ->disableOriginalConstructor() ->getMock() ; - return $rfs; + return $httpDownloader; } private function getAuthJsonMock() diff --git a/tests/Composer/Test/Util/GitLabTest.php b/tests/Composer/Test/Util/GitLabTest.php index 27f46b4ad..611b25256 100644 --- a/tests/Composer/Test/Util/GitLabTest.php +++ b/tests/Composer/Test/Util/GitLabTest.php @@ -14,6 +14,7 @@ namespace Composer\Test\Util; use Composer\Downloader\TransportException; use Composer\Util\GitLab; +use Composer\Util\Http\Response; use PHPUnit\Framework\TestCase; /** @@ -49,17 +50,15 @@ class GitLabTest extends TestCase ->willReturn($this->password) ; - $rfs = $this->getRemoteFilesystemMock(); - $rfs + $httpDownloader = $this->getHttpDownloaderMock(); + $httpDownloader ->expects($this->once()) - ->method('getContents') + ->method('get') ->with( - $this->equalTo($this->origin), - $this->equalTo(sprintf('http://%s/oauth/token', $this->origin)), - $this->isFalse(), + $this->equalTo($url = sprintf('http://%s/oauth/token', $this->origin)), $this->anything() ) - ->willReturn(sprintf('{"access_token": "%s", "token_type": "bearer", "expires_in": 7200}', $this->token)) + ->willReturn(new Response(array('url' => $url), 200, array(), sprintf('{"access_token": "%s", "token_type": "bearer", "expires_in": 7200}', $this->token))); ; $config = $this->getConfigMock(); @@ -69,7 +68,7 @@ class GitLabTest extends TestCase ->willReturn($this->getAuthJsonMock()) ; - $gitLab = new GitLab($io, $config, null, $rfs); + $gitLab = new GitLab($io, $config, null, $httpDownloader); $this->assertTrue($gitLab->authorizeOAuthInteractively('http', $this->origin, $this->message)); } @@ -94,10 +93,10 @@ class GitLabTest extends TestCase ->willReturn($this->password) ; - $rfs = $this->getRemoteFilesystemMock(); - $rfs + $httpDownloader = $this->getHttpDownloaderMock(); + $httpDownloader ->expects($this->exactly(5)) - ->method('getContents') + ->method('get') ->will($this->throwException(new TransportException('', 401))) ; @@ -108,7 +107,7 @@ class GitLabTest extends TestCase ->willReturn($this->getAuthJsonMock()) ; - $gitLab = new GitLab($io, $config, null, $rfs); + $gitLab = new GitLab($io, $config, null, $httpDownloader); $gitLab->authorizeOAuthInteractively('https', $this->origin); } @@ -129,15 +128,15 @@ class GitLabTest extends TestCase return $this->getMockBuilder('Composer\Config')->getMock(); } - private function getRemoteFilesystemMock() + private function getHttpDownloaderMock() { - $rfs = $this - ->getMockBuilder('Composer\Util\RemoteFilesystem') + $httpDownloader = $this + ->getMockBuilder('Composer\Util\HttpDownloader') ->disableOriginalConstructor() ->getMock() ; - return $rfs; + return $httpDownloader; } private function getAuthJsonMock()