diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index f085e5c41..e03b6bd6a 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -18,6 +18,7 @@ use Composer\Pcre\Preg; use Composer\Repository\InstalledRepository; use Composer\Repository\LockArrayRepository; use Composer\Repository\PlatformRepository; +use Composer\Repository\RootPackageRepository; use Composer\Util\ProcessExecutor; use Composer\Package\Dumper\ArrayDumper; use Composer\Package\Loader\ArrayLoader; @@ -514,9 +515,10 @@ class Locker if ($includeDev === true) { $sets[] = ['repo' => $this->getLockedRepository(true), 'method' => 'getDevRequires', 'description' => 'Required (in require-dev)']; } + $rootRepo = new RootPackageRepository($package); foreach ($sets as $set) { - $installedRepo = new InstalledRepository([$set['repo']]); + $installedRepo = new InstalledRepository([$set['repo'], $rootRepo]); foreach (call_user_func([$package, $set['method']]) as $link) { if (PlatformRepository::isPlatformPackage($link->getTarget())) { @@ -527,9 +529,21 @@ class Locker } if ($installedRepo->findPackagesWithReplacersAndProviders($link->getTarget(), $link->getConstraint()) === []) { $results = $installedRepo->findPackagesWithReplacersAndProviders($link->getTarget()); + if ($results !== []) { $provider = reset($results); - $missingRequirementInfo[] = '- ' . $set['description'].' package "' . $link->getTarget() . '" is in the lock file as "'.$provider->getPrettyVersion().'" but that does not satisfy your constraint "'.$link->getPrettyConstraint().'".'; + $description = $provider->getPrettyVersion(); + if ($provider->getName() !== $link->getTarget()) { + foreach (['getReplaces' => 'replaced as %s by %s', 'getProvides' => 'provided as %s by %s'] as $method => $text) { + foreach (call_user_func([$provider, $method]) as $providerLink) { + if ($providerLink->getTarget() === $link->getTarget()) { + $description = sprintf($text, $providerLink->getPrettyConstraint(), $provider->getPrettyName().' '.$provider->getPrettyVersion()); + break 2; + } + } + } + } + $missingRequirementInfo[] = '- ' . $set['description'].' package "' . $link->getTarget() . '" is in the lock file as "'.$description.'" but that does not satisfy your constraint "'.$link->getPrettyConstraint().'".'; } else { $missingRequirementInfo[] = '- ' . $set['description'].' package "' . $link->getTarget() . '" is not present in the lock file.'; } diff --git a/tests/Composer/Test/Fixtures/installer/root-requirements-do-not-affect-locked-versions.test b/tests/Composer/Test/Fixtures/installer/root-requirements-do-not-affect-locked-versions.test index f8db5ff03..32127b612 100644 --- a/tests/Composer/Test/Fixtures/installer/root-requirements-do-not-affect-locked-versions.test +++ b/tests/Composer/Test/Fixtures/installer/root-requirements-do-not-affect-locked-versions.test @@ -17,7 +17,15 @@ The locked version will not get overwritten by an install but fails on invalid p "require": { "foo/bar": "2.0.0", "foo/baz": "2.0.0", - "foo/self": "self.version" + "foo/self": "self.version", + "foo/provided": "1.0.0", + "foo/provided-wrong-version": "1.0.0", + "foo/root-replaced": "1.0.0", + "foo/root-replaced-wrong-version": "1.0.0" + }, + "replace": { + "foo/root-replaced": "^1", + "foo/root-replaced-wrong-version": "^2" } } --LOCK-- @@ -25,7 +33,14 @@ The locked version will not get overwritten by an install but fails on invalid p "packages": [ { "name": "foo/bar", "version": "1.0.0" }, { "name": "foo/baz", "version": "2.0.0" }, - { "name": "foo/self", "version": "1.2.2" } + { + "name": "foo/self", + "version": "1.2.2", + "provide": { + "foo/provided": "^1", + "foo/provided-wrong-version": "^3" + } + } ], "packages-dev": [], "aliases": [], @@ -45,6 +60,8 @@ install Installing dependencies from lock file (including require-dev) Verifying lock file contents can be installed on current platform. - Required package "foo/bar" is in the lock file as "1.0.0" but that does not satisfy your constraint "2.0.0". +- Required package "foo/provided-wrong-version" is in the lock file as "provided as ^3 by foo/self 1.2.2" but that does not satisfy your constraint "1.0.0". +- Required package "foo/root-replaced-wrong-version" is in the lock file as "replaced as ^2 by __root__ 1.2.3" but that does not satisfy your constraint "1.0.0". This usually happens when composer files are incorrectly merged or the composer.json file is manually edited. Read more about correctly resolving merge conflicts https://getcomposer.org/doc/articles/resolving-merge-conflicts.md and prefer using the "require" command over editing the composer.json file directly https://getcomposer.org/doc/03-cli.md#require-r