From 3933a7f404cfa197c5457f49b0665eae40ddedd9 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 7 Mar 2016 01:50:41 +0000 Subject: [PATCH] Add conflict detection in why-not, fixes #5013 --- src/Composer/Command/BaseDependencyCommand.php | 10 ++++++++++ src/Composer/Repository/BaseRepository.php | 13 +++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/Composer/Command/BaseDependencyCommand.php b/src/Composer/Command/BaseDependencyCommand.php index b0cfe7f7d..f02eb8e13 100644 --- a/src/Composer/Command/BaseDependencyCommand.php +++ b/src/Composer/Command/BaseDependencyCommand.php @@ -18,6 +18,7 @@ use Composer\Package\PackageInterface; use Composer\Repository\ArrayRepository; use Composer\Repository\CompositeRepository; use Composer\Repository\PlatformRepository; +use Composer\Repository\RepositoryFactory; use Composer\Plugin\CommandEvent; use Composer\Plugin\PluginEvents; use Symfony\Component\Console\Formatter\OutputFormatterStyle; @@ -93,6 +94,15 @@ class BaseDependencyCommand extends BaseCommand throw new \InvalidArgumentException(sprintf('Could not find package "%s" in your project', $needle)); } + // If the version we ask for is not installed then we need to locate it in remote repos and add it. + // This is needed for why-not to resolve conflicts from an uninstalled version against installed packages. + if (!$repository->findPackage($needle, $textConstraint)) { + $defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO())); + if ($match = $defaultRepos->findPackage($needle, $textConstraint)) { + $repository->addRepository(new ArrayRepository(array(clone $match))); + } + } + // Include replaced packages for inverted lookups as they are then the actual starting point to consider $needles = array($needle); if ($inverted) { diff --git a/src/Composer/Repository/BaseRepository.php b/src/Composer/Repository/BaseRepository.php index 79814eca8..04a40df07 100644 --- a/src/Composer/Repository/BaseRepository.php +++ b/src/Composer/Repository/BaseRepository.php @@ -14,6 +14,7 @@ namespace Composer\Repository; use Composer\Package\RootPackageInterface; use Composer\Semver\Constraint\ConstraintInterface; +use Composer\Semver\Constraint\Constraint; /** * Common ancestor class for generic repository functionality. @@ -80,6 +81,18 @@ abstract class BaseRepository implements RepositoryInterface } } } + + // When inverting, we need to check for conflicts of the needles against installed packages + if ($invert && in_array($package->getName(), $needles)) { + foreach ($package->getConflicts() as $link) { + foreach ($this->findPackages($link->getTarget()) as $pkg) { + $version = new Constraint('=', $pkg->getVersion()); + if ($link->getConstraint()->matches($version) === $invert) { + $results[$package->getName()] = array($package, $link, false); + } + } + } + } } ksort($results);