Browse Source

Merge remote-tracking branch 'origin/master' into 2.0

Jordi Boggiano 6 years ago
parent
commit
2e0f31106a
100 changed files with 443 additions and 224 deletions
  1. 4 3
      .travis.yml
  2. 10 0
      CHANGELOG.md
  3. 5 5
      composer.lock
  4. 3 3
      doc/00-intro.md
  5. 3 3
      doc/03-cli.md
  6. 1 1
      doc/05-repositories.md
  7. 1 1
      doc/faqs/how-to-install-composer-programmatically.md
  8. 1 1
      doc/faqs/why-can't-composer-load-repositories-recursively.md
  9. 1 1
      src/Composer/Autoload/ClassLoader.php
  10. 1 1
      src/Composer/Command/BaseCommand.php
  11. 66 9
      src/Composer/Command/DiagnoseCommand.php
  12. 2 0
      src/Composer/Command/OutdatedCommand.php
  13. 1 1
      src/Composer/Command/SelfUpdateCommand.php
  14. 43 28
      src/Composer/Command/ShowCommand.php
  15. 1 1
      src/Composer/Compiler.php
  16. 4 0
      src/Composer/Console/Application.php
  17. 2 2
      src/Composer/DependencyResolver/RuleSetGenerator.php
  18. 3 3
      src/Composer/DependencyResolver/RuleWatchGraph.php
  19. 3 3
      src/Composer/Downloader/GitDownloader.php
  20. 3 3
      src/Composer/Downloader/PearPackageExtractor.php
  21. 2 1
      src/Composer/Downloader/ZipDownloader.php
  22. 1 1
      src/Composer/EventDispatcher/EventDispatcher.php
  23. 1 1
      src/Composer/Factory.php
  24. 4 4
      src/Composer/Installer.php
  25. 1 1
      src/Composer/Package/Archiver/GitExcludeFilter.php
  26. 1 1
      src/Composer/Package/Archiver/HgExcludeFilter.php
  27. 1 1
      src/Composer/Package/Archiver/ZipArchiver.php
  28. 1 0
      src/Composer/Package/Comparer/Comparer.php
  29. 4 2
      src/Composer/Repository/ArtifactRepository.php
  30. 4 4
      src/Composer/Repository/Pear/BaseChannelReader.php
  31. 3 3
      src/Composer/Repository/Pear/ChannelReader.php
  32. 9 9
      src/Composer/Repository/Pear/ChannelRest10Reader.php
  33. 5 5
      src/Composer/Repository/Pear/ChannelRest11Reader.php
  34. 8 8
      src/Composer/Repository/Pear/PackageDependencyParser.php
  35. 12 2
      src/Composer/Repository/PlatformRepository.php
  36. 0 7
      src/Composer/Repository/RepositoryInterface.php
  37. 15 3
      src/Composer/Repository/Vcs/BitbucketDriver.php
  38. 61 12
      src/Composer/Repository/VcsRepository.php
  39. 23 0
      src/Composer/Repository/VersionCacheInterface.php
  40. 1 1
      src/Composer/Util/ErrorHandler.php
  41. 2 2
      src/Composer/Util/Filesystem.php
  42. 1 1
      src/Composer/Util/NoProxyPattern.php
  43. 5 7
      src/Composer/Util/Perforce.php
  44. 2 6
      src/Composer/Util/ProcessExecutor.php
  45. 10 2
      src/Composer/Util/RemoteFilesystem.php
  46. 1 1
      src/Composer/Util/StreamContextFactory.php
  47. 1 1
      src/Composer/Util/TlsHelper.php
  48. 1 1
      tests/Composer/Test/AllFunctionalTest.php
  49. 1 1
      tests/Composer/Test/ApplicationTest.php
  50. 1 1
      tests/Composer/Test/Autoload/AutoloadGeneratorTest.php
  51. 1 1
      tests/Composer/Test/Autoload/ClassMapGeneratorTest.php
  52. 1 1
      tests/Composer/Test/CacheTest.php
  53. 1 1
      tests/Composer/Test/Command/InitCommandTest.php
  54. 1 1
      tests/Composer/Test/Command/RunScriptCommandTest.php
  55. 1 1
      tests/Composer/Test/ComposerTest.php
  56. 2 2
      tests/Composer/Test/Config/JsonConfigSourceTest.php
  57. 1 1
      tests/Composer/Test/ConfigTest.php
  58. 1 1
      tests/Composer/Test/DefaultConfigTest.php
  59. 1 2
      tests/Composer/Test/DependencyResolver/DefaultPolicyTest.php
  60. 1 1
      tests/Composer/Test/DependencyResolver/PoolTest.php
  61. 1 1
      tests/Composer/Test/DependencyResolver/RequestTest.php
  62. 1 1
      tests/Composer/Test/DependencyResolver/RuleSetTest.php
  63. 1 1
      tests/Composer/Test/DependencyResolver/RuleTest.php
  64. 1 1
      tests/Composer/Test/DependencyResolver/SolverTest.php
  65. 1 1
      tests/Composer/Test/Downloader/FileDownloaderTest.php
  66. 1 1
      tests/Composer/Test/Downloader/FossilDownloaderTest.php
  67. 1 1
      tests/Composer/Test/Downloader/GitDownloaderTest.php
  68. 1 1
      tests/Composer/Test/Downloader/HgDownloaderTest.php
  69. 1 1
      tests/Composer/Test/Downloader/PearPackageExtractorTest.php
  70. 1 1
      tests/Composer/Test/Downloader/PerforceDownloaderTest.php
  71. 1 1
      tests/Composer/Test/Downloader/XzDownloaderTest.php
  72. 5 3
      tests/Composer/Test/Downloader/ZipDownloaderTest.php
  73. 1 1
      tests/Composer/Test/EventDispatcher/EventDispatcherTest.php
  74. 40 0
      tests/Composer/Test/FactoryTest.php
  75. 1 1
      tests/Composer/Test/IO/ConsoleIOTest.php
  76. 1 1
      tests/Composer/Test/IO/NullIOTest.php
  77. 1 1
      tests/Composer/Test/Installer/LibraryInstallerTest.php
  78. 0 1
      tests/Composer/Test/InstallerTest.php
  79. 1 1
      tests/Composer/Test/Mock/FactoryMock.php
  80. 1 1
      tests/Composer/Test/Package/Archiver/ArchivableFilesFinderTest.php
  81. 1 1
      tests/Composer/Test/Package/Archiver/ArchiverTest.php
  82. 1 1
      tests/Composer/Test/Package/CompletePackageTest.php
  83. 1 1
      tests/Composer/Test/Package/RootAliasPackageTest.php
  84. 2 2
      tests/Composer/Test/Plugin/PluginInstallerTest.php
  85. 1 1
      tests/Composer/Test/Question/StrictConfirmationQuestionTest.php
  86. 1 1
      tests/Composer/Test/Repository/ArrayRepositoryTest.php
  87. 4 4
      tests/Composer/Test/Repository/ArtifactRepositoryTest.php
  88. 1 1
      tests/Composer/Test/Repository/ComposerRepositoryTest.php
  89. 1 1
      tests/Composer/Test/Repository/CompositeRepositoryTest.php
  90. 1 1
      tests/Composer/Test/Repository/FilesystemRepositoryTest.php
  91. 1 0
      tests/Composer/Test/Repository/Fixtures/artifacts/not-a-zip-with-zip-extension.zip
  92. 5 9
      tests/Composer/Test/Repository/PathRepositoryTest.php
  93. 1 1
      tests/Composer/Test/Repository/Pear/ChannelReaderTest.php
  94. 2 2
      tests/Composer/Test/Repository/Pear/ChannelRest10ReaderTest.php
  95. 2 2
      tests/Composer/Test/Repository/Pear/ChannelRest11ReaderTest.php
  96. 1 1
      tests/Composer/Test/Repository/Pear/PackageDependencyParserTest.php
  97. 1 1
      tests/Composer/Test/Repository/PearRepositoryTest.php
  98. 1 1
      tests/Composer/Test/Repository/RepositoryFactoryTest.php
  99. 1 1
      tests/Composer/Test/Repository/RepositoryManagerTest.php
  100. 1 1
      tests/Composer/Test/Repository/Vcs/FossilDriverTest.php

+ 4 - 3
.travis.yml

@@ -23,13 +23,14 @@ php:
   - 7.0
   - 7.1
   - 7.2
+  - 7.3
   - nightly
 
 matrix:
   include:
     - php: 5.3
       dist: precise
-    - php: 7.2
+    - php: 7.3
       env: deps=high
   fast_finish: true
   allow_failures:
@@ -59,7 +60,7 @@ before_script:
 
 script:
     # run test suite directories in parallel using GNU parallel
-    - ls -d tests/Composer/Test/* | parallel --gnu --keep-order 'echo "Running {} tests"; ./vendor/bin/phpunit -c tests/complete.phpunit.xml --colors=always {} || (echo -e "\e[41mFAILED\e[0m {}" && exit 1);'
+    - ls -d tests/Composer/Test/* | grep -v TestCase.php | parallel --gnu --keep-order 'echo "Running {} tests"; ./vendor/bin/phpunit -c tests/complete.phpunit.xml --colors=always {} || (echo -e "\e[41mFAILED\e[0m {}" && exit 1);'
 
 before_deploy:
     - php -d phar.readonly=0 bin/compile
@@ -72,4 +73,4 @@ deploy:
   on:
     tags: true
     repo: composer/composer
-    php:  '7.1'
+    php:  '7.2'

+ 10 - 0
CHANGELOG.md

@@ -1,3 +1,12 @@
+### [1.7.3] 2018-11-01
+
+  * Fixed handling of replace/conflict rules. This may affect dependency resolution in some edge cases.
+  * Fixed Bitbucket API support and migrated all calls to API v2 as v1 is deprecated
+  * Fixed support for lib-openssl 1.1.1 having only lowercase algorithm names
+  * Fixed escaping of URLs in Perforce and Svn drivers
+  * Fixed `show` command not respecting `--path` when a single package name was given
+  * Fixed regression in 1.7.2's handling of metapackages
+
 ### [1.7.2] 2018-08-16
 
   * Fixed reporting of authentication/rate limiting issues for GitHub API access
@@ -687,6 +696,7 @@
 
   * Initial release
 
+[1.7.3]: https://github.com/composer/composer/compare/1.7.2...1.7.3
 [1.7.2]: https://github.com/composer/composer/compare/1.7.1...1.7.2
 [1.7.1]: https://github.com/composer/composer/compare/1.7.0...1.7.1
 [1.7.0]: https://github.com/composer/composer/compare/1.7.0-RC...1.7.0

+ 5 - 5
composer.lock

@@ -8,16 +8,16 @@
     "packages": [
         {
             "name": "composer/ca-bundle",
-            "version": "1.1.2",
+            "version": "1.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/composer/ca-bundle.git",
-                "reference": "46afded9720f40b9dc63542af4e3e43a1177acb0"
+                "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/composer/ca-bundle/zipball/46afded9720f40b9dc63542af4e3e43a1177acb0",
-                "reference": "46afded9720f40b9dc63542af4e3e43a1177acb0",
+                "url": "https://api.github.com/repos/composer/ca-bundle/zipball/8afa52cd417f4ec417b4bfe86b68106538a87660",
+                "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660",
                 "shasum": ""
             },
             "require": {
@@ -60,7 +60,7 @@
                 "ssl",
                 "tls"
             ],
-            "time": "2018-08-08T08:57:40+00:00"
+            "time": "2018-10-18T06:09:13+00:00"
         },
         {
             "name": "composer/semver",

+ 3 - 3
doc/00-intro.md

@@ -40,9 +40,9 @@ To install packages from sources instead of simple zip archives, you will need
 git, svn, fossil or hg depending on how the package is version-controlled.
 
 Composer is multi-platform and we strive to make it run equally well on Windows,
-Linux and OSX.
+Linux and macOS.
 
-## Installation - Linux / Unix / OSX
+## Installation - Linux / Unix / macOS
 
 ### Downloading the Composer Executable
 
@@ -100,7 +100,7 @@ Linux distributions.
 > **Note:** If the above fails due to permissions, you may need to run it again
 > with sudo.
 
-> **Note:** On some versions of OSX the `/usr` directory does not exist by
+> **Note:** On some versions of macOS the `/usr` directory does not exist by
 > default. If you receive the error "/usr/local/bin/composer: No such file or
 > directory" then you must create the directory manually before proceeding:
 > `mkdir -p /usr/local/bin`.

+ 3 - 3
doc/03-cli.md

@@ -856,9 +856,9 @@ is a hidden, global (per-user on the machine) directory that is shared between
 all projects.
 
 By default it points to `C:\Users\<user>\AppData\Roaming\Composer` on Windows
-and `/Users/<user>/.composer` on OSX. On *nix systems that follow the [XDG Base
+and `/Users/<user>/.composer` on macOS. On \*nix systems that follow the [XDG Base
 Directory Specifications](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html),
-it points to `$XDG_CONFIG_HOME/composer`. On other *nix systems, it points to
+it points to `$XDG_CONFIG_HOME/composer`. On other \*nix systems, it points to
 `/home/<user>/.composer`.
 
 #### COMPOSER_HOME/config.json
@@ -878,7 +878,7 @@ configuration in the project's `composer.json` always wins.
 The `COMPOSER_CACHE_DIR` var allows you to change the Composer cache directory,
 which is also configurable via the [`cache-dir`](06-config.md#cache-dir) option.
 
-By default it points to `$COMPOSER_HOME/cache` on \*nix and OSX, and
+By default it points to `$COMPOSER_HOME/cache` on \*nix and macOS, and
 `C:\Users\<user>\AppData\Local\Composer` (or `%LOCALAPPDATA%/Composer`) on Windows.
 
 ### COMPOSER_PROCESS_TIMEOUT

+ 1 - 1
doc/05-repositories.md

@@ -657,7 +657,7 @@ be explicitly defined in the package's `composer.json` file. If the version
 cannot be resolved by these means, it is assumed to be `dev-master`.
 
 The local package will be symlinked if possible, in which case the output in
-the console will read `Symlinked from ../../packages/my-package`. If symlinking
+the console will read `Symlinking from ../../packages/my-package`. If symlinking
 is _not_ possible the package will be copied. In that case, the console will
 output `Mirrored from ../../packages/my-package`.
 

+ 1 - 1
doc/faqs/how-to-install-composer-programmatically.md

@@ -11,7 +11,7 @@ An alternative is to use this script which only works with UNIX utilities:
 
 EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"
 php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
-ACTUAL_SIGNATURE="$(php -r "echo hash_file('SHA384', 'composer-setup.php');")"
+ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
 
 if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
 then

+ 1 - 1
doc/faqs/why-can't-composer-load-repositories-recursively.md

@@ -15,7 +15,7 @@ associated with inline VCS repositories.
 There are three ways the dependency solver could work with custom repositories:
 
 - Fetch the repositories of root package, get all the packages from the defined
-repositories, resolve requirements. This is the current state and it works well
+repositories, then resolve requirements. This is the current state and it works well
 except for the limitation of not loading repositories recursively.
 
 - Fetch the repositories of root package, while initializing packages from the

+ 1 - 1
src/Composer/Autoload/ClassLoader.php

@@ -279,7 +279,7 @@ class ClassLoader
      */
     public function setApcuPrefix($apcuPrefix)
     {
-        $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
+        $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
     }
 
     /**

+ 1 - 1
src/Composer/Command/BaseCommand.php

@@ -33,7 +33,7 @@ use Symfony\Component\Console\Command\Command;
 abstract class BaseCommand extends Command
 {
     /**
-     * @var Composer
+     * @var Composer|null
      */
     private $composer;
 

+ 66 - 9
src/Composer/Command/DiagnoseCommand.php

@@ -119,8 +119,9 @@ EOT
             $io->write('Checking github.com rate limit: ', false);
             try {
                 $rate = $this->getGithubRateLimit('github.com');
-                $this->outputResult(true);
-                if (10 > $rate['remaining']) {
+                if (!is_array($rate)) {
+                    $this->outputResult($rate);
+                } elseif (10 > $rate['remaining']) {
                     $io->write('<warning>WARNING</warning>');
                     $io->write(sprintf(
                         '<comment>Github has a rate limit on their API. '
@@ -131,6 +132,8 @@ EOT
                         $rate['remaining'],
                         $rate['limit']
                     ));
+                } else {
+                    $this->outputResult(true);
                 }
             } catch (\Exception $e) {
                 if ($e instanceof TransportException && $e->getCode() === 401) {
@@ -207,6 +210,11 @@ EOT
 
     private function checkHttp($proto, Config $config)
     {
+        $result = $this->checkConnectivity();
+        if ($result !== true) {
+            return $result;
+        }
+
         $disableTls = false;
         $result = array();
         if ($proto === 'https' && $config->get('disable-tls') === true) {
@@ -238,6 +246,11 @@ EOT
 
     private function checkHttpProxy()
     {
+        $result = $this->checkConnectivity();
+        if ($result !== true) {
+            return $result;
+        }
+
         $protocol = extension_loaded('openssl') ? 'https' : 'http';
         try {
             $json = json_decode($this->rfs->getContents('packagist.org', $protocol . '://repo.packagist.org/packages.json', false), true);
@@ -265,6 +278,11 @@ EOT
      */
     private function checkHttpProxyFullUriRequestParam()
     {
+        $result = $this->checkConnectivity();
+        if ($result !== true) {
+            return $result;
+        }
+
         $url = 'http://repo.packagist.org/packages.json';
         try {
             $this->rfs->getContents('packagist.org', $url, false);
@@ -290,6 +308,11 @@ EOT
      */
     private function checkHttpsProxyFullUriRequestParam()
     {
+        $result = $this->checkConnectivity();
+        if ($result !== true) {
+            return $result;
+        }
+
         if (!extension_loaded('openssl')) {
             return 'You need the openssl extension installed for this check';
         }
@@ -312,6 +335,11 @@ EOT
 
     private function checkGithubOauth($domain, $token)
     {
+        $result = $this->checkConnectivity();
+        if ($result !== true) {
+            return $result;
+        }
+
         $this->getIO()->setAuthentication($domain, $token, 'x-oauth-basic');
         try {
             $url = $domain === 'github.com' ? 'https://api.'.$domain.'/' : 'https://'.$domain.'/api/v3/';
@@ -332,10 +360,15 @@ EOT
      * @param  string             $domain
      * @param  string             $token
      * @throws TransportException
-     * @return array
+     * @return array|string
      */
     private function getGithubRateLimit($domain, $token = null)
     {
+        $result = $this->checkConnectivity();
+        if ($result !== true) {
+            return $result;
+        }
+
         if ($token) {
             $this->getIO()->setAuthentication($domain, $token, 'x-oauth-basic');
         }
@@ -390,6 +423,11 @@ EOT
 
     private function checkVersion($config)
     {
+        $result = $this->checkConnectivity();
+        if ($result !== true) {
+            return $result;
+        }
+
         $versionsUtil = new Versions($config, $this->rfs);
         $latest = $versionsUtil->getLatest();
 
@@ -413,6 +451,7 @@ EOT
         }
 
         $hadError = false;
+        $hadWarning = false;
         if ($result instanceof \Exception) {
             $result = '<error>['.get_class($result).'] '.$result->getMessage().'</error>';
         }
@@ -427,16 +466,18 @@ EOT
             foreach ($result as $message) {
                 if (false !== strpos($message, '<error>')) {
                     $hadError = true;
+                } elseif (false !== strpos($message, '<warning>')) {
+                    $hadWarning = true;
                 }
             }
         }
 
         if ($hadError) {
             $io->write('<error>FAIL</error>');
-            $this->exitCode = 2;
-        } else {
+            $this->exitCode = max($this->exitCode, 2);
+        } elseif ($hadWarning) {
             $io->write('<warning>WARNING</warning>');
-            $this->exitCode = 1;
+            $this->exitCode = max($this->exitCode, 1);
         }
 
         if ($result) {
@@ -481,7 +522,7 @@ EOT
             $errors['iconv_mbstring'] = true;
         }
 
-        if (!ini_get('allow_url_fopen')) {
+        if (!filter_var(ini_get('allow_url_fopen'), FILTER_VALIDATE_BOOLEAN)) {
             $errors['allow_url_fopen'] = true;
         }
 
@@ -505,7 +546,7 @@ EOT
             $warnings['openssl_version'] = true;
         }
 
-        if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) {
+        if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN)) {
             $warnings['apc_cli'] = true;
         }
 
@@ -528,7 +569,7 @@ EOT
             }
         }
 
-        if (ini_get('xdebug.profiler_enabled')) {
+        if (filter_var(ini_get('xdebug.profiler_enabled'), FILTER_VALIDATE_BOOLEAN)) {
             $warnings['xdebug_profile'] = true;
         } elseif (extension_loaded('xdebug')) {
             $warnings['xdebug_loaded'] = true;
@@ -668,4 +709,20 @@ EOT
 
         return !$warnings && !$errors ? true : $output;
     }
+
+
+    /**
+     * Check if allow_url_fopen is ON
+     *
+     * @return bool|string
+     */
+    private function checkConnectivity()
+    {
+        if (!ini_get('allow_url_fopen')) {
+            $result = '<info>Skipped because allow_url_fopen is missing.</info>';
+            return $result;
+        }
+
+        return true;
+    }
 }

+ 2 - 0
src/Composer/Command/OutdatedCommand.php

@@ -36,6 +36,7 @@ class OutdatedCommand extends ShowCommand
                 new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code when there are outdated packages'),
                 new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates. Use with the --outdated option.'),
                 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'),
+                new InputOption('ignore', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore specified package(s). Use it with the --outdated option if you don\'t want to be informed about new versions of some packages.'),
             ))
             ->setHelp(
                 <<<EOT
@@ -77,6 +78,7 @@ EOT
             $args['--minor-only'] = true;
         }
         $args['--format'] = $input->getOption('format');
+        $args['--ignore'] = $input->getOption('ignore');
 
         $input = new ArrayInput($args);
 

+ 1 - 1
src/Composer/Command/SelfUpdateCommand.php

@@ -220,7 +220,7 @@ TAGSPUBKEY
 
             $pubkeyid = openssl_pkey_get_public($sigFile);
             $algo = defined('OPENSSL_ALGO_SHA384') ? OPENSSL_ALGO_SHA384 : 'SHA384';
-            if (!in_array('SHA384', openssl_get_md_methods())) {
+            if (!in_array('sha384', array_map('strtolower', openssl_get_md_methods()))) {
                 throw new \RuntimeException('SHA384 is not supported by your openssl extension, could not verify the phar file integrity');
             }
             $signature = json_decode($signature, true);

+ 43 - 28
src/Composer/Command/ShowCommand.php

@@ -74,6 +74,7 @@ class ShowCommand extends BaseCommand
                 new InputOption('tree', 't', InputOption::VALUE_NONE, 'List the dependencies as a tree'),
                 new InputOption('latest', 'l', InputOption::VALUE_NONE, 'Show the latest version'),
                 new InputOption('outdated', 'o', InputOption::VALUE_NONE, 'Show the latest version but only for packages that are outdated'),
+                new InputOption('ignore', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore specified package(s). Use it with the --outdated option if you don\'t want to be informed about new versions of some packages.'),
                 new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates. Use with the --outdated option.'),
                 new InputOption('direct', 'D', InputOption::VALUE_NONE, 'Shows only packages that are directly required by the root package'),
                 new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code when there are outdated packages'),
@@ -105,6 +106,8 @@ EOT
 
         if ($input->getOption('outdated')) {
             $input->setOption('latest', true);
+        } elseif ($input->getOption('ignore')) {
+            $io->writeError('<warning>You are using the option "ignore" for action other than "outdated", it will be ignored.</warning>');
         }
 
         if ($input->getOption('direct') && ($input->getOption('all') || $input->getOption('available') || $input->getOption('platform'))) {
@@ -219,6 +222,12 @@ EOT
                 if ($input->getOption('outdated') && $input->getOption('strict') && $latestPackage && $latestPackage->getFullPrettyVersion() !== $package->getFullPrettyVersion() && !$latestPackage->isAbandoned()) {
                     $exitCode = 1;
                 }
+                if ($input->getOption('path')) {
+                    $io->write($package->getName(), false);
+                    $io->write(' ' . strtok(realpath($composer->getInstallationManager()->getInstallPath($package)), "\r\n"));
+
+                    return $exitCode;
+                }
                 $this->printMeta($package, $versions, $installedRepo, $latestPackage ?: null);
                 $this->printLinks($package, 'requires');
                 $this->printLinks($package, 'devRequires', 'requires (dev)');
@@ -333,6 +342,7 @@ EOT
         $showAllTypes = $input->getOption('all');
         $showLatest = $input->getOption('latest');
         $showMinorOnly = $input->getOption('minor-only');
+        $ignoredPackages = array_map('strtolower', $input->getOption('ignore'));
         $indent = $showAllTypes ? '  ' : '';
         $latestPackages = array();
         $exitCode = 0;
@@ -372,7 +382,11 @@ EOT
                         if ($showLatest && isset($latestPackages[$package->getPrettyName()])) {
                             $latestPackage = $latestPackages[$package->getPrettyName()];
                         }
-                        if ($input->getOption('outdated') && $latestPackage && $latestPackage->getFullPrettyVersion() === $package->getFullPrettyVersion() && !$latestPackage->isAbandoned()) {
+
+                        // Determine if Composer is checking outdated dependencies and if current package should trigger non-default exit code
+                        $packageIsUpToDate = $latestPackage && $latestPackage->getFullPrettyVersion() === $package->getFullPrettyVersion() && !$latestPackage->isAbandoned();
+                        $packageIsIgnored = \in_array($package->getPrettyName(), $ignoredPackages, true);
+                        if ($input->getOption('outdated') && ($packageIsUpToDate || $packageIsIgnored)) {
                             continue;
                         } elseif ($input->getOption('outdated') || $input->getOption('strict')) {
                             $hasOutdatedPackages = true;
@@ -573,6 +587,9 @@ EOT
         $this->printLicenses($package);
         $io->write('<info>source</info>   : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getSourceType(), $package->getSourceUrl(), $package->getSourceReference()));
         $io->write('<info>dist</info>     : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getDistType(), $package->getDistUrl(), $package->getDistReference()));
+        if ($installedRepo->hasPackage($package)) {
+            $io->write('<info>path</info>     : ' . sprintf('%s', realpath($this->getComposer()->getInstallationManager()->getInstallPath($package))));
+        }
         $io->write('<info>names</info>    : ' . implode(', ', $package->getNames()));
 
         if ($latestPackage->isAbandoned()) {
@@ -716,7 +733,7 @@ EOT
     /**
      * Display the tree
      *
-     * @param $arrayTree
+     * @param array $arrayTree
      */
     protected function displayPackageTree(array $arrayTree)
     {
@@ -761,7 +778,7 @@ EOT
     /**
      * Generate the package tree
      *
-     * @param  PackageInterface|string $package
+     * @param  PackageInterface $package
      * @param  RepositoryInterface     $installedRepo
      * @param  RepositoryInterface     $distantRepos
      * @return array
@@ -771,38 +788,36 @@ EOT
         RepositoryInterface $installedRepo,
         RepositoryInterface $distantRepos
     ) {
-        if (is_object($package)) {
-            $requires = $package->getRequires();
-            ksort($requires);
-            $children = array();
-            foreach ($requires as $requireName => $require) {
-                $packagesInTree = array($package->getName(), $requireName);
-
-                $treeChildDesc = array(
-                    'name' => $requireName,
-                    'version' => $require->getPrettyConstraint(),
-                );
+        $requires = $package->getRequires();
+        ksort($requires);
+        $children = array();
+        foreach ($requires as $requireName => $require) {
+            $packagesInTree = array($package->getName(), $requireName);
 
-                $deepChildren = $this->addTree($requireName, $require, $installedRepo, $distantRepos, $packagesInTree);
+            $treeChildDesc = array(
+                'name' => $requireName,
+                'version' => $require->getPrettyConstraint(),
+            );
 
-                if ($deepChildren) {
-                    $treeChildDesc['requires'] = $deepChildren;
-                }
+            $deepChildren = $this->addTree($requireName, $require, $installedRepo, $distantRepos, $packagesInTree);
 
-                $children[] = $treeChildDesc;
+            if ($deepChildren) {
+                $treeChildDesc['requires'] = $deepChildren;
             }
-            $tree = array(
-                'name' => $package->getPrettyName(),
-                'version' => $package->getPrettyVersion(),
-                'description' => $package->getDescription(),
-            );
 
-            if ($children) {
-                $tree['requires'] = $children;
-            }
+            $children[] = $treeChildDesc;
+        }
+        $tree = array(
+            'name' => $package->getPrettyName(),
+            'version' => $package->getPrettyVersion(),
+            'description' => $package->getDescription(),
+        );
 
-            return $tree;
+        if ($children) {
+            $tree['requires'] = $children;
         }
+
+        return $tree;
     }
 
     /**

+ 1 - 1
src/Composer/Compiler.php

@@ -255,7 +255,7 @@ class Compiler
  */
 
 // Avoid APC causing random fatal errors per https://github.com/composer/composer/issues/264
-if (extension_loaded('apc') && ini_get('apc.enable_cli') && ini_get('apc.cache_by_default')) {
+if (extension_loaded('apc') && filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN) && filter_var(ini_get('apc.cache_by_default'), FILTER_VALIDATE_BOOLEAN)) {
     if (version_compare(phpversion('apc'), '3.0.12', '>=')) {
         ini_set('apc.cache_by_default', 0);
     } else {

+ 4 - 0
src/Composer/Console/Application.php

@@ -16,6 +16,7 @@ use Composer\IO\NullIO;
 use Composer\Util\Platform;
 use Composer\Util\Silencer;
 use Symfony\Component\Console\Application as BaseApplication;
+use Symfony\Component\Console\Exception\CommandNotFoundException;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
@@ -125,6 +126,9 @@ class Application extends BaseApplication
         if ($name = $this->getCommandName($input)) {
             try {
                 $commandName = $this->find($name)->getName();
+            } catch (CommandNotFoundException $e) {
+              // we'll check command validity again later after plugins are loaded
+              $commandName = false;
             } catch (\InvalidArgumentException $e) {
             }
         }

+ 2 - 2
src/Composer/DependencyResolver/RuleSetGenerator.php

@@ -49,7 +49,7 @@ class RuleSetGenerator
      *                                      reason for generating this rule
      * @param  mixed            $reasonData Any data, e.g. the requirement name,
      *                                      that goes with the reason
-     * @return Rule             The generated rule or null if tautological
+     * @return Rule|null             The generated rule or null if tautological
      */
     protected function createRequireRule(PackageInterface $package, array $providers, $reason, $reasonData = null)
     {
@@ -116,7 +116,7 @@ class RuleSetGenerator
      *                                      reason for generating this rule
      * @param  mixed            $reasonData Any data, e.g. the package name, that
      *                                      goes with the reason
-     * @return Rule             The generated rule
+     * @return Rule|null             The generated rule
      */
     protected function createRule2Literals(PackageInterface $issuer, PackageInterface $provider, $reason, $reasonData = null)
     {

+ 3 - 3
src/Composer/DependencyResolver/RuleWatchGraph.php

@@ -127,9 +127,9 @@ class RuleWatchGraph
      *
      * The rule node's watched literals are updated accordingly.
      *
-     * @param $fromLiteral mixed A literal the node used to watch
-     * @param $toLiteral mixed A literal the node should watch now
-     * @param $node mixed The rule node to be moved
+     * @param int           $fromLiteral A literal the node used to watch
+     * @param int           $toLiteral A literal the node should watch now
+     * @param RuleWatchNode $node The rule node to be moved
      */
     protected function moveWatch($fromLiteral, $toLiteral, $node)
     {

+ 3 - 3
src/Composer/Downloader/GitDownloader.php

@@ -433,7 +433,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
     }
 
     /**
-     * @param $path
+     * @param string $path
      * @throws \RuntimeException
      */
     protected function discardChanges($path)
@@ -447,7 +447,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
     }
 
     /**
-     * @param $path
+     * @param string $path
      * @throws \RuntimeException
      */
     protected function stashChanges($path)
@@ -461,7 +461,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
     }
 
     /**
-     * @param $path
+     * @param string $path
      * @throws \RuntimeException
      */
     protected function viewDiff($path)

+ 3 - 3
src/Composer/Downloader/PearPackageExtractor.php

@@ -73,8 +73,8 @@ class PearPackageExtractor
      * Perform copy actions on files
      *
      * @param array $files array of copy actions ('from', 'to') with relative paths
-     * @param $source string path to source dir.
-     * @param $target string path to destination dir
+     * @param string $source path to source dir.
+     * @param string $target path to destination dir
      * @param array $roles array [role => roleRoot] relative root for files having that role
      * @param array $vars  list of values can be used for replacement tasks
      */
@@ -135,7 +135,7 @@ class PearPackageExtractor
      */
     private function buildCopyActions($source, array $roles, $vars)
     {
-        /** @var $package \SimpleXmlElement */
+        /** @var \SimpleXmlElement $package */
         $package = simplexml_load_string(file_get_contents($this->combine($source, 'package.xml')));
         if (false === $package) {
             throw new \RuntimeException('Package definition file is not valid.');

+ 2 - 1
src/Composer/Downloader/ZipDownloader.php

@@ -69,7 +69,8 @@ class ZipDownloader extends ArchiveDownloader
 
             if (!self::$isWindows && !self::$hasSystemUnzip) {
                 $this->io->writeError("<warning>As there is no 'unzip' command installed zip files are being unpacked using the PHP zip extension.</warning>");
-                $this->io->writeError("<warning>This may cause invalid reports of corrupted archives. Installing 'unzip' may remediate them.</warning>");
+                $this->io->writeError("<warning>This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.</warning>");
+                $this->io->writeError("<warning>Installing 'unzip' may remediate them.</warning>");
             }
         }
 

+ 1 - 1
src/Composer/EventDispatcher/EventDispatcher.php

@@ -264,7 +264,7 @@ class EventDispatcher
         $finder = new PhpExecutableFinder();
         $phpPath = $finder->find();
         if (!$phpPath) {
-            throw new \RuntimeException('Failed to locate PHP binary to execute '.$scriptName);
+            throw new \RuntimeException('Failed to locate PHP binary to execute '.$phpPath);
         }
 
         $allowUrlFOpenFlag = ' -d allow_url_fopen=' . ProcessExecutor::escape(ini_get('allow_url_fopen'));

+ 1 - 1
src/Composer/Factory.php

@@ -588,7 +588,7 @@ class Factory
         $disableTls = false;
         if ($config && $config->get('disable-tls') === true) {
             if (!$warned) {
-                $io->write('<warning>You are running Composer with SSL/TLS protection disabled.</warning>');
+                $io->writeError('<warning>You are running Composer with SSL/TLS protection disabled.</warning>');
             }
             $warned = true;
             $disableTls = true;

+ 4 - 4
src/Composer/Installer.php

@@ -614,14 +614,14 @@ class Installer
                 }
             }
 
+            if ($this->executeOperations || $this->writeLock) {
+                $localRepo->write();
+            }
+
             $event = 'Composer\Installer\PackageEvents::POST_PACKAGE_'.strtoupper($jobType);
             if (defined($event) && $this->runScripts) {
                 $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $policy, $repositorySet, $installedRepo, $request, $operations, $operation);
             }
-
-            if ($this->executeOperations || $this->writeLock) {
-                $localRepo->write();
-            }
         }
 
         if ($this->executeOperations) {

+ 1 - 1
src/Composer/Package/Archiver/GitExcludeFilter.php

@@ -64,7 +64,7 @@ class GitExcludeFilter extends BaseExcludeFilter
      *
      * @param string $line A line from .gitattributes
      *
-     * @return array An exclude pattern for filter()
+     * @return array|null An exclude pattern for filter()
      */
     public function parseGitAttributesLine($line)
     {

+ 1 - 1
src/Composer/Package/Archiver/HgExcludeFilter.php

@@ -54,7 +54,7 @@ class HgExcludeFilter extends BaseExcludeFilter
      *
      * @param string $line A line from .hgignore
      *
-     * @return array An exclude pattern for filter()
+     * @return array|null An exclude pattern for filter()
      */
     public function parseHgIgnoreLine($line)
     {

+ 1 - 1
src/Composer/Package/Archiver/ZipArchiver.php

@@ -37,7 +37,7 @@ class ZipArchiver implements ArchiverInterface
         if ($res === true) {
             $files = new ArchivableFilesFinder($sources, $excludes, $ignoreFilters);
             foreach ($files as $file) {
-                /** @var $file \SplFileInfo */
+                /** @var \SplFileInfo $file */
                 $filepath = strtr($file->getPath()."/".$file->getFilename(), '\\', '/');
                 $localname = str_replace($sources.'/', '', $filepath);
                 if ($file->isDir()) {

+ 1 - 0
src/Composer/Package/Comparer/Comparer.php

@@ -70,6 +70,7 @@ class Comparer
         if (!is_array($source)) {
             return;
         }
+        chdir($currentDirectory);
         chdir($this->update);
         $destination = $this->doTree('.', $destination);
         if (!is_array($destination)) {

+ 4 - 2
src/Composer/Repository/ArtifactRepository.php

@@ -84,7 +84,7 @@ class ArtifactRepository extends ArrayRepository implements ConfigurableReposito
      * Find a file by name, returning the one that has the shortest path.
      *
      * @param \ZipArchive $zip
-     * @param $filename
+     * @param string $filename
      * @return bool|int
      */
     private function locateFile(\ZipArchive $zip, $filename)
@@ -126,7 +126,9 @@ class ArtifactRepository extends ArrayRepository implements ConfigurableReposito
     private function getComposerInformation(\SplFileInfo $file)
     {
         $zip = new \ZipArchive();
-        $zip->open($file->getPathname());
+        if ($zip->open($file->getPathname()) !== true) {
+            return false;
+        }
 
         if (0 == $zip->numFiles) {
             $zip->close();

+ 4 - 4
src/Composer/Repository/Pear/BaseChannelReader.php

@@ -44,8 +44,8 @@ abstract class BaseChannelReader
     /**
      * Read content from remote filesystem.
      *
-     * @param $origin string server
-     * @param $path   string relative path to content
+     * @param string $origin server
+     * @param string $path   relative path to content
      * @throws \UnexpectedValueException
      * @return \SimpleXMLElement
      */
@@ -63,8 +63,8 @@ abstract class BaseChannelReader
     /**
      * Read xml content from remote filesystem
      *
-     * @param $origin string server
-     * @param $path   string relative path to content
+     * @param string $origin server
+     * @param string $path   relative path to content
      * @throws \UnexpectedValueException
      * @return \SimpleXMLElement
      */

+ 3 - 3
src/Composer/Repository/Pear/ChannelReader.php

@@ -44,7 +44,7 @@ class ChannelReader extends BaseChannelReader
     /**
      * Reads PEAR channel through REST interface and builds list of packages
      *
-     * @param $url string PEAR Channel url
+     * @param string $url PEAR Channel url
      * @throws \UnexpectedValueException
      * @return ChannelInfo
      */
@@ -70,8 +70,8 @@ class ChannelReader extends BaseChannelReader
     /**
      * Reads channel supported REST interfaces and selects one of them
      *
-     * @param $channelXml \SimpleXMLElement
-     * @param $supportedVersions string[] supported PEAR REST protocols
+     * @param \SimpleXMLElement $channelXml
+     * @param string[] $supportedVersions supported PEAR REST protocols
      * @return array|null hash with selected version and baseUrl
      */
     private function selectRestVersion($channelXml, $supportedVersions)

+ 9 - 9
src/Composer/Repository/Pear/ChannelRest10Reader.php

@@ -39,7 +39,7 @@ class ChannelRest10Reader extends BaseChannelReader
     /**
      * Reads package descriptions using PEAR Rest 1.0 interface
      *
-     * @param $baseUrl  string base Url interface
+     * @param string $baseUrl base Url interface
      *
      * @return PackageInfo[]
      */
@@ -52,7 +52,7 @@ class ChannelRest10Reader extends BaseChannelReader
      * Read list of packages from
      *  {baseUrl}/p/packages.xml
      *
-     * @param $baseUrl string
+     * @param string $baseUrl
      * @return PackageInfo[]
      */
     private function readPackages($baseUrl)
@@ -75,8 +75,8 @@ class ChannelRest10Reader extends BaseChannelReader
      * Read package info from
      *  {baseUrl}/p/{package}/info.xml
      *
-     * @param $baseUrl      string
-     * @param $packageName  string
+     * @param string $baseUrl
+     * @param string $packageName
      * @return PackageInfo
      */
     private function readPackage($baseUrl, $packageName)
@@ -105,8 +105,8 @@ class ChannelRest10Reader extends BaseChannelReader
      * Read package releases from
      *  {baseUrl}/p/{package}/allreleases.xml
      *
-     * @param $baseUrl      string
-     * @param $packageName  string
+     * @param string $baseUrl
+     * @param string $packageName
      * @throws \Composer\Downloader\TransportException|\Exception
      * @return ReleaseInfo[]                                      hash array with keys as version numbers
      */
@@ -146,9 +146,9 @@ class ChannelRest10Reader extends BaseChannelReader
      * Read package dependencies from
      *  {baseUrl}/p/{package}/deps.{version}.txt
      *
-     * @param $baseUrl      string
-     * @param $packageName  string
-     * @param $version      string
+     * @param string $baseUrl
+     * @param string $packageName
+     * @param string $version
      * @return DependencyInfo[]
      */
     private function readPackageReleaseDependencies($baseUrl, $packageName, $version)

+ 5 - 5
src/Composer/Repository/Pear/ChannelRest11Reader.php

@@ -35,7 +35,7 @@ class ChannelRest11Reader extends BaseChannelReader
     /**
      * Reads package descriptions using PEAR Rest 1.1 interface
      *
-     * @param $baseUrl  string base Url interface
+     * @param string $baseUrl base Url interface
      *
      * @return PackageInfo[]
      */
@@ -48,7 +48,7 @@ class ChannelRest11Reader extends BaseChannelReader
      * Read list of channel categories from
      *  {baseUrl}/c/categories.xml
      *
-     * @param $baseUrl string
+     * @param string $baseUrl
      * @return PackageInfo[]
      */
     private function readChannelPackages($baseUrl)
@@ -70,8 +70,8 @@ class ChannelRest11Reader extends BaseChannelReader
      * Read packages from
      *  {baseUrl}/c/{category}/packagesinfo.xml
      *
-     * @param $baseUrl      string
-     * @param $categoryName string
+     * @param string $baseUrl
+     * @param string $categoryName
      * @return PackageInfo[]
      */
     private function readCategoryPackages($baseUrl, $categoryName)
@@ -92,7 +92,7 @@ class ChannelRest11Reader extends BaseChannelReader
     /**
      * Parses package node.
      *
-     * @param $packageInfo  \SimpleXMLElement   xml element describing package
+     * @param \SimpleXMLElement $packageInfo  xml element describing package
      * @return PackageInfo
      */
     private function parsePackage($packageInfo)

+ 8 - 8
src/Composer/Repository/Pear/PackageDependencyParser.php

@@ -22,7 +22,7 @@ class PackageDependencyParser
     /**
      * Builds dependency information. It detects used package.xml format.
      *
-     * @param $depArray array
+     * @param array $depArray
      * @return DependencyInfo
      */
     public function buildDependencyInfo($depArray)
@@ -46,7 +46,7 @@ class PackageDependencyParser
      * { type="php|os|sapi|ext|pkg" rel="has|not|eq|ge|gt|le|lt" optional="yes"
      *   channel="channelName" name="extName|packageName" }
      *
-     * @param $depArray array Dependency data in package.xml 1.0 format
+     * @param array $depArray Dependency data in package.xml 1.0 format
      * @return DependencyConstraint[]
      */
     private function buildDependency10Info($depArray)
@@ -115,7 +115,7 @@ class PackageDependencyParser
     /**
      * Builds dependency information from package.xml 2.0 format
      *
-     * @param $depArray array Dependency data in package.xml 1.0 format
+     * @param array $depArray Dependency data in package.xml 1.0 format
      * @return DependencyInfo
      */
     private function buildDependency20Info($depArray)
@@ -187,8 +187,8 @@ class PackageDependencyParser
     /**
      * Builds dependency constraint of 'extension' type
      *
-     * @param $depItem array dependency constraint or array of dependency constraints
-     * @param $depType string target type of building constraint.
+     * @param array $depItem dependency constraint or array of dependency constraints
+     * @param string $depType target type of building constraint.
      * @return DependencyConstraint[]
      */
     private function buildDepExtensionConstraints($depItem, $depType)
@@ -217,8 +217,8 @@ class PackageDependencyParser
     /**
      * Builds dependency constraint of 'package' type
      *
-     * @param $depItem array dependency constraint or array of dependency constraints
-     * @param $depType string target type of building constraint.
+     * @param array $depItem dependency constraint or array of dependency constraints
+     * @param string $depType target type of building constraint.
      * @return DependencyConstraint[]
      */
     private function buildDepPackageConstraints($depItem, $depType)
@@ -287,7 +287,7 @@ class PackageDependencyParser
     /**
      * Softened version parser
      *
-     * @param $version
+     * @param string $version
      * @return null|string
      */
     private function parseVersion($version)

+ 12 - 2
src/Composer/Repository/PlatformRepository.php

@@ -236,7 +236,12 @@ class PlatformRepository extends ArrayRepository
         // Skip if overridden
         if (isset($this->overrides[$package->getName()])) {
             $overrider = $this->findPackage($package->getName(), '*');
-            $overrider->setDescription($overrider->getDescription().' (actual: '.$package->getPrettyVersion().')');
+            if ($package->getVersion() === $overrider->getVersion()) {
+                $actualText = 'same as actual';
+            } else {
+                $actualText = 'actual: '.$package->getPrettyVersion();
+            }
+            $overrider->setDescription($overrider->getDescription().' ('.$actualText.')');
 
             return;
         }
@@ -244,7 +249,12 @@ class PlatformRepository extends ArrayRepository
         // Skip if PHP is overridden and we are adding a php-* package
         if (isset($this->overrides['php']) && 0 === strpos($package->getName(), 'php-')) {
             $overrider = $this->addOverriddenPackage($this->overrides['php'], $package->getPrettyName());
-            $overrider->setDescription($overrider->getDescription().' (actual: '.$package->getPrettyVersion().')');
+            if ($package->getVersion() === $overrider->getVersion()) {
+                $actualText = 'same as actual';
+            } else {
+                $actualText = 'actual: '.$package->getPrettyVersion();
+            }
+            $overrider->setDescription($overrider->getDescription().' ('.$actualText.')');
 
             return;
         }

+ 0 - 7
src/Composer/Repository/RepositoryInterface.php

@@ -81,11 +81,4 @@ interface RepositoryInterface extends \Countable
      * @return array[] an array of array('name' => '...', 'description' => '...')
      */
     public function search($query, $mode = 0);
-
-    /**
-     * Removes a package from the registered packages list.
-     *
-     * @param PackageInterface $package
-     */
-    public function removePackage(PackageInterface $package);
 }

+ 15 - 3
src/Composer/Repository/Vcs/BitbucketDriver.php

@@ -189,8 +189,15 @@ abstract class BitbucketDriver extends VcsDriver
             return $this->fallbackDriver->getFileContent($file, $identifier);
         }
 
+        if (strpos($identifier, '/') !== false) {
+            $branches = $this->getBranches();
+            if (isset($branches[$identifier])) {
+                $identifier = $branches[$identifier];
+            }
+        }
+
         $resource = sprintf(
-            'https://api.bitbucket.org/1.0/repositories/%s/%s/raw/%s/%s',
+            'https://api.bitbucket.org/2.0/repositories/%s/%s/src/%s/%s',
             $this->owner,
             $this->repository,
             $identifier,
@@ -421,11 +428,16 @@ abstract class BitbucketDriver extends VcsDriver
     protected function getMainBranchData()
     {
         $resource = sprintf(
-            'https://api.bitbucket.org/1.0/repositories/%s/%s/main-branch',
+            'https://api.bitbucket.org/2.0/repositories/%s/%s?fields=mainbranch',
             $this->owner,
             $this->repository
         );
 
-        return JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource);
+        $data = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource);
+        if (isset($data['mainbranch'])) {
+            return $data['mainbranch'];
+        }
+
+        return null;
     }
 }

+ 61 - 12
src/Composer/Repository/VcsRepository.php

@@ -41,8 +41,10 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt
     private $drivers;
     /** @var VcsDriverInterface */
     private $driver;
+    /** @var VersionCacheInterface */
+    private $versionCache;
 
-    public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher = null, array $drivers = null)
+    public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher = null, array $drivers = null, VersionCacheInterface $versionCache = null)
     {
         parent::__construct();
         $this->drivers = $drivers ?: array(
@@ -64,6 +66,7 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt
         $this->verbose = $io->isVeryVerbose();
         $this->config = $config;
         $this->repoConfig = $repoConfig;
+        $this->versionCache = $versionCache;
     }
 
     public function getRepoConfig()
@@ -152,6 +155,13 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt
             // strip the release- prefix from tags if present
             $tag = str_replace('release-', '', $tag);
 
+            $cachedPackage = $this->getCachedPackageVersion($tag, $identifier, $verbose);
+            if ($cachedPackage) {
+                $this->addPackage($cachedPackage);
+
+                continue;
+            }
+
             if (!$parsedTag = $this->validateTag($tag)) {
                 if ($verbose) {
                     $this->io->writeError('<warning>Skipped tag '.$tag.', invalid tag name</warning>');
@@ -188,7 +198,8 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt
                     continue;
                 }
 
-                if ($existingPackage = $this->findPackage($data['name'], $data['version_normalized'])) {
+                $tagPackageName = isset($data['name']) ? $data['name'] : $this->packageName;
+                if ($existingPackage = $this->findPackage($tagPackageName, $data['version_normalized'])) {
                     if ($verbose) {
                         $this->io->writeError('<warning>Skipped tag '.$tag.', it conflicts with an another tag ('.$existingPackage->getPrettyVersion().') as both resolve to '.$data['version_normalized'].' internally</warning>');
                     }
@@ -235,6 +246,21 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt
                 continue;
             }
 
+            // make sure branch packages have a dev flag
+            if ('dev-' === substr($parsedBranch, 0, 4) || '9999999-dev' === $parsedBranch) {
+                $version = 'dev-' . $branch;
+            } else {
+                $prefix = substr($branch, 0, 1) === 'v' ? 'v' : '';
+                $version = $prefix . preg_replace('{(\.9{7})+}', '.x', $parsedBranch);
+            }
+
+            $cachedPackage = $this->getCachedPackageVersion($version, $identifier, $verbose);
+            if ($cachedPackage) {
+                $this->addPackage($cachedPackage);
+
+                continue;
+            }
+
             try {
                 if (!$data = $driver->getComposerInformation($identifier)) {
                     if ($verbose) {
@@ -244,17 +270,9 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt
                 }
 
                 // branches are always auto-versioned, read value from branch name
-                $data['version'] = $branch;
+                $data['version'] = $version;
                 $data['version_normalized'] = $parsedBranch;
 
-                // make sure branch packages have a dev flag
-                if ('dev-' === substr($parsedBranch, 0, 4) || '9999999-dev' === $parsedBranch) {
-                    $data['version'] = 'dev-' . $data['version'];
-                } else {
-                    $prefix = substr($branch, 0, 1) === 'v' ? 'v' : '';
-                    $data['version'] = $prefix . preg_replace('{(\.9{7})+}', '.x', $parsedBranch);
-                }
-
                 if ($verbose) {
                     $this->io->writeError('Importing branch '.$branch.' ('.$data['version'].')');
                 }
@@ -294,7 +312,8 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt
     protected function preProcess(VcsDriverInterface $driver, array $data, $identifier)
     {
         // keep the name of the main identifier for all packages
-        $data['name'] = $this->packageName ?: $data['name'];
+        $dataPackageName = isset($data['name']) ? $data['name'] : null;
+        $data['name'] = $this->packageName ?: $dataPackageName;
 
         if (!isset($data['dist'])) {
             $data['dist'] = $driver->getDist($identifier);
@@ -325,4 +344,34 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt
 
         return false;
     }
+
+    private function getCachedPackageVersion($version, $identifier, $verbose)
+    {
+        if (!$this->versionCache) {
+            return;
+        }
+
+        $cachedPackage = $this->versionCache->getVersionPackage($version, $identifier);
+        if ($cachedPackage) {
+            $msg = 'Found cached composer.json of <info>' . ($this->packageName ?: $this->url) . '</info> (<comment>' . $version . '</comment>)';
+            if ($verbose) {
+                $this->io->writeError($msg);
+            } else {
+                $this->io->overwriteError($msg, false);
+            }
+
+            if ($existingPackage = $this->findPackage($cachedPackage['name'], $cachedPackage['version_normalized'])) {
+                if ($verbose) {
+                    $this->io->writeError('<warning>Skipped cached version '.$version.', it conflicts with an another tag ('.$existingPackage->getPrettyVersion().') as both resolve to '.$cachedPackage['version_normalized'].' internally</warning>');
+                }
+                $cachedPackage = null;
+            }
+        }
+
+        if ($cachedPackage) {
+            return $this->loader->load($cachedPackage);
+        }
+
+        return null;
+    }
 }

+ 23 - 0
src/Composer/Repository/VersionCacheInterface.php

@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Repository;
+
+interface VersionCacheInterface
+{
+    /**
+     * @param string $version
+     * @param string $identifier
+     * @return array Package version data
+     */
+    public function getVersionPackage($version, $identifier);
+}

+ 1 - 1
src/Composer/Util/ErrorHandler.php

@@ -41,7 +41,7 @@ class ErrorHandler
             return;
         }
 
-        if (ini_get('xdebug.scream')) {
+        if (filter_var(ini_get('xdebug.scream'), FILTER_VALIDATE_BOOLEAN)) {
             $message .= "\n\nWarning: You have xdebug.scream enabled, the warning above may be".
             "\na legitimately suppressed error that you were not supposed to see.";
         }

+ 2 - 2
src/Composer/Util/Filesystem.php

@@ -264,8 +264,8 @@ class Filesystem
     /**
      * Copies a file or directory from $source to $target.
      *
-     * @param $source
-     * @param $target
+     * @param string $source
+     * @param string $target
      * @return bool
      */
     public function copy($source, $target)

+ 1 - 1
src/Composer/Util/NoProxyPattern.php

@@ -35,7 +35,7 @@ class NoProxyPattern
      *
      * @param string $url
      *
-     * @return true if the URL matches one of the rules.
+     * @return bool true if the URL matches one of the rules.
      */
     public function test($url)
     {

+ 5 - 7
src/Composer/Util/Perforce.php

@@ -485,8 +485,7 @@ class Perforce
         $resArray = explode(PHP_EOL, $result);
         $tags = array();
         foreach ($resArray as $line) {
-            $index = strpos($line, 'Label');
-            if (!($index === false)) {
+            if (strpos($line, 'Label') !== false) {
                 $fields = explode(' ', $line);
                 $tags[$fields[1]] = $this->getStream() . '@' . $fields[1];
             }
@@ -502,8 +501,7 @@ class Perforce
         $result = $this->commandResult;
         $resArray = explode(PHP_EOL, $result);
         foreach ($resArray as $line) {
-            $index = strpos($line, 'Depot');
-            if (!($index === false)) {
+            if (strpos($line, 'Depot') !== false) {
                 $fields = explode(' ', $line);
                 if (strcmp($this->p4Depot, $fields[1]) === 0) {
                     $this->p4DepotType = $fields[3];
@@ -517,7 +515,7 @@ class Perforce
     }
 
     /**
-     * @param $reference
+     * @param string $reference
      * @return mixed|null
      */
     protected function getChangeList($reference)
@@ -539,8 +537,8 @@ class Perforce
     }
 
     /**
-     * @param $fromReference
-     * @param $toReference
+     * @param string $fromReference
+     * @param string $toReference
      * @return mixed|null
      */
     public function getCommitLogs($fromReference, $toReference)

+ 2 - 6
src/Composer/Util/ProcessExecutor.php

@@ -60,7 +60,7 @@ class ProcessExecutor
             $cwd = realpath(getcwd());
         }
 
-        $this->captureOutput = count(func_get_args()) > 1;
+        $this->captureOutput = func_num_args() > 1;
         $this->errorOutput = null;
         $process = new Process($command, $cwd, null, null, static::getTimeout());
 
@@ -131,15 +131,11 @@ class ProcessExecutor
      */
     public static function escape($argument)
     {
-        if (method_exists('Symfony\Component\Process\ProcessUtils', 'escapeArgument')) {
-            return ProcessUtils::escapeArgument($argument);
-        }
-
         return self::escapeArgument($argument);
     }
 
     /**
-     * Copy of ProcessUtils::escapeArgument() that is removed in Symfony 4.
+     * Copy of ProcessUtils::escapeArgument() that is deprecated in Symfony 3.3 and removed in Symfony 4.
      *
      * @param string $argument
      *

+ 10 - 2
src/Composer/Util/RemoteFilesystem.php

@@ -114,13 +114,18 @@ class RemoteFilesystem
     /**
      * Merges new options
      *
-     * @return array $options
+     * @param array $options
      */
     public function setOptions(array $options)
     {
         $this->options = array_replace_recursive($this->options, $options);
     }
 
+    /**
+     * Check is disable TLS.
+     *
+     * @return bool
+     */
     public function isTlsDisabled()
     {
         return $this->disableTls === true;
@@ -364,7 +369,7 @@ class RemoteFilesystem
             }
             $result = false;
         }
-        if ($errorMessage && !ini_get('allow_url_fopen')) {
+        if ($errorMessage && !filter_var(ini_get('allow_url_fopen'), FILTER_VALIDATE_BOOLEAN)) {
             $errorMessage = 'allow_url_fopen must be enabled in php.ini ('.$errorMessage.')';
         }
         restore_error_handler();
@@ -385,15 +390,18 @@ class RemoteFilesystem
 
         $statusCode = null;
         $contentType = null;
+        $locationHeader = null;
         if (!empty($http_response_header[0])) {
             $statusCode = $this->findStatusCode($http_response_header);
             $contentType = $this->findHeaderValue($http_response_header, 'content-type');
+            $locationHeader = $this->findHeaderValue($http_response_header, 'location');
         }
 
         // check for bitbucket login page asking to authenticate
         if ($originUrl === 'bitbucket.org'
             && !$this->isPublicBitBucketDownload($fileUrl)
             && substr($fileUrl, -4) === '.zip'
+            && (!$locationHeader || substr($locationHeader, -4) !== '.zip')
             && $contentType && preg_match('{^text/html\b}i', $contentType)
         ) {
             $result = false;

+ 1 - 1
src/Composer/Util/StreamContextFactory.php

@@ -160,7 +160,7 @@ final class StreamContextFactory
      * This method fixes the array by moving the content-type header to the end
      *
      * @link https://bugs.php.net/bug.php?id=61548
-     * @param $header
+     * @param string|array $header
      * @return array
      */
     private static function fixHttpHeaderField($header)

+ 1 - 1
src/Composer/Util/TlsHelper.php

@@ -164,7 +164,7 @@ final class TlsHelper
      *
      * @param string $certName CN/SAN
      *
-     * @return callable|null
+     * @return callable|void
      */
     private static function certNameMatcher($certName)
     {

+ 1 - 1
tests/Composer/Test/AllFunctionalTest.php

@@ -12,7 +12,7 @@
 
 namespace Composer\Test;
 
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 use Symfony\Component\Finder\Finder;
 use Symfony\Component\Process\Process;

+ 1 - 1
tests/Composer/Test/ApplicationTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test;
 
 use Composer\Console\Application;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Symfony\Component\Console\Output\OutputInterface;
 
 class ApplicationTest extends TestCase

+ 1 - 1
tests/Composer/Test/Autoload/AutoloadGeneratorTest.php

@@ -17,7 +17,7 @@ use Composer\Package\Link;
 use Composer\Util\Filesystem;
 use Composer\Package\AliasPackage;
 use Composer\Package\Package;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Script\ScriptEvents;
 use Composer\Repository\InstalledRepositoryInterface;
 use Composer\Installer\InstallationManager;

+ 1 - 1
tests/Composer/Test/Autoload/ClassMapGeneratorTest.php

@@ -19,7 +19,7 @@
 namespace Composer\Test\Autoload;
 
 use Composer\Autoload\ClassMapGenerator;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Symfony\Component\Finder\Finder;
 use Composer\Util\Filesystem;
 

+ 1 - 1
tests/Composer/Test/CacheTest.php

@@ -12,7 +12,7 @@
 
 namespace Composer\Test;
 
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 
 class CacheTest extends TestCase

+ 1 - 1
tests/Composer/Test/Command/InitCommandTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\Command;
 
 use Composer\Command\InitCommand;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class InitCommandTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/Command/RunScriptCommandTest.php

@@ -15,7 +15,7 @@ namespace Composer\Test\Command;
 use Composer\Composer;
 use Composer\Config;
 use Composer\Script\Event as ScriptEvent;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class RunScriptCommandTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/ComposerTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test;
 
 use Composer\Composer;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class ComposerTest extends TestCase
 {

+ 2 - 2
tests/Composer/Test/Config/JsonConfigSourceTest.php

@@ -10,11 +10,11 @@
  * file that was distributed with this source code.
  */
 
-namespace Composer\Test\Json;
+namespace Composer\Test\Config;
 
 use Composer\Config\JsonConfigSource;
 use Composer\Json\JsonFile;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 
 class JsonConfigSourceTest extends TestCase

+ 1 - 1
tests/Composer/Test/ConfigTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test;
 
 use Composer\Config;
-use PHPUnit\Framework\TestCase;
+use Composer\Test\TestCase;
 
 class ConfigTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/DefaultConfigTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test;
 
 use Composer\Config;
-use PHPUnit\Framework\TestCase;
+use Composer\Test\TestCase;
 
 class DefaultConfigTest extends TestCase
 {

+ 1 - 2
tests/Composer/Test/DependencyResolver/DefaultPolicyTest.php

@@ -20,8 +20,7 @@ use Composer\Package\Link;
 use Composer\Package\AliasPackage;
 use Composer\Repository\RepositorySet;
 use Composer\Semver\Constraint\Constraint;
-use Composer\TestCase;
-use http\Env\Request;
+use Composer\Test\TestCase;
 
 class DefaultPolicyTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/DependencyResolver/PoolTest.php

@@ -15,7 +15,7 @@ namespace Composer\Test\DependencyResolver;
 use Composer\DependencyResolver\Pool;
 use Composer\Repository\ArrayRepository;
 use Composer\Package\BasePackage;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class PoolTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/DependencyResolver/RequestTest.php

@@ -14,7 +14,7 @@ namespace Composer\Test\DependencyResolver;
 
 use Composer\DependencyResolver\Request;
 use Composer\Repository\ArrayRepository;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class RequestTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/DependencyResolver/RuleSetTest.php

@@ -18,7 +18,7 @@ use Composer\DependencyResolver\RuleSet;
 use Composer\DependencyResolver\Pool;
 use Composer\Package\BasePackage;
 use Composer\Repository\ArrayRepository;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class RuleSetTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/DependencyResolver/RuleTest.php

@@ -18,7 +18,7 @@ use Composer\DependencyResolver\RuleSet;
 use Composer\DependencyResolver\Pool;
 use Composer\Package\BasePackage;
 use Composer\Repository\ArrayRepository;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class RuleTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/DependencyResolver/SolverTest.php

@@ -22,7 +22,7 @@ use Composer\DependencyResolver\SolverProblemsException;
 use Composer\Package\Link;
 use Composer\Repository\InstalledArrayRepository;
 use Composer\Repository\RepositorySet;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Semver\Constraint\MultiConstraint;
 
 class SolverTest extends TestCase

+ 1 - 1
tests/Composer/Test/Downloader/FileDownloaderTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\Downloader;
 
 use Composer\Downloader\FileDownloader;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 
 class FileDownloaderTest extends TestCase

+ 1 - 1
tests/Composer/Test/Downloader/FossilDownloaderTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\Downloader;
 
 use Composer\Downloader\FossilDownloader;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 use Composer\Util\Platform;
 

+ 1 - 1
tests/Composer/Test/Downloader/GitDownloaderTest.php

@@ -14,7 +14,7 @@ namespace Composer\Test\Downloader;
 
 use Composer\Downloader\GitDownloader;
 use Composer\Config;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 use Composer\Util\Platform;
 

+ 1 - 1
tests/Composer/Test/Downloader/HgDownloaderTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\Downloader;
 
 use Composer\Downloader\HgDownloader;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 use Composer\Util\Platform;
 

+ 1 - 1
tests/Composer/Test/Downloader/PearPackageExtractorTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\Downloader;
 
 use Composer\Downloader\PearPackageExtractor;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class PearPackageExtractorTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/Downloader/PerforceDownloaderTest.php

@@ -16,7 +16,7 @@ use Composer\Downloader\PerforceDownloader;
 use Composer\Config;
 use Composer\Repository\VcsRepository;
 use Composer\IO\IOInterface;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 
 /**

+ 1 - 1
tests/Composer/Test/Downloader/XzDownloaderTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\Downloader;
 
 use Composer\Downloader\XzDownloader;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 use Composer\Util\Platform;
 use Composer\Util\RemoteFilesystem;

+ 5 - 3
tests/Composer/Test/Downloader/ZipDownloaderTest.php

@@ -14,7 +14,7 @@ namespace Composer\Test\Downloader;
 
 use Composer\Downloader\ZipDownloader;
 use Composer\Package\PackageInterface;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 
 class ZipDownloaderTest extends TestCase
@@ -24,6 +24,8 @@ class ZipDownloaderTest extends TestCase
      */
     private $testDir;
     private $prophet;
+    private $io;
+    private $config;
 
     public function setUp()
     {
@@ -46,9 +48,9 @@ class ZipDownloaderTest extends TestCase
         $reflectedProperty = $reflectionClass->getProperty($name);
         $reflectedProperty->setAccessible(true);
         if ($obj === null) {
-            $reflectedProperty = $reflectedProperty->setValue($value);
+            $reflectedProperty->setValue($value);
         } else {
-            $reflectedProperty = $reflectedProperty->setValue($obj, $value);
+            $reflectedProperty->setValue($obj, $value);
         }
     }
 

+ 1 - 1
tests/Composer/Test/EventDispatcher/EventDispatcherTest.php

@@ -17,7 +17,7 @@ use Composer\EventDispatcher\EventDispatcher;
 use Composer\Installer\InstallerEvents;
 use Composer\Config;
 use Composer\Composer;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\IO\BufferIO;
 use Composer\Script\ScriptEvents;
 use Composer\Script\Event as ScriptEvent;

+ 40 - 0
tests/Composer/Test/FactoryTest.php

@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Test;
+
+use Composer\Factory;
+
+class FactoryTest extends TestCase
+{
+    /**
+     * @group TLS
+     */
+    public function testDefaultValuesAreAsExpected()
+    {
+        $ioMock = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
+
+        $ioMock->expects($this->once())
+            ->method("writeError")
+            ->with($this->equalTo('<warning>You are running Composer with SSL/TLS protection disabled.</warning>'));
+
+        $config = $this
+            ->getMockBuilder('Composer\Config')
+            ->getMock();
+
+        $config->method('get')
+            ->with($this->equalTo('disable-tls'))
+            ->will($this->returnValue(true));
+
+        Factory::createRemoteFilesystem($ioMock, $config);
+    }
+}

+ 1 - 1
tests/Composer/Test/IO/ConsoleIOTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\IO;
 
 use Composer\IO\ConsoleIO;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Symfony\Component\Console\Output\OutputInterface;
 
 class ConsoleIOTest extends TestCase

+ 1 - 1
tests/Composer/Test/IO/NullIOTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\IO;
 
 use Composer\IO\NullIO;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class NullIOTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/Installer/LibraryInstallerTest.php

@@ -14,7 +14,7 @@ namespace Composer\Test\Installer;
 
 use Composer\Installer\LibraryInstaller;
 use Composer\Util\Filesystem;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Composer;
 use Composer\Config;
 

+ 0 - 1
tests/Composer/Test/InstallerTest.php

@@ -30,7 +30,6 @@ use Symfony\Component\Console\Input\StringInput;
 use Symfony\Component\Console\Output\StreamOutput;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Formatter\OutputFormatter;
-use Composer\TestCase;
 
 class InstallerTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/Mock/FactoryMock.php

@@ -19,7 +19,7 @@ use Composer\Repository\RepositoryManager;
 use Composer\Repository\WritableRepositoryInterface;
 use Composer\Installer;
 use Composer\IO\IOInterface;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class FactoryMock extends Factory
 {

+ 1 - 1
tests/Composer/Test/Package/Archiver/ArchivableFilesFinderTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\Package\Archiver;
 
 use Composer\Package\Archiver\ArchivableFilesFinder;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 use Symfony\Component\Process\Process;
 

+ 1 - 1
tests/Composer/Test/Package/Archiver/ArchiverTest.php

@@ -12,7 +12,7 @@
 
 namespace Composer\Test\Package\Archiver;
 
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 use Composer\Util\ProcessExecutor;
 use Composer\Package\Package;

+ 1 - 1
tests/Composer/Test/Package/CompletePackageTest.php

@@ -14,7 +14,7 @@ namespace Composer\Test\Package;
 
 use Composer\Package\Package;
 use Composer\Semver\VersionParser;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class CompletePackageTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/Package/RootAliasPackageTest.php

@@ -14,7 +14,7 @@ namespace Composer\Test\Package;
 
 use Composer\Package\Link;
 use Composer\Package\RootAliasPackage;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Prophecy\Argument;
 
 class RootAliasPackageTest extends TestCase

+ 2 - 2
tests/Composer/Test/Plugin/PluginInstallerTest.php

@@ -10,7 +10,7 @@
  * file that was distributed with this source code.
  */
 
-namespace Composer\Test\Installer;
+namespace Composer\Test\Plugin;
 
 use Composer\Composer;
 use Composer\Config;
@@ -20,7 +20,7 @@ use Composer\Package\Loader\JsonLoader;
 use Composer\Package\Loader\ArrayLoader;
 use Composer\Plugin\PluginManager;
 use Composer\Autoload\AutoloadGenerator;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 
 class PluginInstallerTest extends TestCase

+ 1 - 1
tests/Composer/Test/Question/StrictConfirmationQuestionTest.php

@@ -10,7 +10,7 @@
  * file that was distributed with this source code.
  */
 
-namespace Composer\Question\Test;
+namespace Composer\Test\Question;
 
 use Composer\Question\StrictConfirmationQuestion;
 use PHPUnit\Framework\TestCase;

+ 1 - 1
tests/Composer/Test/Repository/ArrayRepositoryTest.php

@@ -14,7 +14,7 @@ namespace Composer\Test\Repository;
 
 use Composer\Repository\ArrayRepository;
 use Composer\Repository\RepositoryInterface;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class ArrayRepositoryTest extends TestCase
 {

+ 4 - 4
tests/Composer/Test/Repository/ArtifactRepositoryTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\Repository;
 
 use Composer\Repository\ArtifactRepository;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\IO\NullIO;
 use Composer\Config;
 use Composer\Package\BasePackage;
@@ -42,7 +42,7 @@ class ArtifactRepositoryTest extends TestCase
         );
 
         $coordinates = array('type' => 'artifact', 'url' => __DIR__ . '/Fixtures/artifacts');
-        $repo = new ArtifactRepository($coordinates, new NullIO(), new Config());
+        $repo = new ArtifactRepository($coordinates, new NullIO());
 
         $foundPackages = array_map(function (BasePackage $package) {
             return "{$package->getPrettyName()}-{$package->getPrettyVersion()}";
@@ -58,7 +58,7 @@ class ArtifactRepositoryTest extends TestCase
     {
         $absolutePath = __DIR__ . '/Fixtures/artifacts';
         $coordinates = array('type' => 'artifact', 'url' => $absolutePath);
-        $repo = new ArtifactRepository($coordinates, new NullIO(), new Config());
+        $repo = new ArtifactRepository($coordinates, new NullIO());
 
         foreach ($repo->getPackages() as $package) {
             $this->assertSame(strpos($package->getDistUrl(), strtr($absolutePath, '\\', '/')), 0);
@@ -69,7 +69,7 @@ class ArtifactRepositoryTest extends TestCase
     {
         $relativePath = 'tests/Composer/Test/Repository/Fixtures/artifacts';
         $coordinates = array('type' => 'artifact', 'url' => $relativePath);
-        $repo = new ArtifactRepository($coordinates, new NullIO(), new Config());
+        $repo = new ArtifactRepository($coordinates, new NullIO());
 
         foreach ($repo->getPackages() as $package) {
             $this->assertSame(strpos($package->getDistUrl(), $relativePath), 0);

+ 1 - 1
tests/Composer/Test/Repository/ComposerRepositoryTest.php

@@ -16,7 +16,7 @@ use Composer\IO\NullIO;
 use Composer\Repository\ComposerRepository;
 use Composer\Repository\RepositoryInterface;
 use Composer\Test\Mock\FactoryMock;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Package\Loader\ArrayLoader;
 use Composer\Semver\VersionParser;
 

+ 1 - 1
tests/Composer/Test/Repository/CompositeRepositoryTest.php

@@ -14,7 +14,7 @@ namespace Composer\Test\Repository;
 
 use Composer\Repository\CompositeRepository;
 use Composer\Repository\ArrayRepository;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class CompositeRepositoryTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/Repository/FilesystemRepositoryTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\Repository;
 
 use Composer\Repository\FilesystemRepository;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class FilesystemRepositoryTest extends TestCase
 {

+ 1 - 0
tests/Composer/Test/Repository/Fixtures/artifacts/not-a-zip-with-zip-extension.zip

@@ -0,0 +1 @@
+AAAAAAAAA

+ 5 - 9
tests/Composer/Test/Repository/PathRepositoryTest.php

@@ -15,7 +15,7 @@ namespace Composer\Test\Repository;
 use Composer\Package\Loader\ArrayLoader;
 use Composer\Repository\PathRepository;
 use Composer\Semver\VersionParser;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class PathRepositoryTest extends TestCase
 {
@@ -25,11 +25,10 @@ class PathRepositoryTest extends TestCase
             ->getMock();
 
         $config = new \Composer\Config();
-        $loader = new ArrayLoader(new VersionParser());
         $versionGuesser = null;
 
         $repositoryUrl = implode(DIRECTORY_SEPARATOR, array(__DIR__, 'Fixtures', 'path', 'with-version'));
-        $repository = new PathRepository(array('url' => $repositoryUrl), $ioInterface, $config, $loader);
+        $repository = new PathRepository(array('url' => $repositoryUrl), $ioInterface, $config);
         $repository->getPackages();
 
         $this->assertEquals(1, $repository->count());
@@ -42,11 +41,10 @@ class PathRepositoryTest extends TestCase
             ->getMock();
 
         $config = new \Composer\Config();
-        $loader = new ArrayLoader(new VersionParser());
         $versionGuesser = null;
 
         $repositoryUrl = implode(DIRECTORY_SEPARATOR, array(__DIR__, 'Fixtures', 'path', 'without-version'));
-        $repository = new PathRepository(array('url' => $repositoryUrl), $ioInterface, $config, $loader);
+        $repository = new PathRepository(array('url' => $repositoryUrl), $ioInterface, $config);
         $packages = $repository->getPackages();
 
         $this->assertEquals(1, $repository->count());
@@ -64,11 +62,10 @@ class PathRepositoryTest extends TestCase
             ->getMock();
 
         $config = new \Composer\Config();
-        $loader = new ArrayLoader(new VersionParser());
         $versionGuesser = null;
 
         $repositoryUrl = implode(DIRECTORY_SEPARATOR, array(__DIR__, 'Fixtures', 'path', '*'));
-        $repository = new PathRepository(array('url' => $repositoryUrl), $ioInterface, $config, $loader);
+        $repository = new PathRepository(array('url' => $repositoryUrl), $ioInterface, $config);
         $packages = $repository->getPackages();
         $names = array();
 
@@ -93,7 +90,6 @@ class PathRepositoryTest extends TestCase
             ->getMock();
 
         $config = new \Composer\Config();
-        $loader = new ArrayLoader(new VersionParser());
         $versionGuesser = null;
 
         // realpath() does not fully expand the paths
@@ -103,7 +99,7 @@ class PathRepositoryTest extends TestCase
         // PHP Bug https://bugs.php.net/bug.php?id=73797
         $relativeUrl = ltrim(substr($repositoryUrl, strlen(realpath(realpath(getcwd())))), DIRECTORY_SEPARATOR);
 
-        $repository = new PathRepository(array('url' => $relativeUrl), $ioInterface, $config, $loader);
+        $repository = new PathRepository(array('url' => $relativeUrl), $ioInterface, $config);
         $packages = $repository->getPackages();
 
         $this->assertEquals(1, $repository->count());

+ 1 - 1
tests/Composer/Test/Repository/Pear/ChannelReaderTest.php

@@ -17,7 +17,7 @@ use Composer\Repository\Pear\DependencyConstraint;
 use Composer\Repository\Pear\DependencyInfo;
 use Composer\Repository\Pear\PackageInfo;
 use Composer\Repository\Pear\ReleaseInfo;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Semver\VersionParser;
 use Composer\Semver\Constraint\Constraint;
 use Composer\Package\Link;

+ 2 - 2
tests/Composer/Test/Repository/Pear/ChannelRest10ReaderTest.php

@@ -12,7 +12,7 @@
 
 namespace Composer\Test\Repository\Pear;
 
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Test\Mock\RemoteFilesystemMock;
 
 class ChannelRest10ReaderTest extends TestCase
@@ -31,7 +31,7 @@ class ChannelRest10ReaderTest extends TestCase
 
         $reader = new \Composer\Repository\Pear\ChannelRest10Reader($rfs);
 
-        /** @var $packages \Composer\Package\PackageInterface[] */
+        /** @var \Composer\Package\PackageInterface[] $packages */
         $packages = $reader->read('http://test.loc/rest10');
 
         $this->assertCount(2, $packages);

+ 2 - 2
tests/Composer/Test/Repository/Pear/ChannelRest11ReaderTest.php

@@ -12,7 +12,7 @@
 
 namespace Composer\Test\Repository\Pear;
 
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Test\Mock\RemoteFilesystemMock;
 
 class ChannelRest11ReaderTest extends TestCase
@@ -27,7 +27,7 @@ class ChannelRest11ReaderTest extends TestCase
 
         $reader = new \Composer\Repository\Pear\ChannelRest11Reader($rfs);
 
-        /** @var $packages \Composer\Package\PackageInterface[] */
+        /** @var \Composer\Package\PackageInterface[] $packages */
         $packages = $reader->read('http://test.loc/rest11');
 
         $this->assertCount(3, $packages);

+ 1 - 1
tests/Composer/Test/Repository/Pear/PackageDependencyParserTest.php

@@ -14,7 +14,7 @@ namespace Composer\Test\Repository\Pear;
 
 use Composer\Repository\Pear\DependencyConstraint;
 use Composer\Repository\Pear\PackageDependencyParser;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class PackageDependencyParserTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/Repository/PearRepositoryTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\Repository;
 
 use Composer\Repository\PearRepository;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 /**
  * @group legacy

+ 1 - 1
tests/Composer/Test/Repository/RepositoryFactoryTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\Repository;
 
 use Composer\Repository\RepositoryFactory;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 
 class RepositoryFactoryTest extends TestCase
 {

+ 1 - 1
tests/Composer/Test/Repository/RepositoryManagerTest.php

@@ -13,7 +13,7 @@
 namespace Composer\Test\Repository;
 
 use Composer\Repository\RepositoryManager;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 
 class RepositoryManagerTest extends TestCase

+ 1 - 1
tests/Composer/Test/Repository/Vcs/FossilDriverTest.php

@@ -14,7 +14,7 @@ namespace Composer\Test\Repository\Vcs;
 
 use Composer\Repository\Vcs\FossilDriver;
 use Composer\Config;
-use Composer\TestCase;
+use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 use Composer\Util\Platform;
 

Some files were not shown because too many files changed in this diff