1
0
Fork 0

Add InstalledRepository to clean up some concepts and usages, remove BaseRepository

pull/8669/head
Jordi Boggiano 2020-02-13 21:44:24 +01:00
parent 78885c556a
commit 2d8a8ed7e3
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
10 changed files with 184 additions and 113 deletions

View File

@ -14,8 +14,10 @@ namespace Composer\Command;
use Composer\Package\Link; use Composer\Package\Link;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Repository\ArrayRepository; use Composer\Repository\InstalledArrayRepository;
use Composer\Repository\CompositeRepository; use Composer\Repository\CompositeRepository;
use Composer\Repository\RootPackageRepository;
use Composer\Repository\InstalledRepository;
use Composer\Repository\PlatformRepository; use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryFactory; use Composer\Repository\RepositoryFactory;
use Composer\Plugin\CommandEvent; use Composer\Plugin\CommandEvent;
@ -70,10 +72,9 @@ class BaseDependencyCommand extends BaseCommand
$commandEvent = new CommandEvent(PluginEvents::COMMAND, $this->getName(), $input, $output); $commandEvent = new CommandEvent(PluginEvents::COMMAND, $this->getName(), $input, $output);
$composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
// Prepare repositories and set up a repo set
$platformOverrides = $composer->getConfig()->get('platform') ?: array(); $platformOverrides = $composer->getConfig()->get('platform') ?: array();
$repository = new CompositeRepository(array( $installedRepo = new InstalledRepository(array(
new ArrayRepository(array($composer->getPackage())), new RootPackageRepository($composer->getPackage()),
$composer->getRepositoryManager()->getLocalRepository(), $composer->getRepositoryManager()->getLocalRepository(),
new PlatformRepository(array(), $platformOverrides), new PlatformRepository(array(), $platformOverrides),
)); ));
@ -84,25 +85,19 @@ class BaseDependencyCommand extends BaseCommand
2, 2,
$input->getArgument(self::ARGUMENT_CONSTRAINT) $input->getArgument(self::ARGUMENT_CONSTRAINT)
); );
$needle = strtolower($needle);
// Find packages that are or provide the requested package first // Find packages that are or provide the requested package first
$packages = array(); $packages = $installedRepo->findPackagesWithReplacersAndProviders($needle);
foreach ($repository->getPackages() as $package) {
if (in_array($needle, $package->getNames(), true)) {
$packages[] = $package;
}
}
if (empty($packages)) { if (empty($packages)) {
throw new \InvalidArgumentException(sprintf('Could not find package "%s" in your project', $needle)); 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. // 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. // 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())); $defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO()));
if ($match = $defaultRepos->findPackage($needle, $textConstraint)) { 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); $recursive = $renderTree || $input->getOption(self::OPTION_RECURSIVE);
// Resolve dependencies // Resolve dependencies
$results = $repository->getDependents($needles, $constraint, $inverted, $recursive); $results = $installedRepo->getDependents($needles, $constraint, $inverted, $recursive);
if (empty($results)) { if (empty($results)) {
$extra = (null !== $constraint) ? sprintf(' in versions %smatching %s', $inverted ? 'not ' : '', $textConstraint) : ''; $extra = (null !== $constraint) ? sprintf(' in versions %smatching %s', $inverted ? 'not ' : '', $textConstraint) : '';
$this->getIO()->writeError(sprintf( $this->getIO()->writeError(sprintf(

View File

@ -14,7 +14,7 @@ namespace Composer\Command;
use Composer\Package\CompletePackageInterface; use Composer\Package\CompletePackageInterface;
use Composer\Repository\RepositoryInterface; use Composer\Repository\RepositoryInterface;
use Composer\Repository\ArrayRepository; use Composer\Repository\RootPackageRepository;
use Composer\Repository\RepositoryFactory; use Composer\Repository\RepositoryFactory;
use Composer\Util\Platform; use Composer\Util\Platform;
use Composer\Util\ProcessExecutor; use Composer\Util\ProcessExecutor;
@ -157,7 +157,7 @@ EOT
if ($composer) { if ($composer) {
return array_merge( return array_merge(
array(new ArrayRepository(array($composer->getPackage()))), // root package array(new RootPackageRepository($composer->getPackage())), // root package
array($composer->getRepositoryManager()->getLocalRepository()), // installed packages array($composer->getRepositoryManager()->getLocalRepository()), // installed packages
$composer->getRepositoryManager()->getRepositories() // remotes $composer->getRepositoryManager()->getRepositories() // remotes
); );

View File

@ -22,13 +22,14 @@ use Composer\Package\Version\VersionParser;
use Composer\Package\Version\VersionSelector; use Composer\Package\Version\VersionSelector;
use Composer\Plugin\CommandEvent; use Composer\Plugin\CommandEvent;
use Composer\Plugin\PluginEvents; use Composer\Plugin\PluginEvents;
use Composer\Repository\ArrayRepository;
use Composer\Repository\ComposerRepository; use Composer\Repository\ComposerRepository;
use Composer\Repository\CompositeRepository; use Composer\Repository\CompositeRepository;
use Composer\Repository\PlatformRepository; use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryFactory; use Composer\Repository\RepositoryFactory;
use Composer\Repository\InstalledRepository;
use Composer\Repository\RepositoryInterface; use Composer\Repository\RepositoryInterface;
use Composer\Repository\RepositorySet; use Composer\Repository\RepositorySet;
use Composer\Repository\RootPackageRepository;
use Composer\Semver\Constraint\ConstraintInterface; use Composer\Semver\Constraint\ConstraintInterface;
use Composer\Semver\Semver; use Composer\Semver\Semver;
use Composer\Spdx\SpdxLicenses; use Composer\Spdx\SpdxLicenses;
@ -152,11 +153,11 @@ EOT
if ($input->getOption('self')) { if ($input->getOption('self')) {
$package = $this->getComposer()->getPackage(); $package = $this->getComposer()->getPackage();
$repos = $installedRepo = new ArrayRepository(array($package)); $repos = $installedRepo = new InstalledRepository(array(new RootPackageRepository($package)));
} elseif ($input->getOption('platform')) { } elseif ($input->getOption('platform')) {
$repos = $installedRepo = $platformRepo; $repos = $installedRepo = new InstalledRepository(array($platformRepo));
} elseif ($input->getOption('available')) { } elseif ($input->getOption('available')) {
$installedRepo = $platformRepo; $installedRepo = new InstalledRepository(array($platformRepo));
if ($composer) { if ($composer) {
$repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories()); $repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
} else { } else {
@ -166,15 +167,15 @@ EOT
} }
} elseif ($input->getOption('all') && $composer) { } elseif ($input->getOption('all') && $composer) {
$localRepo = $composer->getRepositoryManager()->getLocalRepository(); $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())); $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
} elseif ($input->getOption('all')) { } elseif ($input->getOption('all')) {
$defaultRepos = RepositoryFactory::defaultRepos($io); $defaultRepos = RepositoryFactory::defaultRepos($io);
$io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos))); $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)); $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));
} else { } else {
$repos = $installedRepo = $this->getComposer()->getRepositoryManager()->getLocalRepository(); $repos = $installedRepo = new InstalledRepository(array($this->getComposer()->getRepositoryManager()->getLocalRepository()));
$rootPkg = $this->getComposer()->getPackage(); $rootPkg = $this->getComposer()->getPackage();
if (!$installedRepo->getPackages() && ($rootPkg->getRequires() || $rootPkg->getDevRequires())) { if (!$installedRepo->getPackages() && ($rootPkg->getRequires() || $rootPkg->getDevRequires())) {
$io->writeError('<warning>No dependencies installed. Try running composer install or update.</warning>'); $io->writeError('<warning>No dependencies installed. Try running composer install or update.</warning>');
@ -313,10 +314,7 @@ EOT
foreach ($repos as $repo) { foreach ($repos as $repo) {
if ($repo === $platformRepo) { if ($repo === $platformRepo) {
$type = 'platform'; $type = 'platform';
} elseif ( } elseif ($repo === $installedRepo || in_array($repo, $installedRepo->getRepositories(), true)) {
$repo === $installedRepo
|| ($installedRepo instanceof CompositeRepository && in_array($repo, $installedRepo->getRepositories(), true))
) {
$type = 'installed'; $type = 'installed';
} else { } else {
$type = 'available'; $type = 'available';
@ -528,14 +526,14 @@ EOT
/** /**
* finds a package by name and version if provided * finds a package by name and version if provided
* *
* @param RepositoryInterface $installedRepo * @param InstalledRepository $installedRepo
* @param RepositoryInterface $repos * @param RepositoryInterface $repos
* @param string $name * @param string $name
* @param ConstraintInterface|string $version * @param ConstraintInterface|string $version
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @return array array(CompletePackageInterface, array of versions) * @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); $name = strtolower($name);
$constraint = is_string($version) ? $this->versionParser->parseConstraints($version) : $version; $constraint = is_string($version) ? $this->versionParser->parseConstraints($version) : $version;
@ -573,10 +571,10 @@ EOT
* *
* @param CompletePackageInterface $package * @param CompletePackageInterface $package
* @param array $versions * @param array $versions
* @param RepositoryInterface $installedRepo * @param InstalledRepository $installedRepo
* @param PackageInterface|null $latestPackage * @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(); $io = $this->getIO();
@ -601,10 +599,10 @@ EOT
* *
* @param CompletePackageInterface $package * @param CompletePackageInterface $package
* @param array $versions * @param array $versions
* @param RepositoryInterface $installedRepo * @param InstalledRepository $installedRepo
* @param PackageInterface|null $latestPackage * @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 = $this->getIO();
$io->write('<info>name</info> : ' . $package->getPrettyName()); $io->write('<info>name</info> : ' . $package->getPrettyName());
@ -673,9 +671,9 @@ EOT
* *
* @param CompletePackageInterface $package * @param CompletePackageInterface $package
* @param array $versions * @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'); uasort($versions, 'version_compare');
$versions = array_keys(array_reverse($versions)); $versions = array_keys(array_reverse($versions));
@ -749,10 +747,10 @@ EOT
* *
* @param CompletePackageInterface $package * @param CompletePackageInterface $package
* @param array $versions * @param array $versions
* @param RepositoryInterface $installedRepo * @param InstalledRepository $installedRepo
* @param PackageInterface|null $latestPackage * @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( $json = array(
'name' => $package->getPrettyName(), 'name' => $package->getPrettyName(),
@ -973,14 +971,14 @@ EOT
* Generate the package tree * Generate the package tree
* *
* @param PackageInterface $package * @param PackageInterface $package
* @param RepositoryInterface $installedRepo * @param InstalledRepository $installedRepo
* @param RepositoryInterface $distantRepos * @param RepositoryInterface $remoteRepos
* @return array * @return array
*/ */
protected function generatePackageTree( protected function generatePackageTree(
PackageInterface $package, PackageInterface $package,
RepositoryInterface $installedRepo, InstalledRepository $installedRepo,
RepositoryInterface $distantRepos RepositoryInterface $remoteRepos
) { ) {
$requires = $package->getRequires(); $requires = $package->getRequires();
ksort($requires); ksort($requires);
@ -993,7 +991,7 @@ EOT
'version' => $require->getPrettyConstraint(), 'version' => $require->getPrettyConstraint(),
); );
$deepChildren = $this->addTree($requireName, $require, $installedRepo, $distantRepos, $packagesInTree); $deepChildren = $this->addTree($requireName, $require, $installedRepo, $remoteRepos, $packagesInTree);
if ($deepChildren) { if ($deepChildren) {
$treeChildDesc['requires'] = $deepChildren; $treeChildDesc['requires'] = $deepChildren;
@ -1072,22 +1070,22 @@ EOT
* *
* @param string $name * @param string $name
* @param PackageInterface|string $package * @param PackageInterface|string $package
* @param RepositoryInterface $installedRepo * @param InstalledRepository $installedRepo
* @param RepositoryInterface $distantRepos * @param RepositoryInterface $remoteRepos
* @param array $packagesInTree * @param array $packagesInTree
* @return array * @return array
*/ */
protected function addTree( protected function addTree(
$name, $name,
$package, $package,
RepositoryInterface $installedRepo, InstalledRepository $installedRepo,
RepositoryInterface $distantRepos, RepositoryInterface $remoteRepos,
array $packagesInTree array $packagesInTree
) { ) {
$children = array(); $children = array();
list($package, $versions) = $this->getPackage( list($package, $versions) = $this->getPackage(
$installedRepo, $installedRepo,
$distantRepos, $remoteRepos,
$name, $name,
$package->getPrettyConstraint() === 'self.version' ? $package->getConstraint() : $package->getPrettyConstraint() $package->getPrettyConstraint() === 'self.version' ? $package->getConstraint() : $package->getPrettyConstraint()
); );
@ -1104,7 +1102,7 @@ EOT
if (!in_array($requireName, $currentTree, true)) { if (!in_array($requireName, $currentTree, true)) {
$currentTree[] = $requireName; $currentTree[] = $requireName;
$deepChildren = $this->addTree($requireName, $require, $installedRepo, $distantRepos, $currentTree); $deepChildren = $this->addTree($requireName, $require, $installedRepo, $remoteRepos, $currentTree);
if ($deepChildren) { if ($deepChildren) {
$treeChildDesc['requires'] = $deepChildren; $treeChildDesc['requires'] = $deepChildren;
} }

View File

@ -51,6 +51,7 @@ use Composer\Package\PackageInterface;
use Composer\Package\RootPackageInterface; use Composer\Package\RootPackageInterface;
use Composer\Repository\CompositeRepository; use Composer\Repository\CompositeRepository;
use Composer\Repository\InstalledArrayRepository; use Composer\Repository\InstalledArrayRepository;
use Composer\Repository\InstalledRepository;
use Composer\Repository\RootPackageRepository; use Composer\Repository\RootPackageRepository;
use Composer\Repository\PlatformRepository; use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryInterface; use Composer\Repository\RepositoryInterface;
@ -257,12 +258,12 @@ class Installer
} }
if ($this->update) { if ($this->update) {
$installedRepos = array( $installedRepo = new InstalledRepository(array(
$this->locker->getLockedRepository($this->devMode), $this->locker->getLockedRepository($this->devMode),
$this->createPlatformRepo(false), $this->createPlatformRepo(false),
new RootPackageRepository(clone $this->package), new RootPackageRepository(clone $this->package),
); ));
$this->suggestedPackagesReporter->outputMinimalistic(new CompositeRepository($installedRepos)); $this->suggestedPackagesReporter->outputMinimalistic($installedRepo);
} }
// Find abandoned packages and warn user // Find abandoned packages and warn user
@ -859,8 +860,7 @@ class Installer
} }
} }
$repositorySet = new RepositorySet('dev'); $installedRepo = new InstalledRepository(array($lockRepo));
$repositorySet->addRepository($lockRepo);
$seen = array(); $seen = array();
@ -870,7 +870,7 @@ class Installer
$packageQueue = new \SplQueue; $packageQueue = new \SplQueue;
$nameMatchesRequiredPackage = false; $nameMatchesRequiredPackage = false;
$depPackages = $repositorySet->findPackages($packageName, null, RepositorySet::ALLOW_PROVIDERS_REPLACERS); $depPackages = $installedRepo->findPackagesWithReplacersAndProviders($packageName);
$matchesByPattern = array(); $matchesByPattern = array();
// check if the name is a glob pattern that did not match directly // 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 // add any installed package matching the whitelisted name/pattern
$whitelistPatternSearchRegexp = BasePackage::packageNameToRegexp($packageName, '^%s$'); $whitelistPatternSearchRegexp = BasePackage::packageNameToRegexp($packageName, '^%s$');
foreach ($lockRepo->search($whitelistPatternSearchRegexp) as $installedPackage) { 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 // add root requirements which match the whitelisted name/pattern
@ -919,7 +919,7 @@ class Installer
$requires = $package->getRequires(); $requires = $package->getRequires();
foreach ($requires as $require) { foreach ($requires as $require) {
$requirePackages = $repositorySet->findPackages($require->getTarget(), null, RepositorySet::ALLOW_PROVIDERS_REPLACERS); $requirePackages = $installedRepo->findPackagesWithReplacersAndProviders($require->getTarget());
foreach ($requirePackages as $requirePackage) { foreach ($requirePackages as $requirePackage) {
if (isset($this->updateWhitelist[$requirePackage->getName()])) { if (isset($this->updateWhitelist[$requirePackage->getName()])) {

View File

@ -19,7 +19,7 @@ use Composer\Package\CompletePackage;
use Composer\Package\Package; use Composer\Package\Package;
use Composer\Package\Version\VersionParser; use Composer\Package\Version\VersionParser;
use Composer\Repository\RepositoryInterface; use Composer\Repository\RepositoryInterface;
use Composer\Repository\CompositeRepository; use Composer\Repository\InstalledRepository;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Package\Link; use Composer\Package\Link;
use Composer\Semver\Constraint\Constraint; use Composer\Semver\Constraint\Constraint;
@ -158,13 +158,13 @@ class PluginManager
$localRepo = $this->composer->getRepositoryManager()->getLocalRepository(); $localRepo = $this->composer->getRepositoryManager()->getLocalRepository();
$globalRepo = $this->globalComposer ? $this->globalComposer->getRepositoryManager()->getLocalRepository() : null; $globalRepo = $this->globalComposer ? $this->globalComposer->getRepositoryManager()->getLocalRepository() : null;
$localRepos = $localRepo; $installedRepo = new InstalledRepository(array($localRepo));
if ($globalRepo) { if ($globalRepo) {
$localRepos = new CompositeRepository(array($localRepos, $globalRepo)); $installedRepo->addRepository($globalRepo);
} }
$autoloadPackages = array($package->getName() => $package); $autoloadPackages = array($package->getName() => $package);
$autoloadPackages = $this->collectDependencies($localRepos, $autoloadPackages, $package); $autoloadPackages = $this->collectDependencies($installedRepo, $autoloadPackages, $package);
$generator = $this->composer->getAutoloadGenerator(); $generator = $this->composer->getAutoloadGenerator();
$autoloads = array(); $autoloads = array();
@ -375,13 +375,13 @@ class PluginManager
/** /**
* Recursively generates a map of package names to packages for all deps * Recursively generates a map of package names to packages for all deps
* *
* @param RepositoryInterface $localRepos Set of local repos * @param InstalledRepository $installedRepo Set of local repos
* @param array $collected Current state of the map for recursion * @param array $collected Current state of the map for recursion
* @param PackageInterface $package The package to analyze * @param PackageInterface $package The package to analyze
* *
* @return array Map of package names to packages * @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( $requires = array_merge(
$package->getRequires(), $package->getRequires(),
@ -389,10 +389,10 @@ class PluginManager
); );
foreach ($requires as $requireLink) { 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()])) { if (!isset($collected[$requiredPackage->getName()])) {
$collected[$requiredPackage->getName()] = $requiredPackage; $collected[$requiredPackage->getName()] = $requiredPackage;
$collected = $this->collectDependencies($localRepos, $collected, $requiredPackage); $collected = $this->collectDependencies($installedRepo, $collected, $requiredPackage);
} }
} }
} }
@ -400,30 +400,6 @@ class PluginManager
return $collected; 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. * Retrieves the path a package is installed to.
* *

View File

@ -25,7 +25,7 @@ use Composer\Semver\Constraint\Constraint;
* *
* @author Nils Adermann <naderman@naderman.de> * @author Nils Adermann <naderman@naderman.de>
*/ */
class ArrayRepository extends BaseRepository class ArrayRepository implements RepositoryInterface
{ {
/** @var PackageInterface[] */ /** @var PackageInterface[] */
protected $packages; protected $packages;
@ -44,7 +44,7 @@ class ArrayRepository extends BaseRepository
public function getRepoName() 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) { foreach ($this->getPackages() as $package) {
if ($name === $package->getName()) { if ($name === $package->getName()) {
$pkgConstraint = new Constraint('==', $package->getVersion()); if (null === $constraint || $constraint->matches(new Constraint('==', $package->getVersion()))) {
if (null === $constraint || $constraint->matches($pkgConstraint)) {
$packages[] = $package; $packages[] = $package;
} }
} }
@ -250,6 +249,10 @@ class ArrayRepository extends BaseRepository
*/ */
public function count() public function count()
{ {
if (null === $this->packages) {
$this->initialize();
}
return count($this->packages); return count($this->packages);
} }

View File

@ -19,7 +19,7 @@ use Composer\Package\PackageInterface;
* *
* @author Beau Simensen <beau@dflydev.com> * @author Beau Simensen <beau@dflydev.com>
*/ */
class CompositeRepository extends BaseRepository class CompositeRepository implements RepositoryInterface
{ {
/** /**
* List of repositories * List of repositories

View File

@ -12,19 +12,48 @@
namespace Composer\Repository; namespace Composer\Repository;
use Composer\Package\AliasPackage; use Composer\Package\Version\VersionParser;
use Composer\Package\RootPackageInterface;
use Composer\Semver\Constraint\ConstraintInterface; use Composer\Semver\Constraint\ConstraintInterface;
use Composer\Semver\Constraint\Constraint; use Composer\Semver\Constraint\Constraint;
use Composer\Package\AliasPackage;
use Composer\Package\RootPackageInterface;
use Composer\Package\Link; use Composer\Package\Link;
/** /**
* Common ancestor class for generic repository functionality. * Installed repository is a composite of all installed repo types.
* *
* @author Niels Keurentjes <niels.keurentjes@omines.com> * 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 Jordi Boggiano <j.boggiano@seld.be>
*/ */
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 * 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 * 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; 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().')');
}
} }

View File

@ -30,18 +30,14 @@ use Composer\Package\Version\StabilityFilter;
*/ */
class RepositorySet 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 * 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 * 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 */ /** @var array */
private $rootAliases; private $rootAliases;
@ -127,7 +123,6 @@ class RepositorySet
*/ */
public function findPackages($name, ConstraintInterface $constraint = null, $flags = 0) public function findPackages($name, ConstraintInterface $constraint = null, $flags = 0)
{ {
$exactMatch = ($flags & self::ALLOW_PROVIDERS_REPLACERS) === 0;
$ignoreStability = ($flags & self::ALLOW_UNACCEPTABLE_STABILITIES) !== 0; $ignoreStability = ($flags & self::ALLOW_UNACCEPTABLE_STABILITIES) !== 0;
$loadFromAllRepos = ($flags & self::ALLOW_SHADOWED_REPOSITORIES) !== 0; $loadFromAllRepos = ($flags & self::ALLOW_SHADOWED_REPOSITORIES) !== 0;
@ -152,13 +147,14 @@ class RepositorySet
$candidates = $packages ? call_user_func_array('array_merge', $packages) : array(); $candidates = $packages ? call_user_func_array('array_merge', $packages) : array();
$result = array(); // when using loadPackages above (!$loadFromAllRepos) the repos already filter for stability so no need to do it again
foreach ($candidates as $candidate) { if ($ignoreStability || !$loadFromAllRepos) {
if ($exactMatch && $candidate->getName() !== $name) { return $candidates;
continue;
} }
if (!$ignoreStability && $this->isPackageAcceptable($candidate->getNames(), $candidate->getStability())) { $result = array();
foreach ($candidates as $candidate) {
if ($this->isPackageAcceptable($candidate->getNames(), $candidate->getStability())) {
$result[] = $candidate; $result[] = $candidate;
} }
} }

View File

@ -0,0 +1,51 @@
<?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\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));
}
}