Add a new RepositorySet class and restrict pool usage to the solver

Breaking change for the plugin interface so bumping the version of
composer-plugin-api to 2.0.0

First step for a refactoring of the package metadata loading mechanism
main
Nils Adermann 6 years ago
parent 92dc2cd9ad
commit 6ef65e5319

@ -21,6 +21,7 @@ use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryFactory; use Composer\Repository\RepositoryFactory;
use Composer\Plugin\CommandEvent; use Composer\Plugin\CommandEvent;
use Composer\Plugin\PluginEvents; use Composer\Plugin\PluginEvents;
use Composer\Repository\RepositorySet;
use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Composer\Package\Version\VersionParser; use Composer\Package\Version\VersionParser;
use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Helper\Table;
@ -71,15 +72,15 @@ 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 pool // Prepare repositories and set up a repo set
$platformOverrides = $composer->getConfig()->get('platform') ?: array(); $platformOverrides = $composer->getConfig()->get('platform') ?: array();
$repository = new CompositeRepository(array( $repository = new CompositeRepository(array(
new ArrayRepository(array($composer->getPackage())), new ArrayRepository(array($composer->getPackage())),
$composer->getRepositoryManager()->getLocalRepository(), $composer->getRepositoryManager()->getLocalRepository(),
new PlatformRepository(array(), $platformOverrides), new PlatformRepository(array(), $platformOverrides),
)); ));
$pool = new Pool(); $repositorySet = new RepositorySet(new Pool());
$pool->addRepository($repository); $repositorySet->addRepository($repository);
// Parse package name and constraint // Parse package name and constraint
list($needle, $textConstraint) = array_pad( list($needle, $textConstraint) = array_pad(
@ -89,7 +90,7 @@ class BaseDependencyCommand extends BaseCommand
); );
// Find packages that are or provide the requested package first // Find packages that are or provide the requested package first
$packages = $pool->whatProvides(strtolower($needle)); $packages = $repositorySet->findPackages(strtolower($needle)); // TODO this does not search providers
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));
} }

@ -28,6 +28,7 @@ use Composer\Repository\RepositoryFactory;
use Composer\Repository\CompositeRepository; use Composer\Repository\CompositeRepository;
use Composer\Repository\PlatformRepository; use Composer\Repository\PlatformRepository;
use Composer\Repository\InstalledFilesystemRepository; use Composer\Repository\InstalledFilesystemRepository;
use Composer\Repository\RepositorySet;
use Composer\Script\ScriptEvents; use Composer\Script\ScriptEvents;
use Composer\Util\Silencer; use Composer\Util\Silencer;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
@ -290,8 +291,8 @@ EOT
throw new \InvalidArgumentException('Invalid stability provided ('.$stability.'), must be one of: '.implode(', ', array_keys(BasePackage::$stabilities))); throw new \InvalidArgumentException('Invalid stability provided ('.$stability.'), must be one of: '.implode(', ', array_keys(BasePackage::$stabilities)));
} }
$pool = new Pool($stability); $repositorySet = new RepositorySet(new Pool($stability));
$pool->addRepository($sourceRepo); $repositorySet->addRepository($sourceRepo);
$phpVersion = null; $phpVersion = null;
$prettyPhpVersion = null; $prettyPhpVersion = null;
@ -305,7 +306,7 @@ EOT
} }
// find the latest version if there are multiple // find the latest version if there are multiple
$versionSelector = new VersionSelector($pool); $versionSelector = new VersionSelector($repositorySet);
$package = $versionSelector->findBestCandidate($name, $packageVersion, $phpVersion, $stability); $package = $versionSelector->findBestCandidate($name, $packageVersion, $phpVersion, $stability);
if (!$package) { if (!$package) {

@ -21,6 +21,7 @@ use Composer\Package\Version\VersionSelector;
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\RepositorySet;
use Composer\Util\ProcessExecutor; use Composer\Util\ProcessExecutor;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
@ -40,8 +41,8 @@ class InitCommand extends BaseCommand
/** @var array */ /** @var array */
private $gitConfig; private $gitConfig;
/** @var Pool[] */ /** @var RepositorySet[] */
private $pools; private $repositorySets;
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -637,16 +638,16 @@ EOT
return false !== filter_var($email, FILTER_VALIDATE_EMAIL); return false !== filter_var($email, FILTER_VALIDATE_EMAIL);
} }
private function getPool(InputInterface $input, $minimumStability = null) private function getRepositorySet(InputInterface $input, $minimumStability = null)
{ {
$key = $minimumStability ?: 'default'; $key = $minimumStability ?: 'default';
if (!isset($this->pools[$key])) { if (!isset($this->repositorySets[$key])) {
$this->pools[$key] = $pool = new Pool($minimumStability ?: $this->getMinimumStability($input)); $this->repositorySets[$key] = $repositorySet = new RepositorySet(new Pool($minimumStability ?: $this->getMinimumStability($input)));
$pool->addRepository($this->getRepos()); $repositorySet->addRepository($this->getRepos());
} }
return $this->pools[$key]; return $this->repositorySets[$key];
} }
private function getMinimumStability(InputInterface $input) private function getMinimumStability(InputInterface $input)
@ -681,8 +682,8 @@ EOT
*/ */
private function findBestVersionAndNameForPackage(InputInterface $input, $name, $phpVersion, $preferredStability = 'stable', $requiredVersion = null, $minimumStability = null) private function findBestVersionAndNameForPackage(InputInterface $input, $name, $phpVersion, $preferredStability = 'stable', $requiredVersion = null, $minimumStability = null)
{ {
// find the latest version allowed in this pool // find the latest version allowed in this repo set
$versionSelector = new VersionSelector($this->getPool($input, $minimumStability)); $versionSelector = new VersionSelector($this->getRepositorySet($input, $minimumStability));
$package = $versionSelector->findBestCandidate($name, $requiredVersion, $phpVersion, $preferredStability); $package = $versionSelector->findBestCandidate($name, $requiredVersion, $phpVersion, $preferredStability);
// retry without phpVersion if platform requirements are ignored in case nothing was found // retry without phpVersion if platform requirements are ignored in case nothing was found

@ -29,6 +29,7 @@ use Composer\Repository\CompositeRepository;
use Composer\Repository\PlatformRepository; use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryFactory; use Composer\Repository\RepositoryFactory;
use Composer\Repository\RepositoryInterface; use Composer\Repository\RepositoryInterface;
use Composer\Repository\RepositorySet;
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;
@ -52,8 +53,8 @@ class ShowCommand extends BaseCommand
protected $versionParser; protected $versionParser;
protected $colors; protected $colors;
/** @var Pool */ /** @var RepositorySet */
private $pool; private $repositorySet;
protected function configure() protected function configure()
{ {
@ -523,19 +524,13 @@ EOT
$constraint = is_string($version) ? $this->versionParser->parseConstraints($version) : $version; $constraint = is_string($version) ? $this->versionParser->parseConstraints($version) : $version;
$policy = new DefaultPolicy(); $policy = new DefaultPolicy();
$pool = new Pool('dev'); $repositorySet = new RepositorySet(new Pool('dev'));
$pool->addRepository($repos); $repositorySet->addRepository($repos);
$matchedPackage = null; $matchedPackage = null;
$versions = array(); $versions = array();
$matches = $pool->whatProvides($name, $constraint); $matches = $repositorySet->findPackages($name, $constraint);
foreach ($matches as $index => $package) { foreach ($matches as $index => $package) {
// skip providers/replacers
if ($package->getName() !== $name) {
unset($matches[$index]);
continue;
}
// select an exact match if it is in the installed repo and no specific version was required // select an exact match if it is in the installed repo and no specific version was required
if (null === $version && $installedRepo->hasPackage($package)) { if (null === $version && $installedRepo->hasPackage($package)) {
$matchedPackage = $package; $matchedPackage = $package;
@ -546,8 +541,8 @@ EOT
} }
// select preferred package according to policy rules // select preferred package according to policy rules
if (!$matchedPackage && $matches && $preferred = $policy->selectPreferredPackages($pool, array(), $matches)) { if (!$matchedPackage && $matches && $preferred = $policy->selectPreferredPackages($repositorySet->getPoolTemp(), array(), $matches)) { // TODO get rid of the pool call
$matchedPackage = $pool->literalToPackage($preferred[0]); $matchedPackage = $repositorySet->getPoolTemp()->literalToPackage($preferred[0]);
} }
return array($matchedPackage, $versions); return array($matchedPackage, $versions);
@ -961,9 +956,9 @@ EOT
*/ */
private function findLatestPackage(PackageInterface $package, Composer $composer, $phpVersion, $minorOnly = false) private function findLatestPackage(PackageInterface $package, Composer $composer, $phpVersion, $minorOnly = false)
{ {
// find the latest version allowed in this pool // find the latest version allowed in this repo set
$name = $package->getName(); $name = $package->getName();
$versionSelector = new VersionSelector($this->getPool($composer)); $versionSelector = new VersionSelector($this->getRepositorySet($composer));
$stability = $composer->getPackage()->getMinimumStability(); $stability = $composer->getPackage()->getMinimumStability();
$flags = $composer->getPackage()->getStabilityFlags(); $flags = $composer->getPackage()->getStabilityFlags();
if (isset($flags[$name])) { if (isset($flags[$name])) {
@ -987,13 +982,13 @@ EOT
return $versionSelector->findBestCandidate($name, $targetVersion, $phpVersion, $bestStability); return $versionSelector->findBestCandidate($name, $targetVersion, $phpVersion, $bestStability);
} }
private function getPool(Composer $composer) private function getRepositorySet(Composer $composer)
{ {
if (!$this->pool) { if (!$this->repositorySet) {
$this->pool = new Pool($composer->getPackage()->getMinimumStability(), $composer->getPackage()->getStabilityFlags()); $this->repositorySet = new RepositorySet(new Pool($composer->getPackage()->getMinimumStability(), $composer->getPackage()->getStabilityFlags()));
$this->pool->addRepository(new CompositeRepository($composer->getRepositoryManager()->getRepositories())); $this->repositorySet->addRepository(new CompositeRepository($composer->getRepositoryManager()->getRepositories()));
} }
return $this->pool; return $this->repositorySet;
} }
} }

@ -15,6 +15,7 @@ namespace Composer\DependencyResolver;
use Composer\Package\BasePackage; use Composer\Package\BasePackage;
use Composer\Package\AliasPackage; use Composer\Package\AliasPackage;
use Composer\Package\Version\VersionParser; use Composer\Package\Version\VersionParser;
use Composer\Repository\RepositorySet;
use Composer\Semver\Constraint\ConstraintInterface; use Composer\Semver\Constraint\ConstraintInterface;
use Composer\Semver\Constraint\Constraint; use Composer\Semver\Constraint\Constraint;
use Composer\Semver\Constraint\EmptyConstraint; use Composer\Semver\Constraint\EmptyConstraint;

@ -15,6 +15,7 @@ namespace Composer\DependencyResolver;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Repository\RepositoryInterface; use Composer\Repository\RepositoryInterface;
use Composer\Repository\PlatformRepository; use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositorySet;
/** /**
* @author Nils Adermann <naderman@naderman.de> * @author Nils Adermann <naderman@naderman.de>
@ -26,8 +27,8 @@ class Solver
/** @var PolicyInterface */ /** @var PolicyInterface */
protected $policy; protected $policy;
/** @var Pool */ /** @var RepositorySet */
protected $pool; protected $repositorySet = null;
/** @var RepositoryInterface */ /** @var RepositoryInterface */
protected $installed; protected $installed;
/** @var RuleSet */ /** @var RuleSet */
@ -36,6 +37,8 @@ class Solver
protected $ruleSetGenerator; protected $ruleSetGenerator;
/** @var array */ /** @var array */
protected $jobs; protected $jobs;
/** @var Pool */
protected $pool = null;
/** @var int[] */ /** @var int[] */
protected $updateMap = array(); protected $updateMap = array();
@ -62,17 +65,16 @@ class Solver
/** /**
* @param PolicyInterface $policy * @param PolicyInterface $policy
* @param Pool $pool * @param RepositorySet $repositorySet
* @param RepositoryInterface $installed * @param RepositoryInterface $installed
* @param IOInterface $io * @param IOInterface $io
*/ */
public function __construct(PolicyInterface $policy, Pool $pool, RepositoryInterface $installed, IOInterface $io) public function __construct(PolicyInterface $policy, RepositorySet $repositorySet, RepositoryInterface $installed, IOInterface $io)
{ {
$this->io = $io; $this->io = $io;
$this->policy = $policy; $this->policy = $policy;
$this->pool = $pool; $this->repositorySet = $repositorySet;
$this->installed = $installed; $this->installed = $installed;
$this->ruleSetGenerator = new RuleSetGenerator($policy, $pool);
} }
/** /**
@ -83,6 +85,11 @@ class Solver
return count($this->rules); return count($this->rules);
} }
public function getPool()
{
return $this->pool;
}
// aka solver_makeruledecisions // aka solver_makeruledecisions
private function makeAssertionRuleDecisions() private function makeAssertionRuleDecisions()
@ -210,7 +217,11 @@ class Solver
{ {
$this->jobs = $request->getJobs(); $this->jobs = $request->getJobs();
$this->pool = $this->repositorySet->createPool();
$this->setupInstalledMap(); $this->setupInstalledMap();
$this->ruleSetGenerator = new RuleSetGenerator($this->policy, $this->pool);
$this->rules = $this->ruleSetGenerator->getRulesFor($this->jobs, $this->installedMap, $ignorePlatformReqs); $this->rules = $this->ruleSetGenerator->getRulesFor($this->jobs, $this->installedMap, $ignorePlatformReqs);
$this->checkForRootRequireProblems($ignorePlatformReqs); $this->checkForRootRequireProblems($ignorePlatformReqs);
$this->decisions = new Decisions($this->pool); $this->decisions = new Decisions($this->pool);

@ -13,13 +13,13 @@
namespace Composer\EventDispatcher; namespace Composer\EventDispatcher;
use Composer\DependencyResolver\PolicyInterface; use Composer\DependencyResolver\PolicyInterface;
use Composer\DependencyResolver\Pool;
use Composer\DependencyResolver\Request; use Composer\DependencyResolver\Request;
use Composer\Installer\InstallerEvent; use Composer\Installer\InstallerEvent;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Composer; use Composer\Composer;
use Composer\DependencyResolver\Operation\OperationInterface; use Composer\DependencyResolver\Operation\OperationInterface;
use Composer\Repository\CompositeRepository; use Composer\Repository\CompositeRepository;
use Composer\Repository\RepositorySet;
use Composer\Script; use Composer\Script;
use Composer\Installer\PackageEvent; use Composer\Installer\PackageEvent;
use Composer\Installer\BinaryInstaller; use Composer\Installer\BinaryInstaller;
@ -102,7 +102,7 @@ class EventDispatcher
* @param string $eventName The constant in PackageEvents * @param string $eventName The constant in PackageEvents
* @param bool $devMode Whether or not we are in dev mode * @param bool $devMode Whether or not we are in dev mode
* @param PolicyInterface $policy The policy * @param PolicyInterface $policy The policy
* @param Pool $pool The pool * @param RepositorySet $repositorySet The repository set
* @param CompositeRepository $installedRepo The installed repository * @param CompositeRepository $installedRepo The installed repository
* @param Request $request The request * @param Request $request The request
* @param array $operations The list of operations * @param array $operations The list of operations
@ -111,9 +111,9 @@ class EventDispatcher
* @return int return code of the executed script if any, for php scripts a false return * @return int return code of the executed script if any, for php scripts a false return
* value is changed to 1, anything else to 0 * value is changed to 1, anything else to 0
*/ */
public function dispatchPackageEvent($eventName, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations, OperationInterface $operation) public function dispatchPackageEvent($eventName, $devMode, PolicyInterface $policy, RepositorySet $repositorySet, CompositeRepository $installedRepo, Request $request, array $operations, OperationInterface $operation)
{ {
return $this->doDispatch(new PackageEvent($eventName, $this->composer, $this->io, $devMode, $policy, $pool, $installedRepo, $request, $operations, $operation)); return $this->doDispatch(new PackageEvent($eventName, $this->composer, $this->io, $devMode, $policy, $repositorySet, $installedRepo, $request, $operations, $operation));
} }
/** /**
@ -122,7 +122,7 @@ class EventDispatcher
* @param string $eventName The constant in InstallerEvents * @param string $eventName The constant in InstallerEvents
* @param bool $devMode Whether or not we are in dev mode * @param bool $devMode Whether or not we are in dev mode
* @param PolicyInterface $policy The policy * @param PolicyInterface $policy The policy
* @param Pool $pool The pool * @param RepositorySet $repositorySet The repository set
* @param CompositeRepository $installedRepo The installed repository * @param CompositeRepository $installedRepo The installed repository
* @param Request $request The request * @param Request $request The request
* @param array $operations The list of operations * @param array $operations The list of operations
@ -130,9 +130,9 @@ class EventDispatcher
* @return int return code of the executed script if any, for php scripts a false return * @return int return code of the executed script if any, for php scripts a false return
* value is changed to 1, anything else to 0 * value is changed to 1, anything else to 0
*/ */
public function dispatchInstallerEvent($eventName, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations = array()) public function dispatchInstallerEvent($eventName, $devMode, PolicyInterface $policy, RepositorySet $repositorySet, CompositeRepository $installedRepo, Request $request, array $operations = array())
{ {
return $this->doDispatch(new InstallerEvent($eventName, $this->composer, $this->io, $devMode, $policy, $pool, $installedRepo, $request, $operations)); return $this->doDispatch(new InstallerEvent($eventName, $this->composer, $this->io, $devMode, $policy, $repositorySet, $installedRepo, $request, $operations));
} }
/** /**
@ -340,7 +340,7 @@ class EventDispatcher
$event->getIO(), $event->getIO(),
$event->isDevMode(), $event->isDevMode(),
$event->getPolicy(), $event->getPolicy(),
$event->getPool(), $event->getRepositorySet(),
$event->getInstalledRepo(), $event->getInstalledRepo(),
$event->getRequest(), $event->getRequest(),
$event->getOperations(), $event->getOperations(),

@ -37,6 +37,7 @@ use Composer\Package\CompletePackage;
use Composer\Package\Link; use Composer\Package\Link;
use Composer\Package\Loader\ArrayLoader; use Composer\Package\Loader\ArrayLoader;
use Composer\Package\Dumper\ArrayDumper; use Composer\Package\Dumper\ArrayDumper;
use Composer\Repository\RepositorySet;
use Composer\Semver\Constraint\Constraint; use Composer\Semver\Constraint\Constraint;
use Composer\Package\Locker; use Composer\Package\Locker;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
@ -368,21 +369,21 @@ class Installer
$this->io->writeError('<info>Loading composer repositories with package information</info>'); $this->io->writeError('<info>Loading composer repositories with package information</info>');
// creating repository pool // creating repository set
$policy = $this->createPolicy(); $policy = $this->createPolicy();
$pool = $this->createPool($this->update ? null : $lockedRepository); $repositorySet = $this->createRepositorySet($this->update ? null : $lockedRepository);
$pool->addRepository($installedRepo, $aliases); $repositorySet->addRepository($installedRepo, $aliases);
if ($this->update) { if ($this->update) {
$repositories = $this->repositoryManager->getRepositories(); $repositories = $this->repositoryManager->getRepositories();
foreach ($repositories as $repository) { foreach ($repositories as $repository) {
$pool->addRepository($repository, $aliases); $repositorySet->addRepository($repository, $aliases);
} }
} }
// Add the locked repository after the others in case we are doing a // Add the locked repository after the others in case we are doing a
// partial update so missing packages can be found there still. // partial update so missing packages can be found there still.
// For installs from lock it's the only one added so it is first // For installs from lock it's the only one added so it is first
if ($lockedRepository) { if ($lockedRepository) {
$pool->addRepository($lockedRepository, $aliases); $repositorySet->addRepository($lockedRepository, $aliases);
} }
// creating requirements request // creating requirements request
@ -393,7 +394,7 @@ class Installer
$removedUnstablePackages = array(); $removedUnstablePackages = array();
foreach ($localRepo->getPackages() as $package) { foreach ($localRepo->getPackages() as $package) {
if ( if (
!$pool->isPackageAcceptable($package->getNames(), $package->getStability()) !$repositorySet->isPackageAcceptable($package->getNames(), $package->getStability())
&& $this->installationManager->isPackageInstalled($localRepo, $package) && $this->installationManager->isPackageInstalled($localRepo, $package)
) { ) {
$removedUnstablePackages[$package->getName()] = true; $removedUnstablePackages[$package->getName()] = true;
@ -465,11 +466,11 @@ class Installer
} }
// force dev packages to have the latest links if we update or install from a (potentially new) lock // force dev packages to have the latest links if we update or install from a (potentially new) lock
$this->processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, 'force-links'); $this->processDevPackages($localRepo, $repositorySet, $policy, $repositories, $installedRepo, $lockedRepository, 'force-links');
// solve dependencies // solve dependencies
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, $this->devMode, $policy, $pool, $installedRepo, $request); $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, $this->devMode, $policy, $repositorySet, $installedRepo, $request);
$solver = new Solver($policy, $pool, $installedRepo, $this->io); $solver = new Solver($policy, $repositorySet, $installedRepo, $this->io);
try { try {
$operations = $solver->solve($request, $this->ignorePlatformReqs); $operations = $solver->solve($request, $this->ignorePlatformReqs);
} catch (SolverProblemsException $e) { } catch (SolverProblemsException $e) {
@ -483,11 +484,10 @@ class Installer
} }
// force dev packages to be updated if we update or install from a (potentially new) lock // force dev packages to be updated if we update or install from a (potentially new) lock
$operations = $this->processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, 'force-updates', $operations); $operations = $this->processDevPackages($localRepo, $repositorySet, $policy, $repositories, $installedRepo, $lockedRepository, 'force-updates', $operations);
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, $this->devMode, $policy, $pool, $installedRepo, $request, $operations); $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, $this->devMode, $policy, $repositorySet, $installedRepo, $request, $operations);
$this->io->writeError("Analyzed ".count($pool)." packages to resolve dependencies", true, IOInterface::VERBOSE);
$this->io->writeError("Analyzed ".$solver->getRuleSetSize()." rules to resolve dependencies", true, IOInterface::VERBOSE); $this->io->writeError("Analyzed ".$solver->getRuleSetSize()." rules to resolve dependencies", true, IOInterface::VERBOSE);
// execute operations // execute operations
@ -581,7 +581,7 @@ class Installer
$event = 'Composer\Installer\PackageEvents::PRE_PACKAGE_'.strtoupper($jobType); $event = 'Composer\Installer\PackageEvents::PRE_PACKAGE_'.strtoupper($jobType);
if (defined($event) && $this->runScripts) { if (defined($event) && $this->runScripts) {
$this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $policy, $pool, $installedRepo, $request, $operations, $operation); $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $policy, $repositorySet, $installedRepo, $request, $operations, $operation);
} }
// output non-alias ops when not executing operations (i.e. dry run), output alias ops in debug verbosity // output non-alias ops when not executing operations (i.e. dry run), output alias ops in debug verbosity
@ -599,11 +599,11 @@ class Installer
if ($reason instanceof Rule) { if ($reason instanceof Rule) {
switch ($reason->getReason()) { switch ($reason->getReason()) {
case Rule::RULE_JOB_INSTALL: case Rule::RULE_JOB_INSTALL:
$this->io->writeError(' REASON: Required by the root package: '.$reason->getPrettyString($pool)); $this->io->writeError(' REASON: Required by the root package: '.$reason->getPrettyString($solver->getPool()));
$this->io->writeError(''); $this->io->writeError('');
break; break;
case Rule::RULE_PACKAGE_REQUIRES: case Rule::RULE_PACKAGE_REQUIRES:
$this->io->writeError(' REASON: '.$reason->getPrettyString($pool)); $this->io->writeError(' REASON: '.$reason->getPrettyString($solver->getPool()));
$this->io->writeError(''); $this->io->writeError('');
break; break;
} }
@ -612,7 +612,7 @@ class Installer
$event = 'Composer\Installer\PackageEvents::POST_PACKAGE_'.strtoupper($jobType); $event = 'Composer\Installer\PackageEvents::POST_PACKAGE_'.strtoupper($jobType);
if (defined($event) && $this->runScripts) { if (defined($event) && $this->runScripts) {
$this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $policy, $pool, $installedRepo, $request, $operations, $operation); $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $policy, $repositorySet, $installedRepo, $request, $operations, $operation);
} }
if ($this->executeOperations || $this->writeLock) { if ($this->executeOperations || $this->writeLock) {
@ -622,7 +622,7 @@ class Installer
if ($this->executeOperations) { if ($this->executeOperations) {
// force source/dist urls to be updated for all packages // force source/dist urls to be updated for all packages
$this->processPackageUrls($pool, $policy, $localRepo, $repositories); $this->processPackageUrls($repositorySet, $policy, $localRepo, $repositories);
$localRepo->write(); $localRepo->write();
} }
@ -685,9 +685,9 @@ class Installer
unset($tempLocalRepo, $loader, $dumper); unset($tempLocalRepo, $loader, $dumper);
$policy = $this->createPolicy(); $policy = $this->createPolicy();
$pool = $this->createPool(); $repositorySet = $this->createRepositorySet();
$installedRepo = $this->createInstalledRepo($localRepo, $platformRepo); $installedRepo = $this->createInstalledRepo($localRepo, $platformRepo);
$pool->addRepository($installedRepo, $aliases); $repositorySet->addRepository($installedRepo, $aliases);
// creating requirements request without dev requirements // creating requirements request without dev requirements
$request = $this->createRequest($this->package, $platformRepo); $request = $this->createRequest($this->package, $platformRepo);
@ -697,10 +697,10 @@ class Installer
} }
// solve deps to see which get removed // solve deps to see which get removed
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, false, $policy, $pool, $installedRepo, $request); $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, false, $policy, $repositorySet, $installedRepo, $request);
$solver = new Solver($policy, $pool, $installedRepo, $this->io); $solver = new Solver($policy, $repositorySet, $installedRepo, $this->io);
$ops = $solver->solve($request, $this->ignorePlatformReqs); $ops = $solver->solve($request, $this->ignorePlatformReqs);
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, false, $policy, $pool, $installedRepo, $request, $ops); $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, false, $policy, $repositorySet, $installedRepo, $request, $ops);
$devPackages = array(); $devPackages = array();
foreach ($ops as $op) { foreach ($ops as $op) {
@ -844,6 +844,12 @@ class Installer
return $installedRepo; return $installedRepo;
} }
private function createRepositorySet($lockedRepository = null)
{
$pool = $this->createPool($lockedRepository);
return new RepositorySet($pool);
}
/** /**
* @param RepositoryInterface|null $lockedRepository * @param RepositoryInterface|null $lockedRepository
* @return Pool * @return Pool
@ -946,7 +952,7 @@ class Installer
/** /**
* @param WritableRepositoryInterface $localRepo * @param WritableRepositoryInterface $localRepo
* @param Pool $pool * @param RepositorySet $repositorySet
* @param PolicyInterface $policy * @param PolicyInterface $policy
* @param array $repositories * @param array $repositories
* @param RepositoryInterface $installedRepo * @param RepositoryInterface $installedRepo
@ -955,7 +961,7 @@ class Installer
* @param array|null $operations * @param array|null $operations
* @return array * @return array
*/ */
private function processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, $task, array $operations = null) private function processDevPackages($localRepo, $repositorySet, $policy, $repositories, $installedRepo, $lockedRepository, $task, array $operations = null)
{ {
if ($task === 'force-updates' && null === $operations) { if ($task === 'force-updates' && null === $operations) {
throw new \InvalidArgumentException('Missing operations argument'); throw new \InvalidArgumentException('Missing operations argument');
@ -1010,7 +1016,7 @@ class Installer
} }
// find similar packages (name/version) in all repositories // find similar packages (name/version) in all repositories
$matches = $pool->whatProvides($package->getName(), new Constraint('=', $package->getVersion())); $matches = $repositorySet->findPackages($package->getName(), new Constraint('=', $package->getVersion()));
foreach ($matches as $index => $match) { foreach ($matches as $index => $match) {
// skip local packages // skip local packages
if (!in_array($match->getRepository(), $repositories, true)) { if (!in_array($match->getRepository(), $repositories, true)) {
@ -1018,18 +1024,12 @@ class Installer
continue; continue;
} }
// skip providers/replacers
if ($match->getName() !== $package->getName()) {
unset($matches[$index]);
continue;
}
$matches[$index] = $match->getId(); $matches[$index] = $match->getId();
} }
// select preferred package according to policy rules // select preferred package according to policy rules
if ($matches && $matches = $policy->selectPreferredPackages($pool, array(), $matches)) { if ($matches && $matches = $policy->selectPreferredPackages($repositorySet->getPoolTemp(), array(), $matches)) { // TODO remove temp call
$newPackage = $pool->literalToPackage($matches[0]); $newPackage = $repositorySet->getPoolTemp()->literalToPackage($matches[0]);
if ($task === 'force-links' && $newPackage) { if ($task === 'force-links' && $newPackage) {
$package->setRequires($newPackage->getRequires()); $package->setRequires($newPackage->getRequires());
@ -1130,12 +1130,12 @@ class Installer
} }
/** /**
* @param Pool $pool * @param RepositorySet $repositorySet
* @param PolicyInterface $policy * @param PolicyInterface $policy
* @param WritableRepositoryInterface $localRepo * @param WritableRepositoryInterface $localRepo
* @param array $repositories * @param array $repositories
*/ */
private function processPackageUrls($pool, $policy, $localRepo, $repositories) private function processPackageUrls($repositorySet, $policy, $localRepo, $repositories)
{ {
if (!$this->update) { if (!$this->update) {
return; return;
@ -1145,7 +1145,7 @@ class Installer
foreach ($localRepo->getCanonicalPackages() as $package) { foreach ($localRepo->getCanonicalPackages() as $package) {
// find similar packages (name/version) in all repositories // find similar packages (name/version) in all repositories
$matches = $pool->whatProvides($package->getName(), new Constraint('=', $package->getVersion())); $matches = $repositorySet->findPackages($package->getName(), new Constraint('=', $package->getVersion()));
foreach ($matches as $index => $match) { foreach ($matches as $index => $match) {
// skip local packages // skip local packages
if (!in_array($match->getRepository(), $repositories, true)) { if (!in_array($match->getRepository(), $repositories, true)) {
@ -1153,18 +1153,12 @@ class Installer
continue; continue;
} }
// skip providers/replacers
if ($match->getName() !== $package->getName()) {
unset($matches[$index]);
continue;
}
$matches[$index] = $match->getId(); $matches[$index] = $match->getId();
} }
// select preferred package according to policy rules // select preferred package according to policy rules
if ($matches && $matches = $policy->selectPreferredPackages($pool, array(), $matches)) { if ($matches && $matches = $policy->selectPreferredPackages($repositorySet->getPoolTemp(), array(), $matches)) { // TODO get rid of pool
$newPackage = $pool->literalToPackage($matches[0]); $newPackage = $repositorySet->getPoolTemp()->literalToPackage($matches[0]);
// update the dist and source URLs // update the dist and source URLs
$sourceUrl = $package->getSourceUrl(); $sourceUrl = $package->getSourceUrl();
@ -1325,8 +1319,8 @@ class Installer
} }
} }
$pool = new Pool('dev'); $repositorySet = new RepositorySet(new Pool('dev'));
$pool->addRepository($localOrLockRepo); $repositorySet->addRepository($localOrLockRepo);
$seen = array(); $seen = array();
@ -1335,7 +1329,7 @@ class Installer
foreach ($this->updateWhitelist as $packageName => $void) { foreach ($this->updateWhitelist as $packageName => $void) {
$packageQueue = new \SplQueue; $packageQueue = new \SplQueue;
$depPackages = $pool->whatProvides($packageName); $depPackages = $repositorySet->findPackages($packageName); // TODO does this need replacers/providers?
$nameMatchesRequiredPackage = in_array($packageName, $requiredPackageNames, true); $nameMatchesRequiredPackage = in_array($packageName, $requiredPackageNames, true);
@ -1374,7 +1368,7 @@ class Installer
$requires = $package->getRequires(); $requires = $package->getRequires();
foreach ($requires as $require) { foreach ($requires as $require) {
$requirePackages = $pool->whatProvides($require->getTarget()); $requirePackages = $repositorySet->findPackages($require->getTarget()); // TODO does this need replacers/providers?
foreach ($requirePackages as $requirePackage) { foreach ($requirePackages as $requirePackage) {
if (isset($this->updateWhitelist[$requirePackage->getName()])) { if (isset($this->updateWhitelist[$requirePackage->getName()])) {

@ -15,11 +15,11 @@ namespace Composer\Installer;
use Composer\Composer; use Composer\Composer;
use Composer\DependencyResolver\PolicyInterface; use Composer\DependencyResolver\PolicyInterface;
use Composer\DependencyResolver\Operation\OperationInterface; use Composer\DependencyResolver\Operation\OperationInterface;
use Composer\DependencyResolver\Pool;
use Composer\DependencyResolver\Request; use Composer\DependencyResolver\Request;
use Composer\EventDispatcher\Event; use Composer\EventDispatcher\Event;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Repository\CompositeRepository; use Composer\Repository\CompositeRepository;
use Composer\Repository\RepositorySet;
/** /**
* An event for all installer. * An event for all installer.
@ -49,9 +49,9 @@ class InstallerEvent extends Event
private $policy; private $policy;
/** /**
* @var Pool * @var RepositorySet
*/ */
private $pool; private $repositorySet;
/** /**
* @var CompositeRepository * @var CompositeRepository
@ -76,12 +76,12 @@ class InstallerEvent extends Event
* @param IOInterface $io * @param IOInterface $io
* @param bool $devMode * @param bool $devMode
* @param PolicyInterface $policy * @param PolicyInterface $policy
* @param Pool $pool * @param RepositorySet $repositorySet
* @param CompositeRepository $installedRepo * @param CompositeRepository $installedRepo
* @param Request $request * @param Request $request
* @param OperationInterface[] $operations * @param OperationInterface[] $operations
*/ */
public function __construct($eventName, Composer $composer, IOInterface $io, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations = array()) public function __construct($eventName, Composer $composer, IOInterface $io, $devMode, PolicyInterface $policy, RepositorySet $repositorySet, CompositeRepository $installedRepo, Request $request, array $operations = array())
{ {
parent::__construct($eventName); parent::__construct($eventName);
@ -89,7 +89,7 @@ class InstallerEvent extends Event
$this->io = $io; $this->io = $io;
$this->devMode = $devMode; $this->devMode = $devMode;
$this->policy = $policy; $this->policy = $policy;
$this->pool = $pool; $this->repositorySet = $repositorySet;
$this->installedRepo = $installedRepo; $this->installedRepo = $installedRepo;
$this->request = $request; $this->request = $request;
$this->operations = $operations; $this->operations = $operations;
@ -128,11 +128,11 @@ class InstallerEvent extends Event
} }
/** /**
* @return Pool * @return RepositorySet
*/ */
public function getPool() public function getRepositorySet()
{ {
return $this->pool; return $this->repositorySet;
} }
/** /**

@ -16,7 +16,6 @@ use Composer\Composer;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\DependencyResolver\Operation\OperationInterface; use Composer\DependencyResolver\Operation\OperationInterface;
use Composer\DependencyResolver\PolicyInterface; use Composer\DependencyResolver\PolicyInterface;
use Composer\DependencyResolver\Pool;
use Composer\DependencyResolver\Request; use Composer\DependencyResolver\Request;
use Composer\Repository\CompositeRepository; use Composer\Repository\CompositeRepository;
@ -40,15 +39,15 @@ class PackageEvent extends InstallerEvent
* @param IOInterface $io * @param IOInterface $io
* @param bool $devMode * @param bool $devMode
* @param PolicyInterface $policy * @param PolicyInterface $policy
* @param Pool $pool * @param RepositorySet $repositorySet
* @param CompositeRepository $installedRepo * @param CompositeRepository $installedRepo
* @param Request $request * @param Request $request
* @param OperationInterface[] $operations * @param OperationInterface[] $operations
* @param OperationInterface $operation * @param OperationInterface $operation
*/ */
public function __construct($eventName, Composer $composer, IOInterface $io, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations, OperationInterface $operation) public function __construct($eventName, Composer $composer, IOInterface $io, $devMode, PolicyInterface $policy, RepositorySet $repositorySet, CompositeRepository $installedRepo, Request $request, array $operations, OperationInterface $operation)
{ {
parent::__construct($eventName, $composer, $io, $devMode, $policy, $pool, $installedRepo, $request, $operations); parent::__construct($eventName, $composer, $io, $devMode, $policy, $repositorySet, $installedRepo, $request, $operations);
$this->operation = $operation; $this->operation = $operation;
} }

@ -17,6 +17,7 @@ use Composer\Package\BasePackage;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Package\Loader\ArrayLoader; use Composer\Package\Loader\ArrayLoader;
use Composer\Package\Dumper\ArrayDumper; use Composer\Package\Dumper\ArrayDumper;
use Composer\Repository\RepositorySet;
use Composer\Semver\Constraint\Constraint; use Composer\Semver\Constraint\Constraint;
/** /**
@ -27,13 +28,13 @@ use Composer\Semver\Constraint\Constraint;
*/ */
class VersionSelector class VersionSelector
{ {
private $pool; private $repositorySet;
private $parser; private $parser;
public function __construct(Pool $pool) public function __construct(RepositorySet $repositorySet)
{ {
$this->pool = $pool; $this->repositorySet = $repositorySet;
} }
/** /**
@ -49,7 +50,7 @@ class VersionSelector
public function findBestCandidate($packageName, $targetPackageVersion = null, $targetPhpVersion = null, $preferredStability = 'stable') public function findBestCandidate($packageName, $targetPackageVersion = null, $targetPhpVersion = null, $preferredStability = 'stable')
{ {
$constraint = $targetPackageVersion ? $this->getParser()->parseConstraints($targetPackageVersion) : null; $constraint = $targetPackageVersion ? $this->getParser()->parseConstraints($targetPackageVersion) : null;
$candidates = $this->pool->whatProvides(strtolower($packageName), $constraint, true); $candidates = $this->repositorySet->findPackages(strtolower($packageName), $constraint);
if ($targetPhpVersion) { if ($targetPhpVersion) {
$phpConstraint = new Constraint('==', $this->getParser()->normalize($targetPhpVersion)); $phpConstraint = new Constraint('==', $this->getParser()->normalize($targetPhpVersion));

@ -27,7 +27,7 @@ interface PluginInterface
* *
* @var string * @var string
*/ */
const PLUGIN_API_VERSION = '1.1.0'; const PLUGIN_API_VERSION = '2.0.0';
/** /**
* Apply plugin modifications to Composer * Apply plugin modifications to Composer

@ -21,6 +21,7 @@ use Composer\Repository\RepositoryInterface;
use Composer\Package\AliasPackage; use Composer\Package\AliasPackage;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Package\Link; use Composer\Package\Link;
use Composer\Repository\RepositorySet;
use Composer\Semver\Constraint\Constraint; use Composer\Semver\Constraint\Constraint;
use Composer\DependencyResolver\Pool; use Composer\DependencyResolver\Pool;
use Composer\Plugin\Capability\Capability; use Composer\Plugin\Capability\Capability;
@ -157,14 +158,14 @@ 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;
$pool = new Pool('dev'); $repositorySet = new RepositorySet(new Pool('dev'));
$pool->addRepository($localRepo); $repositorySet->addRepository($localRepo);
if ($globalRepo) { if ($globalRepo) {
$pool->addRepository($globalRepo); $repositorySet->addRepository($globalRepo);
} }
$autoloadPackages = array($package->getName() => $package); $autoloadPackages = array($package->getName() => $package);
$autoloadPackages = $this->collectDependencies($pool, $autoloadPackages, $package); $autoloadPackages = $this->collectDependencies($repositorySet, $autoloadPackages, $package);
$generator = $this->composer->getAutoloadGenerator(); $generator = $this->composer->getAutoloadGenerator();
$autoloads = array(); $autoloads = array();
@ -269,13 +270,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 Pool $pool Package pool of installed packages * @param RepositorySet $repositorySet Repository set of installed packages
* @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(Pool $pool, array $collected, PackageInterface $package) private function collectDependencies(RepositorySet $repositorySet, array $collected, PackageInterface $package)
{ {
$requires = array_merge( $requires = array_merge(
$package->getRequires(), $package->getRequires(),
@ -283,10 +284,10 @@ class PluginManager
); );
foreach ($requires as $requireLink) { foreach ($requires as $requireLink) {
$requiredPackage = $this->lookupInstalledPackage($pool, $requireLink); $requiredPackage = $this->lookupInstalledPackage($repositorySet, $requireLink);
if ($requiredPackage && !isset($collected[$requiredPackage->getName()])) { if ($requiredPackage && !isset($collected[$requiredPackage->getName()])) {
$collected[$requiredPackage->getName()] = $requiredPackage; $collected[$requiredPackage->getName()] = $requiredPackage;
$collected = $this->collectDependencies($pool, $collected, $requiredPackage); $collected = $this->collectDependencies($repositorySet, $collected, $requiredPackage);
} }
} }
@ -294,18 +295,18 @@ class PluginManager
} }
/** /**
* Resolves a package link to a package in the installed pool * Resolves a package link to a package in the installed repo set
* *
* Since dependencies are already installed this should always find one. * Since dependencies are already installed this should always find one.
* *
* @param Pool $pool Pool of installed packages only * @param RepositorySet $repositorySet Repository set of installed packages only
* @param Link $link Package link to look up * @param Link $link Package link to look up
* *
* @return PackageInterface|null The found package * @return PackageInterface|null The found package
*/ */
private function lookupInstalledPackage(Pool $pool, Link $link) private function lookupInstalledPackage(RepositorySet $repositorySet, Link $link)
{ {
$packages = $pool->whatProvides($link->getTarget(), $link->getConstraint()); $packages = $repositorySet->findPackages($link->getTarget(), $link->getConstraint()); // TODO this no longer returns providers
return !empty($packages) ? $packages[0] : null; return !empty($packages) ? $packages[0] : null;
} }

@ -0,0 +1,59 @@
<?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\Repository;
use Composer\DependencyResolver\Pool;
use Composer\Package\BasePackage;
use Composer\Package\Version\VersionParser;
use Composer\Repository\CompositeRepository;
use Composer\Repository\PlatformRepository;
use Composer\Semver\Constraint\ConstraintInterface;
/**
* @author Nils Adermann <naderman@naderman.de>
*/
class RepositorySet
{
private $pool;
public function __construct(Pool $pool)
{
$this->pool = $pool;
}
public function addRepository(RepositoryInterface $repo, $rootAliases = array())
{
return $this->pool->addRepository($repo, $rootAliases);
}
public function isPackageAcceptable($name, $stability)
{
return $this->pool->isPackageAcceptable($name, $stability);
}
public function findPackages($name, ConstraintInterface $constraint = null)
{
return $this->pool->whatProvides($name, $constraint, true);
}
public function createPool()
{
return $this->pool;
}
// TODO get rid of this function
public function getPoolTemp()
{
return $this->pool;
}
}

@ -20,12 +20,13 @@ use Composer\DependencyResolver\Request;
use Composer\DependencyResolver\Solver; use Composer\DependencyResolver\Solver;
use Composer\DependencyResolver\SolverProblemsException; use Composer\DependencyResolver\SolverProblemsException;
use Composer\Package\Link; use Composer\Package\Link;
use Composer\Repository\RepositorySet;
use Composer\TestCase; use Composer\TestCase;
use Composer\Semver\Constraint\MultiConstraint; use Composer\Semver\Constraint\MultiConstraint;
class SolverTest extends TestCase class SolverTest extends TestCase
{ {
protected $pool; protected $repoSet;
protected $repo; protected $repo;
protected $repoInstalled; protected $repoInstalled;
protected $request; protected $request;
@ -33,13 +34,13 @@ class SolverTest extends TestCase
public function setUp() public function setUp()
{ {
$this->pool = new Pool; $this->repoSet = new RepositorySet(new Pool);
$this->repo = new ArrayRepository; $this->repo = new ArrayRepository;
$this->repoInstalled = new ArrayRepository; $this->repoInstalled = new ArrayRepository;
$this->request = new Request($this->pool); $this->request = new Request($this->repoSet);
$this->policy = new DefaultPolicy; $this->policy = new DefaultPolicy;
$this->solver = new Solver($this->policy, $this->pool, $this->repoInstalled, new NullIO()); $this->solver = new Solver($this->policy, $this->repoSet, $this->repoInstalled, new NullIO());
} }
public function testSolverInstallSingle() public function testSolverInstallSingle()
@ -90,9 +91,9 @@ class SolverTest extends TestCase
$repo1->addPackage($foo1 = $this->getPackage('foo', '1')); $repo1->addPackage($foo1 = $this->getPackage('foo', '1'));
$repo2->addPackage($foo2 = $this->getPackage('foo', '1')); $repo2->addPackage($foo2 = $this->getPackage('foo', '1'));
$this->pool->addRepository($this->repoInstalled); $this->repoSet->addRepository($this->repoInstalled);
$this->pool->addRepository($repo1); $this->repoSet->addRepository($repo1);
$this->pool->addRepository($repo2); $this->repoSet->addRepository($repo2);
$this->request->install('foo'); $this->request->install('foo');
@ -839,8 +840,8 @@ class SolverTest extends TestCase
protected function reposComplete() protected function reposComplete()
{ {
$this->pool->addRepository($this->repoInstalled); $this->repoSet->addRepository($this->repoInstalled);
$this->pool->addRepository($this->repo); $this->repoSet->addRepository($this->repo);
} }
protected function checkSolverResult(array $expected) protected function checkSolverResult(array $expected)

@ -411,12 +411,12 @@ class EventDispatcherTest extends TestCase
->will($this->returnValue(array())); ->will($this->returnValue(array()));
$policy = $this->getMockBuilder('Composer\DependencyResolver\PolicyInterface')->getMock(); $policy = $this->getMockBuilder('Composer\DependencyResolver\PolicyInterface')->getMock();
$pool = $this->getMockBuilder('Composer\DependencyResolver\Pool')->disableOriginalConstructor()->getMock(); $repositorySet = $this->getMockBuilder('Composer\Repository\RepositorySet')->disableOriginalConstructor()->getMock();
$installedRepo = $this->getMockBuilder('Composer\Repository\CompositeRepository')->disableOriginalConstructor()->getMock(); $installedRepo = $this->getMockBuilder('Composer\Repository\CompositeRepository')->disableOriginalConstructor()->getMock();
$request = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock(); $request = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock();
$dispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, true, $policy, $pool, $installedRepo, $request); $dispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, true, $policy, $repositorySet, $installedRepo, $request);
$dispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, true, $policy, $pool, $installedRepo, $request, array()); $dispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, true, $policy, $repositorySet, $installedRepo, $request, array());
} }
public static function call() public static function call()

@ -22,18 +22,18 @@ class InstallerEventTest extends TestCase
$composer = $this->getMockBuilder('Composer\Composer')->getMock(); $composer = $this->getMockBuilder('Composer\Composer')->getMock();
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
$policy = $this->getMockBuilder('Composer\DependencyResolver\PolicyInterface')->getMock(); $policy = $this->getMockBuilder('Composer\DependencyResolver\PolicyInterface')->getMock();
$pool = $this->getMockBuilder('Composer\DependencyResolver\Pool')->disableOriginalConstructor()->getMock(); $repositorySet = $this->getMockBuilder('Composer\Repository\RepositorySet')->disableOriginalConstructor()->getMock();
$installedRepo = $this->getMockBuilder('Composer\Repository\CompositeRepository')->disableOriginalConstructor()->getMock(); $installedRepo = $this->getMockBuilder('Composer\Repository\CompositeRepository')->disableOriginalConstructor()->getMock();
$request = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock(); $request = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock();
$operations = array($this->getMockBuilder('Composer\DependencyResolver\Operation\OperationInterface')->getMock()); $operations = array($this->getMockBuilder('Composer\DependencyResolver\Operation\OperationInterface')->getMock());
$event = new InstallerEvent('EVENT_NAME', $composer, $io, true, $policy, $pool, $installedRepo, $request, $operations); $event = new InstallerEvent('EVENT_NAME', $composer, $io, true, $policy, $repositorySet, $installedRepo, $request, $operations);
$this->assertSame('EVENT_NAME', $event->getName()); $this->assertSame('EVENT_NAME', $event->getName());
$this->assertInstanceOf('Composer\Composer', $event->getComposer()); $this->assertInstanceOf('Composer\Composer', $event->getComposer());
$this->assertInstanceOf('Composer\IO\IOInterface', $event->getIO()); $this->assertInstanceOf('Composer\IO\IOInterface', $event->getIO());
$this->assertTrue($event->isDevMode()); $this->assertTrue($event->isDevMode());
$this->assertInstanceOf('Composer\DependencyResolver\PolicyInterface', $event->getPolicy()); $this->assertInstanceOf('Composer\DependencyResolver\PolicyInterface', $event->getPolicy());
$this->assertInstanceOf('Composer\DependencyResolver\Pool', $event->getPool()); $this->assertInstanceOf('Composer\Repository\RepositorySet', $event->getRepositorySet());
$this->assertInstanceOf('Composer\Repository\CompositeRepository', $event->getInstalledRepo()); $this->assertInstanceOf('Composer\Repository\CompositeRepository', $event->getInstalledRepo());
$this->assertInstanceOf('Composer\DependencyResolver\Request', $event->getRequest()); $this->assertInstanceOf('Composer\DependencyResolver\Request', $event->getRequest());
$this->assertCount(1, $event->getOperations()); $this->assertCount(1, $event->getOperations());

@ -21,7 +21,7 @@ use PHPUnit\Framework\TestCase;
class VersionSelectorTest extends TestCase class VersionSelectorTest extends TestCase
{ {
// A) multiple versions, get the latest one // A) multiple versions, get the latest one
// B) targetPackageVersion will pass to pool // B) targetPackageVersion will pass to repo set
// C) No results, throw exception // C) No results, throw exception
public function testLatestVersionIsReturned() public function testLatestVersionIsReturned()
@ -33,13 +33,13 @@ class VersionSelectorTest extends TestCase
$package3 = $this->createPackage('1.2.0'); $package3 = $this->createPackage('1.2.0');
$packages = array($package1, $package2, $package3); $packages = array($package1, $package2, $package3);
$pool = $this->createMockPool(); $repositorySet = $this->createMockRepositorySet();
$pool->expects($this->once()) $repositorySet->expects($this->once())
->method('whatProvides') ->method('findPackages')
->with($packageName, null, true) ->with($packageName, null)
->will($this->returnValue($packages)); ->will($this->returnValue($packages));
$versionSelector = new VersionSelector($pool); $versionSelector = new VersionSelector($repositorySet);
$best = $versionSelector->findBestCandidate($packageName); $best = $versionSelector->findBestCandidate($packageName);
// 1.2.2 should be returned because it's the latest of the returned versions // 1.2.2 should be returned because it's the latest of the returned versions
@ -57,13 +57,13 @@ class VersionSelectorTest extends TestCase
$package2->setRequires(array('php' => new Link($packageName, 'php', $parser->parseConstraints('>=5.6'), 'requires', '>=5.6'))); $package2->setRequires(array('php' => new Link($packageName, 'php', $parser->parseConstraints('>=5.6'), 'requires', '>=5.6')));
$packages = array($package1, $package2); $packages = array($package1, $package2);
$pool = $this->createMockPool(); $repositorySet = $this->createMockRepositorySet();
$pool->expects($this->once()) $repositorySet->expects($this->once())
->method('whatProvides') ->method('findPackages')
->with($packageName, null, true) ->with($packageName, null)
->will($this->returnValue($packages)); ->will($this->returnValue($packages));
$versionSelector = new VersionSelector($pool); $versionSelector = new VersionSelector($repositorySet);
$best = $versionSelector->findBestCandidate($packageName, null, '5.5.0'); $best = $versionSelector->findBestCandidate($packageName, null, '5.5.0');
$this->assertSame($package1, $best, 'Latest version supporting php 5.5 should be returned (1.0.0)'); $this->assertSame($package1, $best, 'Latest version supporting php 5.5 should be returned (1.0.0)');
@ -77,13 +77,13 @@ class VersionSelectorTest extends TestCase
$package2 = $this->createPackage('1.1.0-beta'); $package2 = $this->createPackage('1.1.0-beta');
$packages = array($package1, $package2); $packages = array($package1, $package2);
$pool = $this->createMockPool(); $repositorySet = $this->createMockRepositorySet();
$pool->expects($this->once()) $repositorySet->expects($this->once())
->method('whatProvides') ->method('findPackages')
->with($packageName, null, true) ->with($packageName, null)
->will($this->returnValue($packages)); ->will($this->returnValue($packages));
$versionSelector = new VersionSelector($pool); $versionSelector = new VersionSelector($repositorySet);
$best = $versionSelector->findBestCandidate($packageName); $best = $versionSelector->findBestCandidate($packageName);
$this->assertSame($package1, $best, 'Latest most stable version should be returned (1.0.0)'); $this->assertSame($package1, $best, 'Latest most stable version should be returned (1.0.0)');
@ -97,18 +97,18 @@ class VersionSelectorTest extends TestCase
$package2 = $this->createPackage('2.0.0-beta3'); $package2 = $this->createPackage('2.0.0-beta3');
$packages = array($package1, $package2); $packages = array($package1, $package2);
$pool = $this->createMockPool(); $repositorySet = $this->createMockRepositorySet();
$pool->expects($this->at(0)) $repositorySet->expects($this->at(0))
->method('whatProvides') ->method('findPackages')
->with($packageName, null, true) ->with($packageName, null)
->will($this->returnValue($packages)); ->will($this->returnValue($packages));
$pool->expects($this->at(1)) $repositorySet->expects($this->at(1))
->method('whatProvides') ->method('findPackages')
->with($packageName, null, true) ->with($packageName, null)
->will($this->returnValue(array_reverse($packages))); ->will($this->returnValue(array_reverse($packages)));
$versionSelector = new VersionSelector($pool); $versionSelector = new VersionSelector($repositorySet);
$best = $versionSelector->findBestCandidate($packageName, null, null); $best = $versionSelector->findBestCandidate($packageName, null, null);
$this->assertSame($package2, $best, 'Expecting 2.0.0-beta3, cause beta is more stable than dev'); $this->assertSame($package2, $best, 'Expecting 2.0.0-beta3, cause beta is more stable than dev');
@ -124,13 +124,13 @@ class VersionSelectorTest extends TestCase
$package2 = $this->createPackage('1.1.0-beta'); $package2 = $this->createPackage('1.1.0-beta');
$packages = array($package1, $package2); $packages = array($package1, $package2);
$pool = $this->createMockPool(); $repositorySet = $this->createMockRepositorySet();
$pool->expects($this->once()) $repositorySet->expects($this->once())
->method('whatProvides') ->method('findPackages')
->with($packageName, null, true) ->with($packageName, null)
->will($this->returnValue($packages)); ->will($this->returnValue($packages));
$versionSelector = new VersionSelector($pool); $versionSelector = new VersionSelector($repositorySet);
$best = $versionSelector->findBestCandidate($packageName, null, null, 'dev'); $best = $versionSelector->findBestCandidate($packageName, null, null, 'dev');
$this->assertSame($package2, $best, 'Latest version should be returned (1.1.0-beta)'); $this->assertSame($package2, $best, 'Latest version should be returned (1.1.0-beta)');
@ -145,13 +145,13 @@ class VersionSelectorTest extends TestCase
$package3 = $this->createPackage('1.2.0-alpha'); $package3 = $this->createPackage('1.2.0-alpha');
$packages = array($package1, $package2, $package3); $packages = array($package1, $package2, $package3);
$pool = $this->createMockPool(); $repositorySet = $this->createMockRepositorySet();
$pool->expects($this->once()) $repositorySet->expects($this->once())
->method('whatProvides') ->method('findPackages')
->with($packageName, null, true) ->with($packageName, null)
->will($this->returnValue($packages)); ->will($this->returnValue($packages));
$versionSelector = new VersionSelector($pool); $versionSelector = new VersionSelector($repositorySet);
$best = $versionSelector->findBestCandidate($packageName, null, null, 'beta'); $best = $versionSelector->findBestCandidate($packageName, null, null, 'beta');
$this->assertSame($package2, $best, 'Latest version should be returned (1.1.0-beta)'); $this->assertSame($package2, $best, 'Latest version should be returned (1.1.0-beta)');
@ -165,13 +165,13 @@ class VersionSelectorTest extends TestCase
$package3 = $this->createPackage('1.2.0-alpha'); $package3 = $this->createPackage('1.2.0-alpha');
$packages = array($package2, $package3); $packages = array($package2, $package3);
$pool = $this->createMockPool(); $repositorySet = $this->createMockRepositorySet();
$pool->expects($this->once()) $repositorySet->expects($this->once())
->method('whatProvides') ->method('findPackages')
->with($packageName, null, true) ->with($packageName, null)
->will($this->returnValue($packages)); ->will($this->returnValue($packages));
$versionSelector = new VersionSelector($pool); $versionSelector = new VersionSelector($repositorySet);
$best = $versionSelector->findBestCandidate($packageName, null, null, 'stable'); $best = $versionSelector->findBestCandidate($packageName, null, null, 'stable');
$this->assertSame($package2, $best, 'Latest version should be returned (1.1.0-beta)'); $this->assertSame($package2, $best, 'Latest version should be returned (1.1.0-beta)');
@ -179,12 +179,12 @@ class VersionSelectorTest extends TestCase
public function testFalseReturnedOnNoPackages() public function testFalseReturnedOnNoPackages()
{ {
$pool = $this->createMockPool(); $repositorySet = $this->createMockRepositorySet();
$pool->expects($this->once()) $repositorySet->expects($this->once())
->method('whatProvides') ->method('findPackages')
->will($this->returnValue(array())); ->will($this->returnValue(array()));
$versionSelector = new VersionSelector($pool); $versionSelector = new VersionSelector($repositorySet);
$best = $versionSelector->findBestCandidate('foobaz'); $best = $versionSelector->findBestCandidate('foobaz');
$this->assertFalse($best, 'No versions are available returns false'); $this->assertFalse($best, 'No versions are available returns false');
} }
@ -194,8 +194,8 @@ class VersionSelectorTest extends TestCase
*/ */
public function testFindRecommendedRequireVersion($prettyVersion, $isDev, $stability, $expectedVersion, $branchAlias = null) public function testFindRecommendedRequireVersion($prettyVersion, $isDev, $stability, $expectedVersion, $branchAlias = null)
{ {
$pool = $this->createMockPool(); $repositorySet = $this->createMockRepositorySet();
$versionSelector = new VersionSelector($pool); $versionSelector = new VersionSelector($repositorySet);
$versionParser = new VersionParser(); $versionParser = new VersionParser();
$package = $this->getMockBuilder('\Composer\Package\PackageInterface')->getMock(); $package = $this->getMockBuilder('\Composer\Package\PackageInterface')->getMock();
@ -273,8 +273,10 @@ class VersionSelectorTest extends TestCase
return new Package('foo', $parser->normalize($version), $version); return new Package('foo', $parser->normalize($version), $version);
} }
private function createMockPool() private function createMockRepositorySet()
{ {
return $this->getMockBuilder('Composer\DependencyResolver\Pool')->getMock(); return $this->getMockBuilder('Composer\Repository\RepositorySet')
->disableOriginalConstructor()
->getMock();
} }
} }

@ -7,6 +7,6 @@
"class": "Installer\\Plugin" "class": "Installer\\Plugin"
}, },
"require": { "require": {
"composer-plugin-api": "^1.0" "composer-plugin-api": "^2.0"
} }
} }

@ -7,6 +7,6 @@
"class": "Installer\\Plugin2" "class": "Installer\\Plugin2"
}, },
"require": { "require": {
"composer-plugin-api": "^1.0" "composer-plugin-api": "^2.0"
} }
} }

@ -7,6 +7,6 @@
"class": "Installer\\Plugin2" "class": "Installer\\Plugin2"
}, },
"require": { "require": {
"composer-plugin-api": "^1.0" "composer-plugin-api": "^2.0"
} }
} }

@ -10,6 +10,6 @@
] ]
}, },
"require": { "require": {
"composer-plugin-api": "^1.0" "composer-plugin-api": "^2.0"
} }
} }

@ -9,6 +9,6 @@
] ]
}, },
"require": { "require": {
"composer-plugin-api": "1.1.0" "composer-plugin-api": "2.0.0"
} }
} }

@ -7,6 +7,6 @@
"class": "Installer\\Plugin" "class": "Installer\\Plugin"
}, },
"require": { "require": {
"composer-plugin-api": "^1.0" "composer-plugin-api": "^2.0"
} }
} }

Loading…
Cancel
Save