From f946d8eb5a0104d3aefbd5b5fb8803355f482abf Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 12 Nov 2018 15:34:54 +0100 Subject: [PATCH] More RemoteFilesystem usage removals and some repository/vcs driver refactorings --- doc/articles/plugins.md | 2 +- doc/articles/scripts.md | 2 +- src/Composer/Command/DiagnoseCommand.php | 29 ++++++++-------- src/Composer/Command/SelfUpdateCommand.php | 8 ++--- src/Composer/Compiler.php | 1 + src/Composer/Factory.php | 12 +++---- src/Composer/Json/JsonFile.php | 20 +++++------ .../Package/Version/VersionGuesser.php | 3 +- .../Repository/ComposerRepository.php | 33 ++++++++++++------- src/Composer/Repository/PearRepository.php | 2 +- src/Composer/Repository/RepositoryFactory.php | 8 ++--- src/Composer/Repository/RepositoryManager.php | 8 ++--- .../Repository/Vcs/GitBitbucketDriver.php | 4 +-- src/Composer/Repository/Vcs/GitHubDriver.php | 4 +-- src/Composer/Repository/Vcs/GitLabDriver.php | 4 +-- .../Repository/Vcs/HgBitbucketDriver.php | 4 +-- src/Composer/Repository/Vcs/VcsDriver.php | 8 ++--- src/Composer/Repository/VcsRepository.php | 14 +++++--- src/Composer/SelfUpdate/Versions.php | 10 +++--- src/Composer/Util/HttpDownloader.php | 20 +++++++++++ .../Downloader/PerforceDownloaderTest.php | 3 +- tests/Composer/Test/InstallerTest.php | 2 +- .../Repository/ComposerRepositoryTest.php | 6 ++-- .../Test/Repository/PearRepositoryTest.php | 2 +- .../Test/Repository/RepositoryManagerTest.php | 8 ++--- .../Repository/Vcs/GitBitbucketDriverTest.php | 5 +-- .../Test/Repository/Vcs/GitHubDriverTest.php | 16 ++++++--- .../Test/Repository/Vcs/GitLabDriverTest.php | 18 +++++----- .../Repository/Vcs/PerforceDriverTest.php | 4 +-- .../Test/Repository/Vcs/SvnDriverTest.php | 3 +- 30 files changed, 156 insertions(+), 107 deletions(-) diff --git a/doc/articles/plugins.md b/doc/articles/plugins.md index 59e2a2f15..da20193f6 100644 --- a/doc/articles/plugins.md +++ b/doc/articles/plugins.md @@ -176,7 +176,7 @@ class AwsPlugin implements PluginInterface, EventSubscriberInterface if ($protocol === 's3') { $awsClient = new AwsClient($this->io, $this->composer->getConfig()); - $s3Downloader = new S3Downloader($this->io, $event->getRemoteFilesystem()->getOptions(), $awsClient); + $s3Downloader = new S3Downloader($this->io, $event->getHttpDownloader()->getOptions(), $awsClient); $event->setHttpdownloader($s3Downloader); } } diff --git a/doc/articles/scripts.md b/doc/articles/scripts.md index e0c27b10f..17c83c373 100644 --- a/doc/articles/scripts.md +++ b/doc/articles/scripts.md @@ -61,7 +61,7 @@ Composer fires the following named events during its execution process: - **command**: occurs before any Composer Command is executed on the CLI. It provides you with access to the input and output objects of the program. - **pre-file-download**: occurs before files are downloaded and allows - you to manipulate the `RemoteFilesystem` object prior to downloading files + you to manipulate the `HttpDownloader` object prior to downloading files based on the URL to be downloaded. - **pre-command-run**: occurs before a command is executed and allows you to manipulate the `InputInterface` object's options and arguments to tweak diff --git a/src/Composer/Command/DiagnoseCommand.php b/src/Composer/Command/DiagnoseCommand.php index 3c4c3bb32..481d58060 100644 --- a/src/Composer/Command/DiagnoseCommand.php +++ b/src/Composer/Command/DiagnoseCommand.php @@ -22,7 +22,7 @@ use Composer\Plugin\PluginEvents; use Composer\Util\ConfigValidator; use Composer\Util\IniHelper; use Composer\Util\ProcessExecutor; -use Composer\Util\RemoteFilesystem; +use Composer\Util\HttpDownloader; use Composer\Util\StreamContextFactory; use Composer\SelfUpdate\Keys; use Composer\SelfUpdate\Versions; @@ -35,8 +35,8 @@ use Symfony\Component\Console\Output\OutputInterface; */ class DiagnoseCommand extends BaseCommand { - /** @var RemoteFilesystem */ - protected $rfs; + /** @var HttpDownloader */ + protected $httpDownloader; /** @var ProcessExecutor */ protected $process; @@ -85,7 +85,7 @@ EOT $config->merge(array('config' => array('secure-http' => false))); $config->prohibitUrlByConfig('http://repo.packagist.org', new NullIO); - $this->rfs = Factory::createRemoteFilesystem($io, $config); + $this->httpDownloader = Factory::createHttpDownloader($io, $config); $this->process = new ProcessExecutor($io); $io->write('Checking platform settings: ', false); @@ -226,7 +226,7 @@ EOT } try { - $this->rfs->getContents('packagist.org', $proto . '://repo.packagist.org/packages.json', false); + $this->httpDownloader->get($proto . '://repo.packagist.org/packages.json'); } catch (TransportException $e) { if (false !== strpos($e->getMessage(), 'cafile')) { $result[] = '[' . get_class($e) . '] ' . $e->getMessage() . ''; @@ -253,11 +253,11 @@ EOT $protocol = extension_loaded('openssl') ? 'https' : 'http'; try { - $json = json_decode($this->rfs->getContents('packagist.org', $protocol . '://repo.packagist.org/packages.json', false), true); + $json = $this->httpDownloader->get($protocol . '://repo.packagist.org/packages.json')->parseJson(); $hash = reset($json['provider-includes']); $hash = $hash['sha256']; $path = str_replace('%hash%', $hash, key($json['provider-includes'])); - $provider = $this->rfs->getContents('packagist.org', $protocol . '://repo.packagist.org/'.$path, false); + $provider = $this->httpDownloader->get($protocol . '://repo.packagist.org/'.$path)->getBody(); if (hash('sha256', $provider) !== $hash) { return 'It seems that your proxy is modifying http traffic on the fly'; @@ -285,10 +285,10 @@ EOT $url = 'http://repo.packagist.org/packages.json'; try { - $this->rfs->getContents('packagist.org', $url, false); + $this->httpDownloader->get($url); } catch (TransportException $e) { try { - $this->rfs->getContents('packagist.org', $url, false, array('http' => array('request_fulluri' => false))); + $this->httpDownloader->get($url, array('http' => array('request_fulluri' => false))); } catch (TransportException $e) { return 'Unable to assess the situation, maybe packagist.org is down ('.$e->getMessage().')'; } @@ -319,10 +319,10 @@ EOT $url = 'https://api.github.com/repos/Seldaek/jsonlint/zipball/1.0.0'; try { - $this->rfs->getContents('github.com', $url, false); + $this->httpDownloader->get($url); } catch (TransportException $e) { try { - $this->rfs->getContents('github.com', $url, false, array('http' => array('request_fulluri' => false))); + $this->httpDownloader->get($url, array('http' => array('request_fulluri' => false))); } catch (TransportException $e) { return 'Unable to assess the situation, maybe github is down ('.$e->getMessage().')'; } @@ -344,7 +344,7 @@ EOT try { $url = $domain === 'github.com' ? 'https://api.'.$domain.'/' : 'https://'.$domain.'/api/v3/'; - return $this->rfs->getContents($domain, $url, false, array( + return $this->httpDownloader->get($url, array( 'retry-auth-failure' => false, )) ? true : 'Unexpected error'; } catch (\Exception $e) { @@ -374,8 +374,7 @@ EOT } $url = $domain === 'github.com' ? 'https://api.'.$domain.'/rate_limit' : 'https://'.$domain.'/api/rate_limit'; - $json = $this->rfs->getContents($domain, $url, false, array('retry-auth-failure' => false)); - $data = json_decode($json, true); + $data = $this->httpDownloader->get($url, array('retry-auth-failure' => false))->parseJson(); return $data['resources']['core']; } @@ -428,7 +427,7 @@ EOT return $result; } - $versionsUtil = new Versions($config, $this->rfs); + $versionsUtil = new Versions($config, $this->httpDownloader); $latest = $versionsUtil->getLatest(); if (Composer::VERSION !== $latest['version'] && Composer::VERSION !== '@package_version@') { diff --git a/src/Composer/Command/SelfUpdateCommand.php b/src/Composer/Command/SelfUpdateCommand.php index 243755963..903b49d94 100644 --- a/src/Composer/Command/SelfUpdateCommand.php +++ b/src/Composer/Command/SelfUpdateCommand.php @@ -76,9 +76,9 @@ EOT } $io = $this->getIO(); - $remoteFilesystem = Factory::createRemoteFilesystem($io, $config); + $httpDownloader = Factory::createHttpDownloader($io, $config); - $versionsUtil = new Versions($config, $remoteFilesystem); + $versionsUtil = new Versions($config, $httpDownloader); // switch channel if requested foreach (array('stable', 'preview', 'snapshot') as $channel) { @@ -155,9 +155,9 @@ EOT $io->write(sprintf("Updating to version %s (%s channel).", $updateVersion, $versionsUtil->getChannel())); $remoteFilename = $baseUrl . ($updatingToTag ? "/download/{$updateVersion}/composer.phar" : '/composer.phar'); - $signature = $remoteFilesystem->getContents(self::HOMEPAGE, $remoteFilename.'.sig', false); + $signature = $httpDownloader->get($remoteFilename.'.sig')->getBody(); $io->writeError(' ', false); - $remoteFilesystem->copy(self::HOMEPAGE, $remoteFilename, $tempFilename, !$input->getOption('no-progress')); + $httpDownloader->copy($remoteFilename, $tempFilename); $io->writeError(''); if (!file_exists($tempFilename) || !$signature) { diff --git a/src/Composer/Compiler.php b/src/Composer/Compiler.php index 27b1f4816..86be2d7db 100644 --- a/src/Composer/Compiler.php +++ b/src/Composer/Compiler.php @@ -123,6 +123,7 @@ class Compiler ->in(__DIR__.'/../../vendor/composer/ca-bundle/') ->in(__DIR__.'/../../vendor/composer/xdebug-handler/') ->in(__DIR__.'/../../vendor/psr/') + ->in(__DIR__.'/../../vendor/react/') ->sort($finderSort) ; diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 00aa499d0..c96fd2188 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -590,18 +590,18 @@ class Factory throw new Exception\NoSslException('The openssl extension is required for SSL/TLS protection but is not available. ' . 'If you can not enable the openssl extension, you can disable this error, at your own risk, by setting the \'disable-tls\' option to true.'); } - $remoteFilesystemOptions = array(); + $httpDownloaderOptions = array(); if ($disableTls === false) { if ($config && $config->get('cafile')) { - $remoteFilesystemOptions['ssl']['cafile'] = $config->get('cafile'); + $httpDownloaderOptions['ssl']['cafile'] = $config->get('cafile'); } if ($config && $config->get('capath')) { - $remoteFilesystemOptions['ssl']['capath'] = $config->get('capath'); + $httpDownloaderOptions['ssl']['capath'] = $config->get('capath'); } - $remoteFilesystemOptions = array_replace_recursive($remoteFilesystemOptions, $options); + $httpDownloaderOptions = array_replace_recursive($httpDownloaderOptions, $options); } try { - $remoteFilesystem = new HttpDownloader($io, $config, $remoteFilesystemOptions, $disableTls); + $httpDownloader = new HttpDownloader($io, $config, $httpDownloaderOptions, $disableTls); } catch (TransportException $e) { if (false !== strpos($e->getMessage(), 'cafile')) { $io->write('Unable to locate a valid CA certificate file. You must set a valid \'cafile\' option.'); @@ -614,7 +614,7 @@ class Factory throw $e; } - return $remoteFilesystem; + return $httpDownloader; } /** diff --git a/src/Composer/Json/JsonFile.php b/src/Composer/Json/JsonFile.php index b84791420..a61a75c34 100644 --- a/src/Composer/Json/JsonFile.php +++ b/src/Composer/Json/JsonFile.php @@ -15,7 +15,7 @@ namespace Composer\Json; use JsonSchema\Validator; use Seld\JsonLint\JsonParser; use Seld\JsonLint\ParsingException; -use Composer\Util\RemoteFilesystem; +use Composer\Util\HttpDownloader; use Composer\IO\IOInterface; use Composer\Downloader\TransportException; @@ -35,25 +35,25 @@ class JsonFile const JSON_UNESCAPED_UNICODE = 256; private $path; - private $rfs; + private $httpDownloader; private $io; /** * Initializes json file reader/parser. * - * @param string $path path to a lockfile - * @param RemoteFilesystem $rfs required for loading http/https json files + * @param string $path path to a lockfile + * @param HttpDownloader $httpDownloader required for loading http/https json files * @param IOInterface $io * @throws \InvalidArgumentException */ - public function __construct($path, RemoteFilesystem $rfs = null, IOInterface $io = null) + public function __construct($path, HttpDownloader $httpDownloader = null, IOInterface $io = null) { $this->path = $path; - if (null === $rfs && preg_match('{^https?://}i', $path)) { - throw new \InvalidArgumentException('http urls require a RemoteFilesystem instance to be passed'); + if (null === $httpDownloader && preg_match('{^https?://}i', $path)) { + throw new \InvalidArgumentException('http urls require a HttpDownloader instance to be passed'); } - $this->rfs = $rfs; + $this->httpDownloader = $httpDownloader; $this->io = $io; } @@ -84,8 +84,8 @@ class JsonFile public function read() { try { - if ($this->rfs) { - $json = $this->rfs->getContents($this->path, $this->path, false); + if ($this->httpDownloader) { + $json = $this->httpDownloader->get($this->path)->getBody(); } else { if ($this->io && $this->io->isDebug()) { $this->io->writeError('Reading ' . $this->path); diff --git a/src/Composer/Package/Version/VersionGuesser.php b/src/Composer/Package/Version/VersionGuesser.php index e6ff84965..1c2fdf986 100644 --- a/src/Composer/Package/Version/VersionGuesser.php +++ b/src/Composer/Package/Version/VersionGuesser.php @@ -192,7 +192,8 @@ class VersionGuesser } // re-use the HgDriver to fetch branches (this properly includes bookmarks) - $driver = new HgDriver(array('url' => $path), new NullIO(), $this->config, $this->process); + $io = new NullIO(); + $driver = new HgDriver(array('url' => $path), $io, $this->config, new HttpDownloader($io, $this->config), $this->process); $branches = array_keys($driver->getBranches()); // try to find the best (nearest) version branch to assume this feature's version diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index a0036e4fd..b337ea106 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -62,7 +62,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito private $partialPackagesByName; private $versionParser; - public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $eventDispatcher, HttpDownloader $httpDownloader) + public function __construct(array $repoConfig, IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null) { parent::__construct(); if (!preg_match('{^[\w.]+\??://}', $repoConfig['url'])) { @@ -101,7 +101,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $this->cache = new Cache($io, $config->get('cache-repo-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $this->url), 'a-z0-9.$'); $this->versionParser = new VersionParser(); $this->loader = new ArrayLoader($this->versionParser); - if ($httpDownloader && $this->options) { + if ($this->options) { // TODO solve this somehow - should be sent at request time not on the instance $httpDownloader = clone $httpDownloader; $httpDownloader->setOptions($this->options); @@ -781,10 +781,13 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $retries = 3; while ($retries--) { try { - $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename); - $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); + $httpDownloader = $this->httpDownloader; - $httpDownloader = $preFileDownloadEvent->getHttpDownloader(); + if ($this->eventDispatcher) { + $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename); + $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); + $httpDownloader = $preFileDownloadEvent->getHttpDownloader(); + } $response = $httpDownloader->get($filename); $json = $response->getBody(); @@ -869,10 +872,14 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $retries = 3; while ($retries--) { try { - $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename); - $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); + $httpDownloader = $this->httpDownloader; + + if ($this->eventDispatcher) { + $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename); + $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); + $httpDownloader = $preFileDownloadEvent->getHttpDownloader(); + } - $httpDownloader = $preFileDownloadEvent->getHttpDownloader(); $options = array('http' => array('header' => array('If-Modified-Since: '.$lastModifiedTime))); $response = $httpDownloader->get($filename, $options); $json = $response->getBody(); @@ -925,10 +932,14 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito protected function asyncFetchFile($filename, $cacheKey, $lastModifiedTime = null) { $retries = 3; - $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename); - $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); + $httpDownloader = $this->httpDownloader; + + if ($this->eventDispatcher) { + $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename); + $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); + $httpDownloader = $preFileDownloadEvent->getHttpDownloader(); + } - $httpDownloader = $preFileDownloadEvent->getHttpDownloader(); $options = $lastModifiedTime ? array('http' => array('header' => array('If-Modified-Since: '.$lastModifiedTime))) : array(); $io = $this->io; diff --git a/src/Composer/Repository/PearRepository.php b/src/Composer/Repository/PearRepository.php index aef5c0381..1bb22c0ed 100644 --- a/src/Composer/Repository/PearRepository.php +++ b/src/Composer/Repository/PearRepository.php @@ -47,7 +47,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn */ private $vendorAlias; - public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher, HttpDownloader $httpDownloader) + public function __construct(array $repoConfig, IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $dispatcher = null) { parent::__construct(); if (!preg_match('{^https?://}', $repoConfig['url'])) { diff --git a/src/Composer/Repository/RepositoryFactory.php b/src/Composer/Repository/RepositoryFactory.php index 515908f64..9508f5886 100644 --- a/src/Composer/Repository/RepositoryFactory.php +++ b/src/Composer/Repository/RepositoryFactory.php @@ -36,7 +36,7 @@ class RepositoryFactory if (0 === strpos($repository, 'http')) { $repoConfig = array('type' => 'composer', 'url' => $repository); } elseif ("json" === pathinfo($repository, PATHINFO_EXTENSION)) { - $json = new JsonFile($repository, Factory::createRemoteFilesystem($io, $config)); + $json = new JsonFile($repository, Factory::createHttpDownloader($io, $config)); $data = $json->read(); if (!empty($data['packages']) || !empty($data['includes']) || !empty($data['provider-includes'])) { $repoConfig = array('type' => 'composer', 'url' => 'file://' . strtr(realpath($repository), '\\', '/')); @@ -77,7 +77,7 @@ class RepositoryFactory */ public static function createRepo(IOInterface $io, Config $config, array $repoConfig) { - $rm = static::manager($io, $config, null, Factory::createRemoteFilesystem($io, $config)); + $rm = static::manager($io, $config, Factory::createHttpDownloader($io, $config)); $repos = static::createRepos($rm, array($repoConfig)); return reset($repos); @@ -98,7 +98,7 @@ class RepositoryFactory if (!$io) { throw new \InvalidArgumentException('This function requires either an IOInterface or a RepositoryManager'); } - $rm = static::manager($io, $config, null, Factory::createRemoteFilesystem($io, $config)); + $rm = static::manager($io, $config, Factory::createHttpDownloader($io, $config)); } return static::createRepos($rm, $config->getRepositories()); @@ -113,7 +113,7 @@ class RepositoryFactory */ public static function manager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null) { - $rm = new RepositoryManager($io, $config, $eventDispatcher, $httpDownloader); + $rm = new RepositoryManager($io, $config, $httpDownloader, $eventDispatcher); $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 8fc01cb08..c3ce0c24a 100644 --- a/src/Composer/Repository/RepositoryManager.php +++ b/src/Composer/Repository/RepositoryManager.php @@ -35,12 +35,12 @@ class RepositoryManager private $eventDispatcher; private $httpDownloader; - public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher, HttpDownloader $httpDownloader) + public function __construct(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null) { $this->io = $io; $this->config = $config; - $this->eventDispatcher = $eventDispatcher; $this->httpDownloader = $httpDownloader; + $this->eventDispatcher = $eventDispatcher; } /** @@ -127,8 +127,8 @@ 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->httpDownloader); + if (isset($params[3]) && $params[3]->getClass() && $params[3]->getClass()->getName() === 'Composer\Util\HttpDownloader') { + return new $class($config, $this->io, $this->config, $this->httpDownloader, $this->eventDispatcher); } return new $class($config, $this->io, $this->config, $this->eventDispatcher); diff --git a/src/Composer/Repository/Vcs/GitBitbucketDriver.php b/src/Composer/Repository/Vcs/GitBitbucketDriver.php index dd69e753a..5770a8326 100644 --- a/src/Composer/Repository/Vcs/GitBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/GitBitbucketDriver.php @@ -75,8 +75,8 @@ class GitBitbucketDriver extends BitbucketDriver array('url' => $url), $this->io, $this->config, - $this->process, - $this->httpDownloader + $this->httpDownloader, + $this->process ); $this->fallbackDriver->initialize(); } diff --git a/src/Composer/Repository/Vcs/GitHubDriver.php b/src/Composer/Repository/Vcs/GitHubDriver.php index f1ad253d8..69eef200d 100644 --- a/src/Composer/Repository/Vcs/GitHubDriver.php +++ b/src/Composer/Repository/Vcs/GitHubDriver.php @@ -457,8 +457,8 @@ class GitHubDriver extends VcsDriver array('url' => $url), $this->io, $this->config, - $this->process, - $this->httpDownloader + $this->httpDownloader, + $this->process ); $this->gitDriver->initialize(); } diff --git a/src/Composer/Repository/Vcs/GitLabDriver.php b/src/Composer/Repository/Vcs/GitLabDriver.php index 6a1aa8ac2..1e2775ff7 100644 --- a/src/Composer/Repository/Vcs/GitLabDriver.php +++ b/src/Composer/Repository/Vcs/GitLabDriver.php @@ -376,8 +376,8 @@ class GitLabDriver extends VcsDriver array('url' => $url), $this->io, $this->config, - $this->process, - $this->httpDownloader + $this->httpDownloader, + $this->process ); $this->gitDriver->initialize(); } diff --git a/src/Composer/Repository/Vcs/HgBitbucketDriver.php b/src/Composer/Repository/Vcs/HgBitbucketDriver.php index 4a00f2da0..a919e7860 100644 --- a/src/Composer/Repository/Vcs/HgBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/HgBitbucketDriver.php @@ -75,8 +75,8 @@ class HgBitbucketDriver extends BitbucketDriver array('url' => $url), $this->io, $this->config, - $this->process, - $this->httpDownloader + $this->httpDownloader, + $this->process ); $this->fallbackDriver->initialize(); } diff --git a/src/Composer/Repository/Vcs/VcsDriver.php b/src/Composer/Repository/Vcs/VcsDriver.php index 17ed706d2..37946da23 100644 --- a/src/Composer/Repository/Vcs/VcsDriver.php +++ b/src/Composer/Repository/Vcs/VcsDriver.php @@ -55,10 +55,10 @@ abstract class VcsDriver implements VcsDriverInterface * @param array $repoConfig The repository configuration * @param IOInterface $io The IO instance * @param Config $config The composer configuration + * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking * @param ProcessExecutor $process Process instance, injectable for mocking - * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking */ - final public function __construct(array $repoConfig, IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null) + final public function __construct(array $repoConfig, IOInterface $io, Config $config, HttpDownloader $httpDownloader, ProcessExecutor $process) { if (Filesystem::isLocalPath($repoConfig['url'])) { $repoConfig['url'] = Filesystem::getPlatformPath($repoConfig['url']); @@ -69,8 +69,8 @@ abstract class VcsDriver implements VcsDriverInterface $this->repoConfig = $repoConfig; $this->io = $io; $this->config = $config; - $this->process = $process ?: new ProcessExecutor($io); - $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config); + $this->httpDownloader = $httpDownloader; + $this->process = $process; } /** diff --git a/src/Composer/Repository/VcsRepository.php b/src/Composer/Repository/VcsRepository.php index d6fb1bbee..d8e4b1501 100644 --- a/src/Composer/Repository/VcsRepository.php +++ b/src/Composer/Repository/VcsRepository.php @@ -20,6 +20,8 @@ use Composer\Package\Loader\ValidatingArrayLoader; use Composer\Package\Loader\InvalidPackageException; use Composer\Package\Loader\LoaderInterface; use Composer\EventDispatcher\EventDispatcher; +use Composer\Util\ProcessExecutor; +use Composer\Util\HttpDownloader; use Composer\IO\IOInterface; use Composer\Config; @@ -37,6 +39,8 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt protected $type; protected $loader; protected $repoConfig; + protected $httpDownloader; + protected $processExecutor; protected $branchErrorOccurred = false; private $drivers; /** @var VcsDriverInterface */ @@ -44,7 +48,7 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt /** @var VersionCacheInterface */ private $versionCache; - public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher = null, array $drivers = null, VersionCacheInterface $versionCache = null) + public function __construct(array $repoConfig, IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $dispatcher = null, array $drivers = null, VersionCacheInterface $versionCache = null) { parent::__construct(); $this->drivers = $drivers ?: array( @@ -67,6 +71,8 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt $this->config = $config; $this->repoConfig = $repoConfig; $this->versionCache = $versionCache; + $this->httpDownloader = $httpDownloader; + $this->processExecutor = new ProcessExecutor($io); } public function getRepoConfig() @@ -87,7 +93,7 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt if (isset($this->drivers[$this->type])) { $class = $this->drivers[$this->type]; - $this->driver = new $class($this->repoConfig, $this->io, $this->config); + $this->driver = new $class($this->repoConfig, $this->io, $this->config, $this->httpDownloader, $this->processExecutor); $this->driver->initialize(); return $this->driver; @@ -95,7 +101,7 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt foreach ($this->drivers as $driver) { if ($driver::supports($this->io, $this->config, $this->url)) { - $this->driver = new $driver($this->repoConfig, $this->io, $this->config); + $this->driver = new $driver($this->repoConfig, $this->io, $this->config, $this->httpDownloader, $this->processExecutor); $this->driver->initialize(); return $this->driver; @@ -104,7 +110,7 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt foreach ($this->drivers as $driver) { if ($driver::supports($this->io, $this->config, $this->url, true)) { - $this->driver = new $driver($this->repoConfig, $this->io, $this->config); + $this->driver = new $driver($this->repoConfig, $this->io, $this->config, $this->httpDownloader, $this->processExecutor); $this->driver->initialize(); return $this->driver; diff --git a/src/Composer/SelfUpdate/Versions.php b/src/Composer/SelfUpdate/Versions.php index b619bda16..431abecb5 100644 --- a/src/Composer/SelfUpdate/Versions.php +++ b/src/Composer/SelfUpdate/Versions.php @@ -12,7 +12,7 @@ namespace Composer\SelfUpdate; -use Composer\Util\RemoteFilesystem; +use Composer\Util\HttpDownloader; use Composer\Config; use Composer\Json\JsonFile; @@ -21,13 +21,13 @@ use Composer\Json\JsonFile; */ class Versions { - private $rfs; + private $httpDownloader; private $config; private $channel; - public function __construct(Config $config, RemoteFilesystem $rfs) + public function __construct(Config $config, HttpDownloader $httpDownloader) { - $this->rfs = $rfs; + $this->httpDownloader = $httpDownloader; $this->config = $config; } @@ -62,7 +62,7 @@ class Versions public function getLatest() { $protocol = extension_loaded('openssl') ? 'https' : 'http'; - $versions = JsonFile::parseJson($this->rfs->getContents('getcomposer.org', $protocol . '://getcomposer.org/versions', false)); + $versions = $this->httpDownloader->get($protocol . '://getcomposer.org/versions')->decodeJson(); foreach ($versions[$this->getChannel()] as $version) { if ($version['min-php'] <= PHP_VERSION_ID) { diff --git a/src/Composer/Util/HttpDownloader.php b/src/Composer/Util/HttpDownloader.php index 631c0df7d..920c5f75a 100644 --- a/src/Composer/Util/HttpDownloader.php +++ b/src/Composer/Util/HttpDownloader.php @@ -102,6 +102,26 @@ class HttpDownloader return $promise; } + /** + * Retrieve the options set in the constructor + * + * @return array Options + */ + public function getOptions() + { + return $this->options; + } + + /** + * Merges new options + * + * @return array $options + */ + public function setOptions(array $options) + { + $this->options = array_replace_recursive($this->options, $options); + } + private function addJob($request, $sync = false) { $job = array( diff --git a/tests/Composer/Test/Downloader/PerforceDownloaderTest.php b/tests/Composer/Test/Downloader/PerforceDownloaderTest.php index ebb1f0456..1b5041d9f 100644 --- a/tests/Composer/Test/Downloader/PerforceDownloaderTest.php +++ b/tests/Composer/Test/Downloader/PerforceDownloaderTest.php @@ -17,6 +17,7 @@ use Composer\Config; use Composer\Repository\VcsRepository; use Composer\IO\IOInterface; use Composer\Test\TestCase; +use Composer\Factory; use Composer\Util\Filesystem; /** @@ -96,7 +97,7 @@ class PerforceDownloaderTest extends TestCase { $repository = $this->getMockBuilder('Composer\Repository\VcsRepository') ->setMethods(array('getRepoConfig')) - ->setConstructorArgs(array($repoConfig, $io, $config)) + ->setConstructorArgs(array($repoConfig, $io, $config, Factory::createHttpDownloader($io, $config))) ->getMock(); $repository->expects($this->any())->method('getRepoConfig')->will($this->returnValue($repoConfig)); diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index 2e7d70639..acaf8f1ff 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -65,7 +65,7 @@ class InstallerTest extends TestCase $eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(); $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(); - $repositoryManager = new RepositoryManager($io, $config, $eventDispatcher, $httpDownloader); + $repositoryManager = new RepositoryManager($io, $config, $httpDownloader, $eventDispatcher); $repositoryManager->setLocalRepository(new InstalledArrayRepository()); if (!is_array($repositories)) { diff --git a/tests/Composer/Test/Repository/ComposerRepositoryTest.php b/tests/Composer/Test/Repository/ComposerRepositoryTest.php index 1fe60f589..0ffd70751 100644 --- a/tests/Composer/Test/Repository/ComposerRepositoryTest.php +++ b/tests/Composer/Test/Repository/ComposerRepositoryTest.php @@ -37,8 +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() + $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(), + $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock() )) ->getMock(); @@ -203,7 +203,7 @@ class ComposerRepositoryTest extends TestCase ->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); + $repository = new ComposerRepository($repoConfig, new NullIO, FactoryMock::createConfig(), $httpDownloader, $eventDispatcher); $this->assertSame( array(array('name' => 'foo', 'description' => null)), diff --git a/tests/Composer/Test/Repository/PearRepositoryTest.php b/tests/Composer/Test/Repository/PearRepositoryTest.php index 6046fefb4..867d4978d 100644 --- a/tests/Composer/Test/Repository/PearRepositoryTest.php +++ b/tests/Composer/Test/Repository/PearRepositoryTest.php @@ -28,7 +28,7 @@ class PearRepositoryTest extends TestCase /** * @var \PHPUnit_Framework_MockObject_MockObject */ - private $remoteFilesystem; + private $httpDownloader; public function testComposerShouldSetIncludePath() { diff --git a/tests/Composer/Test/Repository/RepositoryManagerTest.php b/tests/Composer/Test/Repository/RepositoryManagerTest.php index c4f09de87..35afd91e2 100644 --- a/tests/Composer/Test/Repository/RepositoryManagerTest.php +++ b/tests/Composer/Test/Repository/RepositoryManagerTest.php @@ -38,8 +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\Util\HttpDownloader')->disableOriginalConstructor()->getMock() + $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(), + $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock() ); $repository1 = $this->getMockBuilder('Composer\Repository\RepositoryInterface')->getMock(); @@ -62,8 +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\Util\HttpDownloader')->disableOriginalConstructor()->getMock() + $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(), + $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock() ); $tmpdir = $this->tmpdir; diff --git a/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php index a3a9219d9..f0139970b 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\ProcessExecutor; use Composer\Util\Http\Response; /** @@ -68,8 +69,8 @@ class GitBitbucketDriverTest extends TestCase $repoConfig, $this->io, $this->config, - null, - $this->httpDownloader + $this->httpDownloader, + new ProcessExecutor($this->io) ); $driver->initialize(); diff --git a/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php index 1f721a4c7..977a4a7aa 100644 --- a/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php @@ -96,7 +96,7 @@ class GitHubDriverTest extends TestCase 'url' => $repoUrl, ); - $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $httpDownloader); + $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $httpDownloader, $process); $gitHubDriver->initialize(); $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha)); @@ -139,7 +139,11 @@ class GitHubDriverTest extends TestCase ); $repoUrl = 'https://github.com/composer/packagist.git'; - $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $httpDownloader); + $process = $this->getMockBuilder('Composer\Util\ProcessExecutor') + ->disableOriginalConstructor() + ->getMock(); + + $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $httpDownloader, $process); $gitHubDriver->initialize(); $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha)); @@ -192,7 +196,11 @@ class GitHubDriverTest extends TestCase ); $repoUrl = 'https://github.com/composer/packagist.git'; - $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $httpDownloader); + $process = $this->getMockBuilder('Composer\Util\ProcessExecutor') + ->disableOriginalConstructor() + ->getMock(); + + $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config,$httpDownloader, $process); $gitHubDriver->initialize(); $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha)); @@ -279,7 +287,7 @@ class GitHubDriverTest extends TestCase 'url' => $repoUrl, ); - $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $httpDownloader); + $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $httpDownloader, $process); $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 f940733ae..0fd2fa956 100644 --- a/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php @@ -92,7 +92,7 @@ JSON; ->shouldBeCalledTimes(1) ; - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->httpDownloader->reveal(), $this->process->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -129,7 +129,7 @@ JSON; ->shouldBeCalledTimes(1) ; - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->httpDownloader->reveal(), $this->process->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -165,7 +165,7 @@ JSON; ->shouldBeCalledTimes(1) ; - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->httpDownloader->reveal(), $this->process->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -204,7 +204,7 @@ JSON; $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->httpDownloader->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->httpDownloader->reveal(), $this->process->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -457,7 +457,7 @@ JSON; ->shouldBeCalledTimes(1) ; - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->httpDownloader->reveal(), $this->process->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -488,7 +488,7 @@ JSON; ->shouldBeCalledTimes(1) ; - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->httpDownloader->reveal(), $this->process->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -519,7 +519,7 @@ JSON; ->shouldBeCalledTimes(1) ; - $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal()); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->httpDownloader->reveal(), $this->process->reveal()); $driver->initialize(); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); @@ -555,8 +555,8 @@ JSON; array('url' => 'https://gitlab.mycompany.local/mygroup/myproject', 'options' => $options), $this->io->reveal(), $this->config, - $this->process->reveal(), - $this->httpDownloader->reveal() + $this->httpDownloader->reveal(), + $this->process->reveal() ); $driver->initialize(); } diff --git a/tests/Composer/Test/Repository/Vcs/PerforceDriverTest.php b/tests/Composer/Test/Repository/Vcs/PerforceDriverTest.php index 8225a4a54..ff4e19121 100644 --- a/tests/Composer/Test/Repository/Vcs/PerforceDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/PerforceDriverTest.php @@ -45,7 +45,7 @@ class PerforceDriverTest extends TestCase $this->process = $this->getMockProcessExecutor(); $this->httpDownloader = $this->getMockHttpDownloader(); $this->perforce = $this->getMockPerforce(); - $this->driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->httpDownloader); + $this->driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->httpDownloader, $this->process); $this->overrideDriverInternalPerforce($this->perforce); } @@ -113,7 +113,7 @@ class PerforceDriverTest extends TestCase public function testInitializeCapturesVariablesFromRepoConfig() { - $driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->httpDownloader); + $driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->httpDownloader, $this->process); $driver->initialize(); $this->assertEquals(self::TEST_URL, $driver->getUrl()); $this->assertEquals(self::TEST_DEPOT, $driver->getDepot()); diff --git a/tests/Composer/Test/Repository/Vcs/SvnDriverTest.php b/tests/Composer/Test/Repository/Vcs/SvnDriverTest.php index 029d20160..946c198f2 100644 --- a/tests/Composer/Test/Repository/Vcs/SvnDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/SvnDriverTest.php @@ -46,6 +46,7 @@ class SvnDriverTest extends TestCase public function testWrongCredentialsInUrl() { $console = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); + $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(); $output = "svn: OPTIONS of 'https://corp.svn.local/repo':"; $output .= " authorization failed: Could not authenticate to server:"; @@ -66,7 +67,7 @@ class SvnDriverTest extends TestCase 'url' => 'https://till:secret@corp.svn.local/repo', ); - $svn = new SvnDriver($repoConfig, $console, $this->config, $process); + $svn = new SvnDriver($repoConfig, $console, $this->config, $httpDownloader, $process); $svn->initialize(); }