diff --git a/src/Composer/Command/BaseDependencyCommand.php b/src/Composer/Command/BaseDependencyCommand.php index dfacb0639..31975b5ac 100644 --- a/src/Composer/Command/BaseDependencyCommand.php +++ b/src/Composer/Command/BaseDependencyCommand.php @@ -14,8 +14,10 @@ namespace Composer\Command; use Composer\Package\Link; use Composer\Package\PackageInterface; -use Composer\Repository\ArrayRepository; +use Composer\Repository\InstalledArrayRepository; use Composer\Repository\CompositeRepository; +use Composer\Repository\RootPackageRepository; +use Composer\Repository\InstalledRepository; use Composer\Repository\PlatformRepository; use Composer\Repository\RepositoryFactory; use Composer\Plugin\CommandEvent; @@ -70,10 +72,9 @@ class BaseDependencyCommand extends BaseCommand $commandEvent = new CommandEvent(PluginEvents::COMMAND, $this->getName(), $input, $output); $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); - // Prepare repositories and set up a repo set $platformOverrides = $composer->getConfig()->get('platform') ?: array(); - $repository = new CompositeRepository(array( - new ArrayRepository(array($composer->getPackage())), + $installedRepo = new InstalledRepository(array( + new RootPackageRepository($composer->getPackage()), $composer->getRepositoryManager()->getLocalRepository(), new PlatformRepository(array(), $platformOverrides), )); @@ -84,25 +85,19 @@ class BaseDependencyCommand extends BaseCommand 2, $input->getArgument(self::ARGUMENT_CONSTRAINT) ); - $needle = strtolower($needle); // Find packages that are or provide the requested package first - $packages = array(); - foreach ($repository->getPackages() as $package) { - if (in_array($needle, $package->getNames(), true)) { - $packages[] = $package; - } - } + $packages = $installedRepo->findPackagesWithReplacersAndProviders($needle); if (empty($packages)) { 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)) { + if (!$installedRepo->findPackage($needle, $textConstraint)) { $defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO())); if ($match = $defaultRepos->findPackage($needle, $textConstraint)) { - $repository->addRepository(new ArrayRepository(array(clone $match))); + $installedRepo->addRepository(new InstalledArrayRepository(array(clone $match))); } } @@ -129,7 +124,7 @@ class BaseDependencyCommand extends BaseCommand $recursive = $renderTree || $input->getOption(self::OPTION_RECURSIVE); // Resolve dependencies - $results = $repository->getDependents($needles, $constraint, $inverted, $recursive); + $results = $installedRepo->getDependents($needles, $constraint, $inverted, $recursive); if (empty($results)) { $extra = (null !== $constraint) ? sprintf(' in versions %smatching %s', $inverted ? 'not ' : '', $textConstraint) : ''; $this->getIO()->writeError(sprintf( diff --git a/src/Composer/Command/HomeCommand.php b/src/Composer/Command/HomeCommand.php index b7d907066..8e43f39a4 100644 --- a/src/Composer/Command/HomeCommand.php +++ b/src/Composer/Command/HomeCommand.php @@ -14,7 +14,7 @@ namespace Composer\Command; use Composer\Package\CompletePackageInterface; use Composer\Repository\RepositoryInterface; -use Composer\Repository\ArrayRepository; +use Composer\Repository\RootPackageRepository; use Composer\Repository\RepositoryFactory; use Composer\Util\Platform; use Composer\Util\ProcessExecutor; @@ -157,7 +157,7 @@ EOT if ($composer) { return array_merge( - array(new ArrayRepository(array($composer->getPackage()))), // root package + array(new RootPackageRepository($composer->getPackage())), // root package array($composer->getRepositoryManager()->getLocalRepository()), // installed packages $composer->getRepositoryManager()->getRepositories() // remotes ); diff --git a/src/Composer/Command/ShowCommand.php b/src/Composer/Command/ShowCommand.php index 3dd75c697..125dd741a 100644 --- a/src/Composer/Command/ShowCommand.php +++ b/src/Composer/Command/ShowCommand.php @@ -22,13 +22,14 @@ use Composer\Package\Version\VersionParser; use Composer\Package\Version\VersionSelector; use Composer\Plugin\CommandEvent; use Composer\Plugin\PluginEvents; -use Composer\Repository\ArrayRepository; use Composer\Repository\ComposerRepository; use Composer\Repository\CompositeRepository; use Composer\Repository\PlatformRepository; use Composer\Repository\RepositoryFactory; +use Composer\Repository\InstalledRepository; use Composer\Repository\RepositoryInterface; use Composer\Repository\RepositorySet; +use Composer\Repository\RootPackageRepository; use Composer\Semver\Constraint\ConstraintInterface; use Composer\Semver\Semver; use Composer\Spdx\SpdxLicenses; @@ -152,11 +153,11 @@ EOT if ($input->getOption('self')) { $package = $this->getComposer()->getPackage(); - $repos = $installedRepo = new ArrayRepository(array($package)); + $repos = $installedRepo = new InstalledRepository(array(new RootPackageRepository($package))); } elseif ($input->getOption('platform')) { - $repos = $installedRepo = $platformRepo; + $repos = $installedRepo = new InstalledRepository(array($platformRepo)); } elseif ($input->getOption('available')) { - $installedRepo = $platformRepo; + $installedRepo = new InstalledRepository(array($platformRepo)); if ($composer) { $repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories()); } else { @@ -166,15 +167,15 @@ EOT } } elseif ($input->getOption('all') && $composer) { $localRepo = $composer->getRepositoryManager()->getLocalRepository(); - $installedRepo = new CompositeRepository(array($localRepo, $platformRepo)); + $installedRepo = new InstalledRepository(array($localRepo, $platformRepo)); $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories())); } elseif ($input->getOption('all')) { $defaultRepos = RepositoryFactory::defaultRepos($io); $io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos))); - $installedRepo = $platformRepo; + $installedRepo = new InstalledRepository(array($platformRepo)); $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos)); } else { - $repos = $installedRepo = $this->getComposer()->getRepositoryManager()->getLocalRepository(); + $repos = $installedRepo = new InstalledRepository(array($this->getComposer()->getRepositoryManager()->getLocalRepository())); $rootPkg = $this->getComposer()->getPackage(); if (!$installedRepo->getPackages() && ($rootPkg->getRequires() || $rootPkg->getDevRequires())) { $io->writeError('No dependencies installed. Try running composer install or update.'); @@ -313,10 +314,7 @@ EOT foreach ($repos as $repo) { if ($repo === $platformRepo) { $type = 'platform'; - } elseif ( - $repo === $installedRepo - || ($installedRepo instanceof CompositeRepository && in_array($repo, $installedRepo->getRepositories(), true)) - ) { + } elseif ($repo === $installedRepo || in_array($repo, $installedRepo->getRepositories(), true)) { $type = 'installed'; } else { $type = 'available'; @@ -528,14 +526,14 @@ EOT /** * finds a package by name and version if provided * - * @param RepositoryInterface $installedRepo + * @param InstalledRepository $installedRepo * @param RepositoryInterface $repos * @param string $name * @param ConstraintInterface|string $version * @throws \InvalidArgumentException * @return array array(CompletePackageInterface, array of versions) */ - protected function getPackage(RepositoryInterface $installedRepo, RepositoryInterface $repos, $name, $version = null) + protected function getPackage(InstalledRepository $installedRepo, RepositoryInterface $repos, $name, $version = null) { $name = strtolower($name); $constraint = is_string($version) ? $this->versionParser->parseConstraints($version) : $version; @@ -573,10 +571,10 @@ EOT * * @param CompletePackageInterface $package * @param array $versions - * @param RepositoryInterface $installedRepo + * @param InstalledRepository $installedRepo * @param PackageInterface|null $latestPackage */ - protected function printPackageInfo(CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, PackageInterface $latestPackage = null) + protected function printPackageInfo(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo, PackageInterface $latestPackage = null) { $io = $this->getIO(); @@ -601,10 +599,10 @@ EOT * * @param CompletePackageInterface $package * @param array $versions - * @param RepositoryInterface $installedRepo + * @param InstalledRepository $installedRepo * @param PackageInterface|null $latestPackage */ - protected function printMeta(CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, PackageInterface $latestPackage = null) + protected function printMeta(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo, PackageInterface $latestPackage = null) { $io = $this->getIO(); $io->write('name : ' . $package->getPrettyName()); @@ -673,9 +671,9 @@ EOT * * @param CompletePackageInterface $package * @param array $versions - * @param RepositoryInterface $installedRepo + * @param InstalledRepository $installedRepo */ - protected function printVersions(CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo) + protected function printVersions(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo) { uasort($versions, 'version_compare'); $versions = array_keys(array_reverse($versions)); @@ -749,10 +747,10 @@ EOT * * @param CompletePackageInterface $package * @param array $versions - * @param RepositoryInterface $installedRepo + * @param InstalledRepository $installedRepo * @param PackageInterface|null $latestPackage */ - protected function printPackageInfoAsJson(CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, PackageInterface $latestPackage = null) + protected function printPackageInfoAsJson(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo, PackageInterface $latestPackage = null) { $json = array( 'name' => $package->getPrettyName(), @@ -972,15 +970,15 @@ EOT /** * Generate the package tree * - * @param PackageInterface $package - * @param RepositoryInterface $installedRepo - * @param RepositoryInterface $distantRepos + * @param PackageInterface $package + * @param InstalledRepository $installedRepo + * @param RepositoryInterface $remoteRepos * @return array */ protected function generatePackageTree( PackageInterface $package, - RepositoryInterface $installedRepo, - RepositoryInterface $distantRepos + InstalledRepository $installedRepo, + RepositoryInterface $remoteRepos ) { $requires = $package->getRequires(); ksort($requires); @@ -993,7 +991,7 @@ EOT 'version' => $require->getPrettyConstraint(), ); - $deepChildren = $this->addTree($requireName, $require, $installedRepo, $distantRepos, $packagesInTree); + $deepChildren = $this->addTree($requireName, $require, $installedRepo, $remoteRepos, $packagesInTree); if ($deepChildren) { $treeChildDesc['requires'] = $deepChildren; @@ -1072,22 +1070,22 @@ EOT * * @param string $name * @param PackageInterface|string $package - * @param RepositoryInterface $installedRepo - * @param RepositoryInterface $distantRepos + * @param InstalledRepository $installedRepo + * @param RepositoryInterface $remoteRepos * @param array $packagesInTree * @return array */ protected function addTree( $name, $package, - RepositoryInterface $installedRepo, - RepositoryInterface $distantRepos, + InstalledRepository $installedRepo, + RepositoryInterface $remoteRepos, array $packagesInTree ) { $children = array(); list($package, $versions) = $this->getPackage( $installedRepo, - $distantRepos, + $remoteRepos, $name, $package->getPrettyConstraint() === 'self.version' ? $package->getConstraint() : $package->getPrettyConstraint() ); @@ -1104,7 +1102,7 @@ EOT if (!in_array($requireName, $currentTree, true)) { $currentTree[] = $requireName; - $deepChildren = $this->addTree($requireName, $require, $installedRepo, $distantRepos, $currentTree); + $deepChildren = $this->addTree($requireName, $require, $installedRepo, $remoteRepos, $currentTree); if ($deepChildren) { $treeChildDesc['requires'] = $deepChildren; } diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 46b7ea1ea..bdee1e9f0 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -51,6 +51,7 @@ use Composer\Package\PackageInterface; use Composer\Package\RootPackageInterface; use Composer\Repository\CompositeRepository; use Composer\Repository\InstalledArrayRepository; +use Composer\Repository\InstalledRepository; use Composer\Repository\RootPackageRepository; use Composer\Repository\PlatformRepository; use Composer\Repository\RepositoryInterface; @@ -257,12 +258,12 @@ class Installer } if ($this->update) { - $installedRepos = array( + $installedRepo = new InstalledRepository(array( $this->locker->getLockedRepository($this->devMode), $this->createPlatformRepo(false), new RootPackageRepository(clone $this->package), - ); - $this->suggestedPackagesReporter->outputMinimalistic(new CompositeRepository($installedRepos)); + )); + $this->suggestedPackagesReporter->outputMinimalistic($installedRepo); } // Find abandoned packages and warn user @@ -859,8 +860,7 @@ class Installer } } - $repositorySet = new RepositorySet('dev'); - $repositorySet->addRepository($lockRepo); + $installedRepo = new InstalledRepository(array($lockRepo)); $seen = array(); @@ -870,7 +870,7 @@ class Installer $packageQueue = new \SplQueue; $nameMatchesRequiredPackage = false; - $depPackages = $repositorySet->findPackages($packageName, null, RepositorySet::ALLOW_PROVIDERS_REPLACERS); + $depPackages = $installedRepo->findPackagesWithReplacersAndProviders($packageName); $matchesByPattern = array(); // check if the name is a glob pattern that did not match directly @@ -878,7 +878,7 @@ class Installer // add any installed package matching the whitelisted name/pattern $whitelistPatternSearchRegexp = BasePackage::packageNameToRegexp($packageName, '^%s$'); foreach ($lockRepo->search($whitelistPatternSearchRegexp) as $installedPackage) { - $matchesByPattern[] = $repositorySet->findPackages($installedPackage['name'], null, RepositorySet::ALLOW_PROVIDERS_REPLACERS); + $matchesByPattern[] = $installedRepo->findPackages($installedPackage['name']); } // add root requirements which match the whitelisted name/pattern @@ -919,7 +919,7 @@ class Installer $requires = $package->getRequires(); foreach ($requires as $require) { - $requirePackages = $repositorySet->findPackages($require->getTarget(), null, RepositorySet::ALLOW_PROVIDERS_REPLACERS); + $requirePackages = $installedRepo->findPackagesWithReplacersAndProviders($require->getTarget()); foreach ($requirePackages as $requirePackage) { if (isset($this->updateWhitelist[$requirePackage->getName()])) { diff --git a/src/Composer/Plugin/PluginManager.php b/src/Composer/Plugin/PluginManager.php index ab7662bc8..97757f4fa 100644 --- a/src/Composer/Plugin/PluginManager.php +++ b/src/Composer/Plugin/PluginManager.php @@ -19,7 +19,7 @@ use Composer\Package\CompletePackage; use Composer\Package\Package; use Composer\Package\Version\VersionParser; use Composer\Repository\RepositoryInterface; -use Composer\Repository\CompositeRepository; +use Composer\Repository\InstalledRepository; use Composer\Package\PackageInterface; use Composer\Package\Link; use Composer\Semver\Constraint\Constraint; @@ -158,13 +158,13 @@ class PluginManager $localRepo = $this->composer->getRepositoryManager()->getLocalRepository(); $globalRepo = $this->globalComposer ? $this->globalComposer->getRepositoryManager()->getLocalRepository() : null; - $localRepos = $localRepo; + $installedRepo = new InstalledRepository(array($localRepo)); if ($globalRepo) { - $localRepos = new CompositeRepository(array($localRepos, $globalRepo)); + $installedRepo->addRepository($globalRepo); } $autoloadPackages = array($package->getName() => $package); - $autoloadPackages = $this->collectDependencies($localRepos, $autoloadPackages, $package); + $autoloadPackages = $this->collectDependencies($installedRepo, $autoloadPackages, $package); $generator = $this->composer->getAutoloadGenerator(); $autoloads = array(); @@ -375,13 +375,13 @@ class PluginManager /** * Recursively generates a map of package names to packages for all deps * - * @param RepositoryInterface $localRepos Set of local repos - * @param array $collected Current state of the map for recursion - * @param PackageInterface $package The package to analyze + * @param InstalledRepository $installedRepo Set of local repos + * @param array $collected Current state of the map for recursion + * @param PackageInterface $package The package to analyze * * @return array Map of package names to packages */ - private function collectDependencies(RepositoryInterface $localRepos, array $collected, PackageInterface $package) + private function collectDependencies(InstalledRepository $installedRepo, array $collected, PackageInterface $package) { $requires = array_merge( $package->getRequires(), @@ -389,10 +389,10 @@ class PluginManager ); foreach ($requires as $requireLink) { - foreach ($this->lookupInstalledPackages($localRepos, $requireLink) as $requiredPackage) { + foreach ($installedRepo->findPackagesWithReplacersAndProviders($requireLink->getTarget(), $requireLink->getConstraint()) as $requiredPackage) { if (!isset($collected[$requiredPackage->getName()])) { $collected[$requiredPackage->getName()] = $requiredPackage; - $collected = $this->collectDependencies($localRepos, $collected, $requiredPackage); + $collected = $this->collectDependencies($installedRepo, $collected, $requiredPackage); } } } @@ -400,30 +400,6 @@ class PluginManager return $collected; } - /** - * Resolves a package link to a package in the installed repo set - * - * Since dependencies are already installed this should always find one. - * - * @param RepositoryInterface $localRepos Set of local repos - * @param Link $link Package link to look up - * - * @return PackageInterface[] The found packages - */ - private function lookupInstalledPackages(RepositoryInterface $localRepos, Link $link) - { - $matches = array(); - foreach ($localRepos->getPackages() as $candidate) { - if (in_array($link->getTarget(), $candidate->getNames(), true)) { - if ($link->getConstraint() === null || $link->getConstraint()->matches(new Constraint('=', $candidate->getVersion()))) { - $matches[] = $candidate; - } - } - } - - return $matches; - } - /** * Retrieves the path a package is installed to. * diff --git a/src/Composer/Repository/ArrayRepository.php b/src/Composer/Repository/ArrayRepository.php index ab67d42d2..f63f80753 100644 --- a/src/Composer/Repository/ArrayRepository.php +++ b/src/Composer/Repository/ArrayRepository.php @@ -25,7 +25,7 @@ use Composer\Semver\Constraint\Constraint; * * @author Nils Adermann */ -class ArrayRepository extends BaseRepository +class ArrayRepository implements RepositoryInterface { /** @var PackageInterface[] */ protected $packages; @@ -44,7 +44,7 @@ class ArrayRepository extends BaseRepository public function getRepoName() { - return 'array repo (defining '.count($this->packages).' package'.(count($this->packages) > 1 ? 's' : '').')'; + return 'array repo (defining '.$this->count().' package'.($this->count() > 1 ? 's' : '').')'; } /** @@ -126,8 +126,7 @@ class ArrayRepository extends BaseRepository foreach ($this->getPackages() as $package) { if ($name === $package->getName()) { - $pkgConstraint = new Constraint('==', $package->getVersion()); - if (null === $constraint || $constraint->matches($pkgConstraint)) { + if (null === $constraint || $constraint->matches(new Constraint('==', $package->getVersion()))) { $packages[] = $package; } } @@ -250,6 +249,10 @@ class ArrayRepository extends BaseRepository */ public function count() { + if (null === $this->packages) { + $this->initialize(); + } + return count($this->packages); } diff --git a/src/Composer/Repository/CompositeRepository.php b/src/Composer/Repository/CompositeRepository.php index 806934b7d..5242da688 100644 --- a/src/Composer/Repository/CompositeRepository.php +++ b/src/Composer/Repository/CompositeRepository.php @@ -19,7 +19,7 @@ use Composer\Package\PackageInterface; * * @author Beau Simensen */ -class CompositeRepository extends BaseRepository +class CompositeRepository implements RepositoryInterface { /** * List of repositories diff --git a/src/Composer/Repository/BaseRepository.php b/src/Composer/Repository/InstalledRepository.php similarity index 80% rename from src/Composer/Repository/BaseRepository.php rename to src/Composer/Repository/InstalledRepository.php index 1274dbb43..42a8d3ce6 100644 --- a/src/Composer/Repository/BaseRepository.php +++ b/src/Composer/Repository/InstalledRepository.php @@ -12,19 +12,48 @@ namespace Composer\Repository; -use Composer\Package\AliasPackage; -use Composer\Package\RootPackageInterface; +use Composer\Package\Version\VersionParser; use Composer\Semver\Constraint\ConstraintInterface; use Composer\Semver\Constraint\Constraint; +use Composer\Package\AliasPackage; +use Composer\Package\RootPackageInterface; use Composer\Package\Link; + /** - * Common ancestor class for generic repository functionality. + * Installed repository is a composite of all installed repo types. + * + * The main use case is tagging a repo as an "installed" repository, and offering a way to get providers/replacers easily. + * + * Installed repos are LockArrayRepository, InstalledRepositoryInterface, RootPackageRepository and PlatformRepository * - * @author Niels Keurentjes + * @author Jordi Boggiano */ -abstract class BaseRepository implements RepositoryInterface +class InstalledRepository extends CompositeRepository { + public function findPackagesWithReplacersAndProviders($name, $constraint = null) + { + $name = strtolower($name); + + if (null !== $constraint && !$constraint instanceof ConstraintInterface) { + $versionParser = new VersionParser(); + $constraint = $versionParser->parseConstraints($constraint); + } + + $matches = array(); + foreach ($this->getRepositories() as $repo) { + foreach ($repo->getPackages() as $candidate) { + if (in_array($name, $candidate->getNames(), true)) { + if (null === $constraint || $constraint->matches(new Constraint('==', $candidate->getVersion()))) { + $matches[] = $candidate; + } + } + } + } + + return $matches; + } + /** * Returns a list of links causing the requested needle packages to be installed, as an associative array with the * dependent's name as key, and an array containing in order the PackageInterface and Link describing the relationship @@ -176,4 +205,27 @@ abstract class BaseRepository implements RepositoryInterface return $results; } + + public function getRepoName() + { + return 'installed repo ('.implode(', ', array_map(function ($repo) { return $repo->getRepoName(); }, $this->repositories)).')'; + } + + /** + * Add a repository. + * @param RepositoryInterface $repository + */ + public function addRepository(RepositoryInterface $repository) + { + if ( + $repository instanceof LockArrayRepository + || $repository instanceof InstalledRepositoryInterface + || $repository instanceof RootPackageRepository + || $repository instanceof PlatformRepository + ) { + return parent::addRepository($repository); + } + + throw new \LogicException('An InstalledRepository can not contain a repository of type '.get_class($repository).' ('.$repository->getRepoName().')'); + } } diff --git a/src/Composer/Repository/RepositorySet.php b/src/Composer/Repository/RepositorySet.php index 6cafaa6c2..98bc36bc6 100644 --- a/src/Composer/Repository/RepositorySet.php +++ b/src/Composer/Repository/RepositorySet.php @@ -30,18 +30,14 @@ use Composer\Package\Version\StabilityFilter; */ class RepositorySet { - /** - * Packages which replace/provide the given name might be returned as well even if they do not match the name exactly - */ - const ALLOW_PROVIDERS_REPLACERS = 1; /** * Packages are returned even though their stability does not match the required stability */ - const ALLOW_UNACCEPTABLE_STABILITIES = 2; + const ALLOW_UNACCEPTABLE_STABILITIES = 1; /** * Packages will be looked up in all repositories, even after they have been found in a higher prio one */ - const ALLOW_SHADOWED_REPOSITORIES = 4; + const ALLOW_SHADOWED_REPOSITORIES = 2; /** @var array */ private $rootAliases; @@ -127,7 +123,6 @@ class RepositorySet */ public function findPackages($name, ConstraintInterface $constraint = null, $flags = 0) { - $exactMatch = ($flags & self::ALLOW_PROVIDERS_REPLACERS) === 0; $ignoreStability = ($flags & self::ALLOW_UNACCEPTABLE_STABILITIES) !== 0; $loadFromAllRepos = ($flags & self::ALLOW_SHADOWED_REPOSITORIES) !== 0; @@ -152,13 +147,14 @@ class RepositorySet $candidates = $packages ? call_user_func_array('array_merge', $packages) : array(); + // when using loadPackages above (!$loadFromAllRepos) the repos already filter for stability so no need to do it again + if ($ignoreStability || !$loadFromAllRepos) { + return $candidates; + } + $result = array(); foreach ($candidates as $candidate) { - if ($exactMatch && $candidate->getName() !== $name) { - continue; - } - - if (!$ignoreStability && $this->isPackageAcceptable($candidate->getNames(), $candidate->getStability())) { + if ($this->isPackageAcceptable($candidate->getNames(), $candidate->getStability())) { $result[] = $candidate; } } diff --git a/tests/Composer/Test/Repository/InstalledRepositoryTest.php b/tests/Composer/Test/Repository/InstalledRepositoryTest.php new file mode 100644 index 000000000..a37adb058 --- /dev/null +++ b/tests/Composer/Test/Repository/InstalledRepositoryTest.php @@ -0,0 +1,51 @@ + + * 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\InstalledRepository; +use Composer\Repository\ArrayRepository; +use Composer\Repository\InstalledArrayRepository; +use Composer\Package\Link; +use Composer\Test\TestCase; + +class InstalledRepositoryTest extends TestCase +{ + public function testFindPackagesWithReplacersAndProviders() + { + $arrayRepoOne = new InstalledArrayRepository; + $arrayRepoOne->addPackage($foo = $this->getPackage('foo', '1')); + $arrayRepoOne->addPackage($foo2 = $this->getPackage('foo', '2')); + + $arrayRepoTwo = new InstalledArrayRepository; + $arrayRepoTwo->addPackage($bar = $this->getPackage('bar', '1')); + $arrayRepoTwo->addPackage($bar2 = $this->getPackage('bar', '2')); + + $foo->setReplaces(array(new Link('foo', 'provided'))); + $bar2->setProvides(array(new Link('bar', 'provided'))); + + $repo = new InstalledRepository(array($arrayRepoOne, $arrayRepoTwo)); + + $this->assertEquals(array($foo2), $repo->findPackagesWithReplacersAndProviders('foo', '2')); + $this->assertEquals(array($bar), $repo->findPackagesWithReplacersAndProviders('bar', '1')); + $this->assertEquals(array($foo, $bar2), $repo->findPackagesWithReplacersAndProviders('provided')); + } + + public function testAddRepository() + { + $arrayRepoOne = new ArrayRepository; + + $this->setExpectedException('LogicException'); + + new InstalledRepository(array($arrayRepoOne)); + } +}