From 1b196720bf451774f65a55e35b2298b9ef5482a4 Mon Sep 17 00:00:00 2001 From: Fred Emmott Date: Tue, 22 Jan 2019 13:45:25 -0800 Subject: [PATCH 01/14] Support identifying the HHVM version when not running with HHVM hhvm-nightly (and the next release) are no longer able to execute Composer. Support executing Composer with PHP to install dependencies for hack projects. The goal is for this to be temporary, until Hack identifies a new package manager, given that Composer does not aim to be a multi-language package manager. fixes #7734 --- .../Repository/PlatformRepository.php | 29 ++++++-- .../Repository/PlatformRepositoryTest.php | 69 +++++++++++++++++++ 2 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 tests/Composer/Test/Repository/PlatformRepositoryTest.php diff --git a/src/Composer/Repository/PlatformRepository.php b/src/Composer/Repository/PlatformRepository.php index 221f2eb97..56dc6ced5 100644 --- a/src/Composer/Repository/PlatformRepository.php +++ b/src/Composer/Repository/PlatformRepository.php @@ -16,8 +16,11 @@ use Composer\Package\CompletePackage; use Composer\Package\PackageInterface; use Composer\Package\Version\VersionParser; use Composer\Plugin\PluginInterface; +use Composer\Util\ProcessExecutor; use Composer\Util\Silencer; +use Composer\Util\Platform; use Composer\XdebugHandler\XdebugHandler; +use Symfony\Component\Process\ExecutableFinder; /** * @author Jordi Boggiano @@ -37,8 +40,11 @@ class PlatformRepository extends ArrayRepository */ private $overrides = array(); - public function __construct(array $packages = array(), array $overrides = array()) + private $process; + + public function __construct(array $packages = array(), array $overrides = array(), ProcessExecutor $process = null) { + $this->process = $process === null ? (new ProcessExecutor()) : $process; foreach ($overrides as $name => $version) { $this->overrides[strtolower($name)] = array('name' => $name, 'version' => $version); } @@ -220,12 +226,27 @@ class PlatformRepository extends ArrayRepository $this->addPackage($lib); } - if (defined('HHVM_VERSION')) { + $hhvmVersion = defined('HHVM_VERSION') ? HHVM_VERSION : null; + if ($hhvmVersion === null && !Platform::isWindows()) { + $finder = new ExecutableFinder(); + $hhvm = $finder->find('hhvm'); + if ($hhvm !== null) { + $exitCode = $this->process->execute( + ProcessExecutor::escape($hhvm). + ' --php -d hhvm.jit=0 -r "echo HHVM_VERSION;" 2>/dev/null', + $hhvmVersion + ); + if ($exitCode !== 0) { + $hhvmVersion = null; + } + } + } + if ($hhvmVersion) { try { - $prettyVersion = HHVM_VERSION; + $prettyVersion = $hhvmVersion; $version = $this->versionParser->normalize($prettyVersion); } catch (\UnexpectedValueException $e) { - $prettyVersion = preg_replace('#^([^~+-]+).*$#', '$1', HHVM_VERSION); + $prettyVersion = preg_replace('#^([^~+-]+).*$#', '$1', $hhvmVersion); $version = $this->versionParser->normalize($prettyVersion); } diff --git a/tests/Composer/Test/Repository/PlatformRepositoryTest.php b/tests/Composer/Test/Repository/PlatformRepositoryTest.php new file mode 100644 index 000000000..90674d4a3 --- /dev/null +++ b/tests/Composer/Test/Repository/PlatformRepositoryTest.php @@ -0,0 +1,69 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Test\Repository; + +use Composer\Repository\PlatformRepository; +use Composer\Test\TestCase; +use Composer\Util\Platform; +use Symfony\Component\Process\ExecutableFinder; + +class PlatformRepositoryTest extends TestCase { + public function testHHVMVersionWhenExecutingInHHVM() { + if (!defined('HHVM_VERSION_ID')) { + $this->markTestSkipped('Not running with HHVM'); + return; + } + $repository = new PlatformRepository(); + $package = $repository->findPackage('hhvm', '*'); + $this->assertNotNull($package, 'failed to find HHVM package'); + $this->assertSame( + sprintf('%d.%d.%d', + HHVM_VERSION_ID / 10000, + (HHVM_VERSION_ID / 100) % 100, + HHVM_VERSION_ID % 100 + ), + $package->getPrettyVersion() + ); + } + + public function testHHVMVersionWhenExecutingInPHP() { + if (defined('HHVM_VERSION_ID')) { + $this->markTestSkipped('Running with HHVM'); + return; + } + if (PHP_VERSION_ID < 50400) { + $this->markTestSkipped('Test only works on PHP 5.4+'); + return; + } + if (Platform::isWindows()) { + $this->markTestSkipped('Test does not run on Windows'); + return; + } + $hhvm = (new ExecutableFinder())->find('hhvm'); + if ($hhvm === null) { + $this->markTestSkipped('HHVM is not installed'); + } + $process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock(); + $process->expects($this->once())->method('execute')->will($this->returnCallback( + function($command, &$out) { + $this->assertContains('HHVM_VERSION', $command); + $out = '4.0.1-dev'; + return 0; + } + )); + $repository = new PlatformRepository(array(), array(), $process); + $package = $repository->findPackage('hhvm', '*'); + $this->assertNotNull($package, 'failed to find HHVM package'); + $this->assertSame('4.0.1.0-dev', $package->getVersion()); + } +} From bac2ef3dfdfe60cec4c1cea7371f776fa6073d0a Mon Sep 17 00:00:00 2001 From: Fred Emmott Date: Fri, 1 Feb 2019 11:20:34 -0800 Subject: [PATCH 02/14] Don't do (new Foo())->bar() - not 5.3-compatible --- tests/Composer/Test/Repository/PlatformRepositoryTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Composer/Test/Repository/PlatformRepositoryTest.php b/tests/Composer/Test/Repository/PlatformRepositoryTest.php index 90674d4a3..aa51a2fc6 100644 --- a/tests/Composer/Test/Repository/PlatformRepositoryTest.php +++ b/tests/Composer/Test/Repository/PlatformRepositoryTest.php @@ -49,7 +49,8 @@ class PlatformRepositoryTest extends TestCase { $this->markTestSkipped('Test does not run on Windows'); return; } - $hhvm = (new ExecutableFinder())->find('hhvm'); + $finder = new ExecutableFinder(); + $hhvm = $finder->find('hhvm'); if ($hhvm === null) { $this->markTestSkipped('HHVM is not installed'); } From 3b117da6d792ceae88b7dc894dfbe5b2f051c9b2 Mon Sep 17 00:00:00 2001 From: JakeConnors376W <46732192+JakeConnors376W@users.noreply.github.com> Date: Mon, 4 Feb 2019 15:59:50 -0800 Subject: [PATCH 03/14] Fix inconsistent casing --- doc/01-basic-usage.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/01-basic-usage.md b/doc/01-basic-usage.md index ffcb1589e..4981542e8 100644 --- a/doc/01-basic-usage.md +++ b/doc/01-basic-usage.md @@ -9,13 +9,13 @@ a logging library. If you have not yet installed Composer, refer to the > **Note:** for the sake of simplicity, this introduction will assume you > have performed a [local](00-intro.md#locally) install of Composer. -## `composer.json`: Project Setup +## `composer.json`: Project setup To start using Composer in your project, all you need is a `composer.json` file. This file describes the dependencies of your project and may contain other metadata as well. -### The `require` Key +### The `require` key The first (and often only) thing you specify in `composer.json` is the [`require`](04-schema.md#require) key. You are simply telling Composer which @@ -41,7 +41,7 @@ assumed that the `monolog/monolog` package is registered on Packagist. (See more about Packagist [below](#packagist), or read more about repositories [here](05-repositories.md)). -### Package Names +### Package names The package name consists of a vendor name and the project's name. Often these will be identical - the vendor name only exists to prevent naming clashes. For @@ -53,7 +53,7 @@ Read more about publishing packages and package naming [here](02-libraries.md). you to require certain versions of server software. See [platform packages](#platform-packages) below.) -### Package Version Constraints +### Package version constraints In our example, we are requesting the Monolog package with the version constraint [`1.0.*`](https://semver.mwl.be/#?package=monolog%2Fmonolog&version=1.0.*). @@ -84,7 +84,7 @@ versions, how versions relate to each other, and on version constraints. > versions of a package. Read more about stability flags and the `minimum-stability` > key on the [schema page](04-schema.md). -## Installing Dependencies +## Installing dependencies To install the defined dependencies for your project, run the [`install`](03-cli.md#install) command. @@ -95,7 +95,7 @@ php composer.phar install When you run this command, one of two things may happen: -### Installing Without `composer.lock` +### Installing without `composer.lock` If you have never run the command before and there is also no `composer.lock` file present, Composer simply resolves all dependencies listed in your `composer.json` file and downloads @@ -114,7 +114,7 @@ of them that it downloaded to the `composer.lock` file, locking the project to t versions. You should commit the `composer.lock` file to your project repo so that all people working on the project are locked to the same versions of dependencies (more below). -### Installing With `composer.lock` +### Installing with `composer.lock` This brings us to the second scenario. If there is already a `composer.lock` file as well as a `composer.json` file when you run `composer install`, it means either you ran the @@ -130,7 +130,7 @@ working on your project. As a result you will have all dependencies requested by the file was created). This is by design, it ensures that your project does not break because of unexpected changes in dependencies. -### Commit Your `composer.lock` File to Version Control +### Commit your `composer.lock` file to version control Committing this file to VC is important because it will cause anyone who sets up the project to use the exact same @@ -142,7 +142,7 @@ reinstalling the project you can feel confident the dependencies installed are still working even if your dependencies released many new versions since then. (See note below about using the `update` command.) -## Updating Dependencies to their Latest Versions +## Updating dependencies to their latest versions As mentioned above, the `composer.lock` file prevents you from automatically getting the latest versions of your dependencies. To update to the latest versions, use the From 17788c76f635f0f4ff43e19e672e651fc144faf4 Mon Sep 17 00:00:00 2001 From: Fred Emmott Date: Wed, 6 Feb 2019 12:51:30 -0800 Subject: [PATCH 04/14] Better error message for present but incompatible versions hhvm-nightly (and next week's release) now report 4.x, so all the 3.x constraints are now giving misleading error messages with this patch. Before: ``` - facebook/fbexpect v2.3.0 requires hhvm ^3.28 -> you are running this with PHP and not HHVM. ``` After: ``` - facebook/fbexpect v2.3.0 requires hhvm ^3.28 -> your HHVM version (4.0.0-dev) does not satisfy that requirement. ``` --- src/Composer/DependencyResolver/Rule.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Composer/DependencyResolver/Rule.php b/src/Composer/DependencyResolver/Rule.php index 4760b8964..82c9c499c 100644 --- a/src/Composer/DependencyResolver/Rule.php +++ b/src/Composer/DependencyResolver/Rule.php @@ -175,13 +175,18 @@ abstract class Rule return $text . ' -> your HHVM version does not satisfy that requirement.'; } - if ($targetName === 'hhvm') { - return $text . ' -> you are running this with PHP and not HHVM.'; - } - $packages = $pool->whatProvides($targetName); $package = count($packages) ? current($packages) : phpversion(); + if ($targetName === 'hhvm') { + if ($package instanceof CompletePackage) { + return $text . ' -> your HHVM version ('.$package->getPrettyVersion().') does not satisfy that requirement.'; + } else { + return $text . ' -> you are running this with PHP and not HHVM.'; + } + } + + if (!($package instanceof CompletePackage)) { return $text . ' -> your PHP version ('.phpversion().') does not satisfy that requirement.'; } From 41c7f4d2bfedcd7266e854240e2ac22e582473c3 Mon Sep 17 00:00:00 2001 From: Fred Emmott Date: Wed, 6 Feb 2019 13:11:04 -0800 Subject: [PATCH 05/14] Same but for Problem.php --- src/Composer/DependencyResolver/Problem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/DependencyResolver/Problem.php b/src/Composer/DependencyResolver/Problem.php index de24b0991..073f64e2d 100644 --- a/src/Composer/DependencyResolver/Problem.php +++ b/src/Composer/DependencyResolver/Problem.php @@ -106,7 +106,7 @@ class Problem $msg = "\n - This package requires ".$job['packageName'].$this->constraintToText($job['constraint']).' but '; - if (defined('HHVM_VERSION')) { + if (defined('HHVM_VERSION') || count($available)) { return $msg . 'your HHVM version does not satisfy that requirement.'; } From f89f9439e4a24013cb48c20fa84e96f00ae280b2 Mon Sep 17 00:00:00 2001 From: Marc Wilhelm Date: Thu, 7 Feb 2019 17:26:17 +0100 Subject: [PATCH 06/14] Update aliases.md Add composer command for alias. --- doc/articles/aliases.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/articles/aliases.md b/doc/articles/aliases.md index 98a6d1335..d36eb11ff 100644 --- a/doc/articles/aliases.md +++ b/doc/articles/aliases.md @@ -89,6 +89,12 @@ Add this to your project's root `composer.json`: } ``` +Or let composer add it for you with: + +``` +php composer.phar require monolog/monolog:"dev-bugfix as 1.0.x-dev" +``` + That will fetch the `dev-bugfix` version of `monolog/monolog` from your GitHub and alias it to `1.0.x-dev`. From f4b9bbbf42064548f77a77d602ff29ce06bd2f10 Mon Sep 17 00:00:00 2001 From: johnstevenson Date: Mon, 4 Feb 2019 12:02:05 +0000 Subject: [PATCH 07/14] Make unixy proxy code POSIX compatible --- src/Composer/Installer/BinaryInstaller.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Composer/Installer/BinaryInstaller.php b/src/Composer/Installer/BinaryInstaller.php index 0f709f60b..0a7b97149 100644 --- a/src/Composer/Installer/BinaryInstaller.php +++ b/src/Composer/Installer/BinaryInstaller.php @@ -196,9 +196,13 @@ class BinaryInstaller dir=\$(cd "\${0%[/\\\\]*}" > /dev/null; cd $binDir && pwd) -if [ -d /proc/cygdrive ] && [[ \$(which php) == \$(readlink -n /proc/cygdrive)/* ]]; then - # We are in Cgywin using Windows php, so the path must be translated - dir=\$(cygpath -m "\$dir"); +if [ -d /proc/cygdrive ]; then + case \$(which php) in + \$(readlink -n /proc/cygdrive)/*) + # We are in Cygwin using Windows php, so the path must be translated + dir=\$(cygpath -m "\$dir"); + ;; + esac fi "\${dir}/$binFile" "\$@" From eee98018f72903424d6d2a5d5bfd26baf3a1a13f Mon Sep 17 00:00:00 2001 From: Michael Telgmann Date: Thu, 7 Feb 2019 16:24:40 +0100 Subject: [PATCH 08/14] Soften hard exit after revert of composer file --- src/Composer/Command/RequireCommand.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Composer/Command/RequireCommand.php b/src/Composer/Command/RequireCommand.php index 1f29751b9..b347de094 100644 --- a/src/Composer/Command/RequireCommand.php +++ b/src/Composer/Command/RequireCommand.php @@ -195,7 +195,7 @@ EOT $status = $install->run(); if ($status !== 0) { - $this->revertComposerFile(); + $this->revertComposerFile(false); } return $status; @@ -226,7 +226,7 @@ EOT return; } - public function revertComposerFile() + public function revertComposerFile($hardExit = true) { $io = $this->getIO(); @@ -238,6 +238,8 @@ EOT file_put_contents($this->json->getPath(), $this->composerBackup); } - exit(1); + if ($hardExit) { + exit(1); + } } } From 408df4b87804503dc2c8861256dd303055652089 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 10 Feb 2019 12:39:00 +0100 Subject: [PATCH 09/14] Avoid dumping null values for dist reference/shasum and source reference, fixes #7955 --- src/Composer/Package/Dumper/ArrayDumper.php | 12 +++++++++--- src/Composer/Package/Loader/ArrayLoader.php | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Composer/Package/Dumper/ArrayDumper.php b/src/Composer/Package/Dumper/ArrayDumper.php index 6593143d5..b1e20dbf5 100644 --- a/src/Composer/Package/Dumper/ArrayDumper.php +++ b/src/Composer/Package/Dumper/ArrayDumper.php @@ -48,7 +48,9 @@ class ArrayDumper if ($package->getSourceType()) { $data['source']['type'] = $package->getSourceType(); $data['source']['url'] = $package->getSourceUrl(); - $data['source']['reference'] = $package->getSourceReference(); + if (null !== ($value = $package->getSourceReference())) { + $data['source']['reference'] = $value; + } if ($mirrors = $package->getSourceMirrors()) { $data['source']['mirrors'] = $mirrors; } @@ -57,8 +59,12 @@ class ArrayDumper if ($package->getDistType()) { $data['dist']['type'] = $package->getDistType(); $data['dist']['url'] = $package->getDistUrl(); - $data['dist']['reference'] = $package->getDistReference(); - $data['dist']['shasum'] = $package->getDistSha1Checksum(); + if (null !== ($value = $package->getDistReference())) { + $data['dist']['reference'] = $value; + } + if (null !== ($value = $package->getDistSha1Checksum())) { + $data['dist']['shasum'] = $value; + } if ($mirrors = $package->getDistMirrors()) { $data['dist']['mirrors'] = $mirrors; } diff --git a/src/Composer/Package/Loader/ArrayLoader.php b/src/Composer/Package/Loader/ArrayLoader.php index 303cc3c13..c269afa22 100644 --- a/src/Composer/Package/Loader/ArrayLoader.php +++ b/src/Composer/Package/Loader/ArrayLoader.php @@ -85,7 +85,7 @@ class ArrayLoader implements LoaderInterface } $package->setSourceType($config['source']['type']); $package->setSourceUrl($config['source']['url']); - $package->setSourceReference($config['source']['reference']); + $package->setSourceReference(isset($config['source']['reference']) ? $config['source']['reference'] : null); if (isset($config['source']['mirrors'])) { $package->setSourceMirrors($config['source']['mirrors']); } From 4de1f021f59a4565f362712558650de4d94e363e Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 10 Feb 2019 12:40:11 +0100 Subject: [PATCH 10/14] Quote wildcards to avoid issues in some shells, fixes #7960 --- doc/03-cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/03-cli.md b/doc/03-cli.md index c3faffe34..6460e9e1d 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -138,7 +138,7 @@ php composer.phar update vendor/package vendor/package2 You can also use wildcards to update a bunch of packages at once: ```sh -php composer.phar update vendor/* +php composer.phar update "vendor/*" ``` ### Options From e1ac0c794880e269f8600d21149d8a4c5dfa0ed5 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 10 Feb 2019 12:49:29 +0100 Subject: [PATCH 11/14] Recognize composer-plugin-api as a platform package, fixes #7951 --- src/Composer/Repository/PlatformRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Repository/PlatformRepository.php b/src/Composer/Repository/PlatformRepository.php index 56dc6ced5..50cbb4649 100644 --- a/src/Composer/Repository/PlatformRepository.php +++ b/src/Composer/Repository/PlatformRepository.php @@ -27,7 +27,7 @@ use Symfony\Component\Process\ExecutableFinder; */ class PlatformRepository extends ArrayRepository { - const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:[_.-]?[a-z0-9]+)*)$}iD'; + const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:[_.-]?[a-z0-9]+)*|composer-plugin-api)$}iD'; private $versionParser; From 94df55425596c0137d0aa14485bba2fb05e15de6 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 10 Feb 2019 12:56:43 +0100 Subject: [PATCH 12/14] Make sure config command output is also output on --quiet so that warnings can be hidden, fixes #7963 --- src/Composer/Command/ConfigCommand.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index b002fd3a7..c2347d306 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -21,6 +21,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Composer\Config; use Composer\Config\JsonConfigSource; use Composer\Factory; +use Composer\IO\IOInterface; use Composer\Json\JsonFile; use Composer\Semver\VersionParser; use Composer\Package\BasePackage; @@ -284,7 +285,7 @@ EOT $value = json_encode($value); } - $this->getIO()->write($value); + $this->getIO()->write($value, true, IOInterface::QUIET); return 0; } @@ -695,9 +696,9 @@ EOT } if (is_string($rawVal) && $rawVal != $value) { - $io->write('[' . $k . $key . '] ' . $rawVal . ' (' . $value . ')'); + $io->write('[' . $k . $key . '] ' . $rawVal . ' (' . $value . ')', true, IOInterface::QUIET); } else { - $io->write('[' . $k . $key . '] ' . $value . ''); + $io->write('[' . $k . $key . '] ' . $value . '', true, IOInterface::QUIET); } } } From c66bb0b1d06454cb73e6cd65b6be470417fae5ff Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 10 Feb 2019 13:07:42 +0100 Subject: [PATCH 13/14] Fix tests --- .../Fixtures/installer/install-dev-using-dist.test | 3 +-- .../Fixtures/installer/update-changes-url.test | 14 +++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test b/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test index ccc9ead1a..5846d13c0 100644 --- a/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test +++ b/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test @@ -35,8 +35,7 @@ install --prefer-dist "dist": { "type": "zip", "url": "http://www.example.com/dist.zip", - "reference": "459720ff3b74ee0c0d159277c6f2f5df89d8a4f6", - "shasum": null + "reference": "459720ff3b74ee0c0d159277c6f2f5df89d8a4f6" }, "type": "library" } diff --git a/tests/Composer/Test/Fixtures/installer/update-changes-url.test b/tests/Composer/Test/Fixtures/installer/update-changes-url.test index 70294c8e6..d774ea188 100644 --- a/tests/Composer/Test/Fixtures/installer/update-changes-url.test +++ b/tests/Composer/Test/Fixtures/installer/update-changes-url.test @@ -101,43 +101,43 @@ g/g is dev and installed in a different ref than the #ref, so it gets updated an { "name": "a/a", "version": "dev-master", "source": { "reference": "2222222222222222222222222222222222222222", "url": "https://github.com/a/newa", "type": "git" }, - "dist": { "reference": "2222222222222222222222222222222222222222", "url": "https://api.github.com/repos/a/newa/zipball/2222222222222222222222222222222222222222", "type": "zip", "shasum": null }, + "dist": { "reference": "2222222222222222222222222222222222222222", "url": "https://api.github.com/repos/a/newa/zipball/2222222222222222222222222222222222222222", "type": "zip" }, "type": "library" }, { "name": "b/b", "version": "2.0.3", "source": { "reference": "2222222222222222222222222222222222222222", "url": "https://github.com/b/newb", "type": "git" }, - "dist": { "reference": "2222222222222222222222222222222222222222", "url": "https://api.github.com/repos/b/newb/zipball/2222222222222222222222222222222222222222", "type": "zip", "shasum": null }, + "dist": { "reference": "2222222222222222222222222222222222222222", "url": "https://api.github.com/repos/b/newb/zipball/2222222222222222222222222222222222222222", "type": "zip" }, "type": "library" }, { "name": "c/c", "version": "1.0.0", "source": { "reference": "1111111111111111111111111111111111111111", "url": "https://github.com/c/newc", "type": "git" }, - "dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/c/newc/zipball/1111111111111111111111111111111111111111", "type": "zip", "shasum": null }, + "dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/c/newc/zipball/1111111111111111111111111111111111111111", "type": "zip" }, "type": "library" }, { "name": "d/d", "version": "dev-master", "source": { "reference": "1111111111111111111111111111111111111111", "url": "https://github.com/d/newd", "type": "git" }, - "dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/d/newd/zipball/1111111111111111111111111111111111111111", "type": "zip", "shasum": null }, + "dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/d/newd/zipball/1111111111111111111111111111111111111111", "type": "zip" }, "type": "library" }, { "name": "e/e", "version": "dev-master", "source": { "reference": "1111111111111111111111111111111111111111", "url": "https://github.com/e/newe", "type": "git" }, - "dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/e/newe/zipball/1111111111111111111111111111111111111111", "type": "zip", "shasum": null }, + "dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/e/newe/zipball/1111111111111111111111111111111111111111", "type": "zip" }, "type": "library" }, { "name": "f/f", "version": "dev-master", "source": { "reference": "1111111111111111111111111111111111111111", "url": "https://github.com/f/newf", "type": "git" }, - "dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/f/newf/zipball/1111111111111111111111111111111111111111", "type": "zip", "shasum": null }, + "dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/f/newf/zipball/1111111111111111111111111111111111111111", "type": "zip" }, "type": "library" }, { "name": "g/g", "version": "dev-master", "source": { "reference": "1111111111111111111111111111111111111111", "url": "https://github.com/g/newg", "type": "git" }, - "dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/g/newg/zipball/1111111111111111111111111111111111111111", "type": "zip", "shasum": null }, + "dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/g/newg/zipball/1111111111111111111111111111111111111111", "type": "zip" }, "type": "library" } ], From 29ff6a40ae2e64d52b444329ce16cf6b10eaf652 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 10 Feb 2019 20:26:47 +0100 Subject: [PATCH 14/14] Follow up to #7946 test: add solver flag to assert path execution --- src/Composer/DependencyResolver/Solver.php | 6 ++++++ tests/Composer/Test/DependencyResolver/SolverTest.php | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index c40789c1f..dbfafd243 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -57,6 +57,9 @@ class Solver /** @var array */ protected $learnedWhy = array(); + /** @var bool */ + public $testFlagLearnedPositiveLiteral = false; + /** @var IOInterface */ protected $io; @@ -470,6 +473,9 @@ class Solver unset($seen[abs($literal)]); if ($num && 0 === --$num) { + if ($literal < 0) { + $this->testFlagLearnedPositiveLiteral = true; + } $learnedLiterals[0] = -$literal; if (!$l1num) { diff --git a/tests/Composer/Test/DependencyResolver/SolverTest.php b/tests/Composer/Test/DependencyResolver/SolverTest.php index 7094f412d..4dadee7d8 100644 --- a/tests/Composer/Test/DependencyResolver/SolverTest.php +++ b/tests/Composer/Test/DependencyResolver/SolverTest.php @@ -891,6 +891,9 @@ class SolverTest extends TestCase $this->request->install('A'); + // check correct setup for assertion later + $this->assertFalse($this->solver->testFlagLearnedPositiveLiteral); + $this->checkSolverResult(array( array('job' => 'install', 'package' => $packageF1), array('job' => 'install', 'package' => $packageD), @@ -900,6 +903,10 @@ class SolverTest extends TestCase array('job' => 'install', 'package' => $packageB), array('job' => 'install', 'package' => $packageA), )); + + // verify that the code path leading to a negative literal resulting in a positive learned literal is actually + // executed + $this->assertTrue($this->solver->testFlagLearnedPositiveLiteral); } protected function reposComplete()