1
0
Fork 0

Remove RepositorySet from Solver and remove getPool from RepositorySet

pull/8558/head
Jordi Boggiano 2020-01-30 15:23:22 +01:00
parent f982a10447
commit c41df325d8
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
10 changed files with 36 additions and 61 deletions

View File

@ -63,7 +63,7 @@ class Problem
* @param array $installedMap A map of all present packages * @param array $installedMap A map of all present packages
* @return string * @return string
*/ */
public function getPrettyString(RepositorySet $repositorySet, Request $request, array $installedMap = array(), array $learnedPool = array()) public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, array $installedMap = array(), array $learnedPool = array())
{ {
// TODO doesn't this entirely defeat the purpose of the problem sections? what's the point of sections? // TODO doesn't this entirely defeat the purpose of the problem sections? what's the point of sections?
$reasons = call_user_func_array('array_merge', array_reverse($this->reasons)); $reasons = call_user_func_array('array_merge', array_reverse($this->reasons));
@ -81,20 +81,20 @@ class Problem
$constraint = $reasonData['constraint']; $constraint = $reasonData['constraint'];
if (isset($constraint)) { if (isset($constraint)) {
$packages = $repositorySet->getPool()->whatProvides($packageName, $constraint); $packages = $pool->whatProvides($packageName, $constraint);
} else { } else {
$packages = array(); $packages = array();
} }
if (empty($packages)) { if (empty($packages)) {
return "\n ".implode(self::getMissingPackageReason($repositorySet, $request, $packageName, $constraint)); return "\n ".implode(self::getMissingPackageReason($repositorySet, $request, $pool, $packageName, $constraint));
} }
} }
$messages = array(); $messages = array();
foreach ($reasons as $rule) { foreach ($reasons as $rule) {
$messages[] = $rule->getPrettyString($repositorySet, $request, $installedMap, $learnedPool); $messages[] = $rule->getPrettyString($repositorySet, $request, $pool, $installedMap, $learnedPool);
} }
return "\n - ".implode("\n - ", $messages); return "\n - ".implode("\n - ", $messages);
@ -125,10 +125,8 @@ class Problem
/** /**
* @internal * @internal
*/ */
public static function getMissingPackageReason(RepositorySet $repositorySet, Request $request, $packageName, $constraint = null) public static function getMissingPackageReason(RepositorySet $repositorySet, Request $request, Pool $pool, $packageName, $constraint = null)
{ {
$pool = $repositorySet->getPool();
// handle php/hhvm // handle php/hhvm
if ($packageName === 'php' || $packageName === 'php-64bit' || $packageName === 'hhvm') { if ($packageName === 'php' || $packageName === 'php-64bit' || $packageName === 'hhvm') {
$version = phpversion(); $version = phpversion();

View File

@ -123,9 +123,8 @@ abstract class Rule
abstract public function isAssertion(); abstract public function isAssertion();
public function getPrettyString(RepositorySet $repositorySet, Request $request, array $installedMap = array(), array $learnedPool = array()) public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, array $installedMap = array(), array $learnedPool = array())
{ {
$pool = $repositorySet->getPool();
$literals = $this->getLiterals(); $literals = $this->getLiterals();
$ruleText = ''; $ruleText = '';
@ -180,7 +179,7 @@ abstract class Rule
} else { } else {
$targetName = $this->reasonData->getTarget(); $targetName = $this->reasonData->getTarget();
$reason = Problem::getMissingPackageReason($repositorySet, $request, $targetName, $this->reasonData->getConstraint()); $reason = Problem::getMissingPackageReason($repositorySet, $request, $pool, $targetName, $this->reasonData->getConstraint());
return $text . ' -> ' . $reason[1]; return $text . ' -> ' . $reason[1];
} }
@ -241,7 +240,7 @@ abstract class Rule
$learnedString = ', learned rules:'."\n - "; $learnedString = ', learned rules:'."\n - ";
$reasons = array(); $reasons = array();
foreach ($learnedPool[$this->reasonData] as $learnedRule) { foreach ($learnedPool[$this->reasonData] as $learnedRule) {
$reasons[] = $learnedRule->getPrettyString($repositorySet, $request, $installedMap, $learnedPool); $reasons[] = $learnedRule->getPrettyString($repositorySet, $request, $pool, $installedMap, $learnedPool);
} }
$learnedString .= implode("\n - ", array_unique($reasons)); $learnedString .= implode("\n - ", array_unique($reasons));
} else { } else {

View File

@ -157,13 +157,13 @@ class RuleSet implements \IteratorAggregate, \Countable
return array_keys($types); return array_keys($types);
} }
public function getPrettyString(RepositorySet $repositorySet = null, Request $request = null) public function getPrettyString(RepositorySet $repositorySet = null, Request $request = null, Pool $pool = null)
{ {
$string = "\n"; $string = "\n";
foreach ($this->rules as $type => $rules) { foreach ($this->rules as $type => $rules) {
$string .= str_pad(self::$types[$type], 8, ' ') . ": "; $string .= str_pad(self::$types[$type], 8, ' ') . ": ";
foreach ($rules as $rule) { foreach ($rules as $rule) {
$string .= ($repositorySet && $request ? $rule->getPrettyString($repositorySet, $request) : $rule)."\n"; $string .= ($repositorySet && $request && $pool ? $rule->getPrettyString($repositorySet, $request, $pool) : $rule)."\n";
} }
$string .= "\n\n"; $string .= "\n\n";
} }
@ -173,6 +173,6 @@ class RuleSet implements \IteratorAggregate, \Countable
public function __toString() public function __toString()
{ {
return $this->getPrettyString(null, null); return $this->getPrettyString(null, null, null);
} }
} }

View File

@ -14,9 +14,7 @@ namespace Composer\DependencyResolver;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
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>
@ -30,8 +28,6 @@ class Solver
protected $policy; protected $policy;
/** @var Pool */ /** @var Pool */
protected $pool; protected $pool;
/** @var RepositorySet */
protected $repositorySet;
/** @var RuleSet */ /** @var RuleSet */
protected $rules; protected $rules;
@ -67,12 +63,11 @@ class Solver
* @param Pool $pool * @param Pool $pool
* @param IOInterface $io * @param IOInterface $io
*/ */
public function __construct(PolicyInterface $policy, Pool $pool, IOInterface $io, RepositorySet $repositorySet) public function __construct(PolicyInterface $policy, Pool $pool, IOInterface $io)
{ {
$this->io = $io; $this->io = $io;
$this->policy = $policy; $this->policy = $policy;
$this->pool = $pool; $this->pool = $pool;
$this->repositorySet = $repositorySet;
} }
/** /**
@ -88,11 +83,6 @@ class Solver
return $this->pool; return $this->pool;
} }
public function getRepositorySet()
{
return $this->repositorySet;
}
// aka solver_makeruledecisions // aka solver_makeruledecisions
private function makeAssertionRuleDecisions() private function makeAssertionRuleDecisions()
@ -222,7 +212,7 @@ class Solver
$this->io->writeError(sprintf('Dependency resolution completed in %.3f seconds', microtime(true) - $before), true, IOInterface::VERBOSE); $this->io->writeError(sprintf('Dependency resolution completed in %.3f seconds', microtime(true) - $before), true, IOInterface::VERBOSE);
if ($this->problems) { if ($this->problems) {
throw new SolverProblemsException($this->problems, $this->repositorySet, $request, $this->learnedPool); throw new SolverProblemsException($this->problems, $this->learnedPool);
} }
return new LockTransaction($this->pool, $request->getPresentMap(), $request->getUnlockableMap(), $this->decisions); return new LockTransaction($this->pool, $request->getPresentMap(), $request->getUnlockableMap(), $this->decisions);

View File

@ -21,24 +21,23 @@ use Composer\Repository\RepositorySet;
class SolverProblemsException extends \RuntimeException class SolverProblemsException extends \RuntimeException
{ {
protected $problems; protected $problems;
protected $installedMap;
protected $learnedPool; protected $learnedPool;
public function __construct(array $problems, RepositorySet $repositorySet, Request $request, array $learnedPool) public function __construct(array $problems, array $learnedPool)
{ {
$this->problems = $problems; $this->problems = $problems;
$this->installedMap = $request->getPresentMap(true);
$this->learnedPool = $learnedPool; $this->learnedPool = $learnedPool;
parent::__construct($this->createMessage($repositorySet, $request), 2); parent::__construct('Failed resolving dependencies with '.count($problems).' problems, call getPrettyString to get formatted details', 2);
} }
protected function createMessage(RepositorySet $repositorySet, Request $request) public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool)
{ {
$installedMap = $request->getPresentMap(true);
$text = "\n"; $text = "\n";
$hasExtensionProblems = false; $hasExtensionProblems = false;
foreach ($this->problems as $i => $problem) { foreach ($this->problems as $i => $problem) {
$text .= " Problem ".($i + 1).$problem->getPrettyString($repositorySet, $request, $this->installedMap, $this->learnedPool)."\n"; $text .= " Problem ".($i + 1).$problem->getPrettyString($repositorySet, $request, $pool, $installedMap, $this->learnedPool)."\n";
if (!$hasExtensionProblems && $this->hasExtensionProblems($problem->getReasons())) { if (!$hasExtensionProblems && $this->hasExtensionProblems($problem->getReasons())) {
$hasExtensionProblems = true; $hasExtensionProblems = true;

View File

@ -396,7 +396,7 @@ class Installer
$solver = null; $solver = null;
} catch (SolverProblemsException $e) { } catch (SolverProblemsException $e) {
$this->io->writeError('<error>Your requirements could not be resolved to an installable set of packages.</error>', true, IOInterface::QUIET); $this->io->writeError('<error>Your requirements could not be resolved to an installable set of packages.</error>', true, IOInterface::QUIET);
$this->io->writeError($e->getMessage()); $this->io->writeError($e->getPrettyString($repositorySet, $request, $pool));
if (!$this->devMode) { if (!$this->devMode) {
$this->io->writeError('<warning>Running update with --no-dev does not mean require-dev is ignored, it just means the packages will not be installed. If dev requirements are blocking the update you have to resolve those problems.</warning>', true, IOInterface::QUIET); $this->io->writeError('<warning>Running update with --no-dev does not mean require-dev is ignored, it just means the packages will not be installed. If dev requirements are blocking the update you have to resolve those problems.</warning>', true, IOInterface::QUIET);
} }
@ -536,7 +536,7 @@ class Installer
$solver = null; $solver = null;
} catch (SolverProblemsException $e) { } catch (SolverProblemsException $e) {
$this->io->writeError('<error>Unable to find a compatible set of packages based on your non-dev requirements alone.</error>', true, IOInterface::QUIET); $this->io->writeError('<error>Unable to find a compatible set of packages based on your non-dev requirements alone.</error>', true, IOInterface::QUIET);
$this->io->writeError($e->getMessage()); $this->io->writeError($e->getPrettyString($repositorySet, $request, $pool));
return max(1, $e->getCode()); return max(1, $e->getCode());
} }
@ -602,7 +602,7 @@ class Installer
} }
} catch (SolverProblemsException $e) { } catch (SolverProblemsException $e) {
$this->io->writeError('<error>Your lock file does not contain a compatible set of packages. Please run composer update.</error>', true, IOInterface::QUIET); $this->io->writeError('<error>Your lock file does not contain a compatible set of packages. Please run composer update.</error>', true, IOInterface::QUIET);
$this->io->writeError($e->getMessage()); $this->io->writeError($e->getPrettyString($repositorySet, $request, $pool));
return max(1, $e->getCode()); return max(1, $e->getCode());
} }

View File

@ -54,8 +54,8 @@ class RepositorySet
private $stabilityFlags; private $stabilityFlags;
private $rootRequires; private $rootRequires;
/** @var Pool */ /** @var bool */
private $pool; private $locked = false;
public function __construct(array $rootAliases = array(), array $rootReferences = array(), $minimumStability = 'stable', array $stabilityFlags = array(), array $rootRequires = array()) public function __construct(array $rootAliases = array(), array $rootReferences = array(), $minimumStability = 'stable', array $stabilityFlags = array(), array $rootRequires = array())
{ {
@ -92,7 +92,7 @@ class RepositorySet
*/ */
public function addRepository(RepositoryInterface $repo) public function addRepository(RepositoryInterface $repo)
{ {
if ($this->pool) { if ($this->locked) {
throw new \RuntimeException("Pool has already been created from this repository set, it cannot be modified anymore."); throw new \RuntimeException("Pool has already been created from this repository set, it cannot be modified anymore.");
} }
@ -191,7 +191,9 @@ class RepositorySet
} }
} }
return $this->pool = $poolBuilder->buildPool($this->repositories, $request); $this->locked = true;
return $poolBuilder->buildPool($this->repositories, $request);
} }
// TODO unify this with above in some simpler version without "request"? // TODO unify this with above in some simpler version without "request"?
@ -210,13 +212,4 @@ class RepositorySet
return $this->createPool($request); return $this->createPool($request);
} }
/**
* Access the pool object after it has been created, relevant for plugins which need to read info from the pool
* @return Pool
*/
public function getPool()
{
return $this->pool;
}
} }

View File

@ -144,9 +144,6 @@ class RuleSetTest extends TestCase
)); ));
$repositorySetMock = $this->getMockBuilder('Composer\Repository\RepositorySet')->disableOriginalConstructor()->getMock(); $repositorySetMock = $this->getMockBuilder('Composer\Repository\RepositorySet')->disableOriginalConstructor()->getMock();
$repositorySetMock->expects($this->any())
->method('getPool')
->willReturn($pool);
$requestMock = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock(); $requestMock = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock();
$ruleSet = new RuleSet; $ruleSet = new RuleSet;
@ -155,6 +152,6 @@ class RuleSetTest extends TestCase
$ruleSet->add($rule, RuleSet::TYPE_REQUEST); $ruleSet->add($rule, RuleSet::TYPE_REQUEST);
$this->assertContains('REQUEST : No package found to satisfy root composer.json require foo/bar', $ruleSet->getPrettyString($repositorySetMock, $requestMock)); $this->assertContains('REQUEST : No package found to satisfy root composer.json require foo/bar', $ruleSet->getPrettyString($repositorySetMock, $requestMock, $pool));
} }
} }

View File

@ -100,13 +100,10 @@ class RuleTest extends TestCase
)); ));
$repositorySetMock = $this->getMockBuilder('Composer\Repository\RepositorySet')->disableOriginalConstructor()->getMock(); $repositorySetMock = $this->getMockBuilder('Composer\Repository\RepositorySet')->disableOriginalConstructor()->getMock();
$repositorySetMock->expects($this->any())
->method('getPool')
->willReturn($pool);
$requestMock = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock(); $requestMock = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock();
$rule = new GenericRule(array($p1->getId(), -$p2->getId()), Rule::RULE_PACKAGE_REQUIRES, new Link('baz', 'foo')); $rule = new GenericRule(array($p1->getId(), -$p2->getId()), Rule::RULE_PACKAGE_REQUIRES, new Link('baz', 'foo'));
$this->assertEquals('baz 1.1 relates to foo -> satisfiable by foo[2.1].', $rule->getPrettyString($repositorySetMock, $requestMock)); $this->assertEquals('baz 1.1 relates to foo -> satisfiable by foo[2.1].', $rule->getPrettyString($repositorySetMock, $requestMock, $pool));
} }
} }

View File

@ -34,6 +34,7 @@ class SolverTest extends TestCase
protected $request; protected $request;
protected $policy; protected $policy;
protected $solver; protected $solver;
protected $pool;
public function setUp() public function setUp()
{ {
@ -82,7 +83,7 @@ class SolverTest extends TestCase
$problems = $e->getProblems(); $problems = $e->getProblems();
$this->assertCount(1, $problems); $this->assertCount(1, $problems);
$this->assertEquals(2, $e->getCode()); $this->assertEquals(2, $e->getCode());
$this->assertEquals("\n - Root composer.json requires b, it could not be found in any version, there may be a typo in the package name.", $problems[0]->getPrettyString($this->repoSet, $this->request)); $this->assertEquals("\n - Root composer.json requires b, it could not be found in any version, there may be a typo in the package name.", $problems[0]->getPrettyString($this->repoSet, $this->request, $this->pool));
} }
} }
@ -653,7 +654,7 @@ class SolverTest extends TestCase
$msg .= " - Root composer.json requires a -> satisfiable by A[1.0].\n"; $msg .= " - Root composer.json requires a -> satisfiable by A[1.0].\n";
$msg .= " - B 1.0 conflicts with A[1.0].\n"; $msg .= " - B 1.0 conflicts with A[1.0].\n";
$msg .= " - Root composer.json requires b -> satisfiable by B[1.0].\n"; $msg .= " - Root composer.json requires b -> satisfiable by B[1.0].\n";
$this->assertEquals($msg, $e->getMessage()); $this->assertEquals($msg, $e->getPrettyString($this->repoSet, $this->request, $this->pool));
} }
} }
@ -683,7 +684,7 @@ class SolverTest extends TestCase
$msg .= " Problem 1\n"; $msg .= " Problem 1\n";
$msg .= " - Root composer.json requires a -> satisfiable by A[1.0].\n"; $msg .= " - Root composer.json requires a -> satisfiable by A[1.0].\n";
$msg .= " - A 1.0 requires b >= 2.0 -> found B[1.0] but it does not match your constraint.\n"; $msg .= " - A 1.0 requires b >= 2.0 -> found B[1.0] but it does not match your constraint.\n";
$this->assertEquals($msg, $e->getMessage()); $this->assertEquals($msg, $e->getPrettyString($this->repoSet, $this->request, $this->pool));
} }
} }
@ -728,7 +729,7 @@ class SolverTest extends TestCase
$msg .= " - Only one of these can be installed: B[0.9, 1.0].\n"; $msg .= " - Only one of these can be installed: B[0.9, 1.0].\n";
$msg .= " - A 1.0 requires b >= 1.0 -> satisfiable by B[1.0].\n"; $msg .= " - A 1.0 requires b >= 1.0 -> satisfiable by B[1.0].\n";
$msg .= " - Root composer.json requires a -> satisfiable by A[1.0].\n"; $msg .= " - Root composer.json requires a -> satisfiable by A[1.0].\n";
$this->assertEquals($msg, $e->getMessage()); $this->assertEquals($msg, $e->getPrettyString($this->repoSet, $this->request, $this->pool));
} }
} }
@ -889,7 +890,8 @@ class SolverTest extends TestCase
protected function createSolver() protected function createSolver()
{ {
$this->solver = new Solver($this->policy, $this->repoSet->createPool($this->request), new NullIO(), $this->repoSet); $this->pool = $this->repoSet->createPool($this->request);
$this->solver = new Solver($this->policy, $this->pool, new NullIO());
} }
protected function checkSolverResult(array $expected) protected function checkSolverResult(array $expected)