Forráskód Böngészése

More RemoteFilesystem usage removals and some repository/vcs driver refactorings

Jordi Boggiano 6 éve
szülő
commit
f946d8eb5a
30 módosított fájl, 156 hozzáadás és 107 törlés
  1. 1 1
      doc/articles/plugins.md
  2. 1 1
      doc/articles/scripts.md
  3. 14 15
      src/Composer/Command/DiagnoseCommand.php
  4. 4 4
      src/Composer/Command/SelfUpdateCommand.php
  5. 1 0
      src/Composer/Compiler.php
  6. 6 6
      src/Composer/Factory.php
  7. 10 10
      src/Composer/Json/JsonFile.php
  8. 2 1
      src/Composer/Package/Version/VersionGuesser.php
  9. 22 11
      src/Composer/Repository/ComposerRepository.php
  10. 1 1
      src/Composer/Repository/PearRepository.php
  11. 4 4
      src/Composer/Repository/RepositoryFactory.php
  12. 4 4
      src/Composer/Repository/RepositoryManager.php
  13. 2 2
      src/Composer/Repository/Vcs/GitBitbucketDriver.php
  14. 2 2
      src/Composer/Repository/Vcs/GitHubDriver.php
  15. 2 2
      src/Composer/Repository/Vcs/GitLabDriver.php
  16. 2 2
      src/Composer/Repository/Vcs/HgBitbucketDriver.php
  17. 4 4
      src/Composer/Repository/Vcs/VcsDriver.php
  18. 10 4
      src/Composer/Repository/VcsRepository.php
  19. 5 5
      src/Composer/SelfUpdate/Versions.php
  20. 20 0
      src/Composer/Util/HttpDownloader.php
  21. 2 1
      tests/Composer/Test/Downloader/PerforceDownloaderTest.php
  22. 1 1
      tests/Composer/Test/InstallerTest.php
  23. 3 3
      tests/Composer/Test/Repository/ComposerRepositoryTest.php
  24. 1 1
      tests/Composer/Test/Repository/PearRepositoryTest.php
  25. 4 4
      tests/Composer/Test/Repository/RepositoryManagerTest.php
  26. 3 2
      tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php
  27. 12 4
      tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php
  28. 9 9
      tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php
  29. 2 2
      tests/Composer/Test/Repository/Vcs/PerforceDriverTest.php
  30. 2 1
      tests/Composer/Test/Repository/Vcs/SvnDriverTest.php

+ 1 - 1
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);
         }
     }

+ 1 - 1
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

+ 14 - 15
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[] = '<error>[' . get_class($e) . '] ' . $e->getMessage() . '</error>';
@@ -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@') {

+ 4 - 4
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 <info>%s</info> (%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) {

+ 1 - 0
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)
         ;
 

+ 6 - 6
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('<error>Unable to locate a valid CA certificate file. You must set a valid \'cafile\' option.</error>');
@@ -614,7 +614,7 @@ class Factory
             throw $e;
         }
 
-        return $remoteFilesystem;
+        return $httpDownloader;
     }
 
     /**

+ 10 - 10
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);

+ 2 - 1
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

+ 22 - 11
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;

+ 1 - 1
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'])) {

+ 4 - 4
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');

+ 4 - 4
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);

+ 2 - 2
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();
     }

+ 2 - 2
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();
     }

+ 2 - 2
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();
     }

+ 2 - 2
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();
     }

+ 4 - 4
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;
     }
 
     /**

+ 10 - 4
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;

+ 5 - 5
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) {

+ 20 - 0
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(

+ 2 - 1
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));
 

+ 1 - 1
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)) {

+ 3 - 3
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)),

+ 1 - 1
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()
     {

+ 4 - 4
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;

+ 3 - 2
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();

+ 12 - 4
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());

+ 9 - 9
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();
     }

+ 2 - 2
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());

+ 2 - 1
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();
     }