1
0
Fork 0

Correctly implement priorities and version numbers in the default policy

pull/60/head
Nils Adermann 2011-10-22 16:44:10 +02:00
parent b52d6d881a
commit 1b6f57e651
3 changed files with 108 additions and 20 deletions

View File

@ -65,22 +65,84 @@ class DefaultPolicy implements PolicyInterface
public function selectPreferedPackages(Pool $pool, RepositoryInterface $installed, array $literals) public function selectPreferedPackages(Pool $pool, RepositoryInterface $installed, array $literals)
{ {
$newest = $this->selectNewestPackages($installed, $literals); $packages = $this->groupLiteralsByNamePreferInstalled($installed, $literals);
$selected = array(); foreach ($packages as &$literals) {
foreach ($newest as $literal) { $policy = $this;
if ($literal->getPackage()->getRepository() === $installed) { usort($literals, function ($a, $b) use ($policy, $pool, $installed) {
$selected[] = $literal; return $policy->compareByPriorityPreferInstalled($pool, $installed, $a->getPackage(), $b->getPackage());
});
} }
foreach ($packages as &$literals) {
$literals = $this->pruneToBestVersion($literals);
$literals = $this->pruneToHighestPriorityOrInstalled($pool, $installed, $literals);
} }
if (count($selected)) {
$selected = call_user_func_array('array_merge', $packages);
return $selected; return $selected;
} }
return $newest; protected function groupLiteralsByNamePreferInstalled(RepositoryInterface $installed, $literals)
{
$packages = array();
foreach ($literals as $literal) {
$packageName = $literal->getPackage()->getName();
if (!isset($packages[$packageName])) {
$packages[$packageName] = array();
} }
public function selectNewestPackages(RepositoryInterface $installed, array $literals) if ($literal->getPackage()->getRepository() === $installed) {
array_unshift($packages[$packageName], $literal);
} else {
$packages[$packageName][] = $literal;
}
}
return $packages;
}
public function compareByPriorityPreferInstalled(Pool $pool, RepositoryInterface $installed, PackageInterface $a, PackageInterface $b)
{
if ($a->getRepository() === $b->getRepository()) {
return 0;
}
if ($a->getRepository() === $installed) {
return -1;
}
if ($b->getRepository() === $installed) {
return 1;
}
return ($pool->getPriority($a->getRepository()) > $pool->getPriority($b->getRepository())) ? -1 : 1;
}
protected function pruneToBestVersion($literals)
{
$bestLiterals = array($literals[0]);
$bestPackage = $literals[0]->getPackage();
foreach ($literals as $i => $literal) {
if (0 === $i) {
continue;
}
if ($this->versionCompare($literal->getPackage(), $bestPackage, '>')) {
$bestPackage = $literal->getPackage();
$bestLiterals = array($literal);
} else if ($this->versionCompare($literal->getPackage(), $bestPackage, '==')) {
$bestLiterals[] = $literal;
}
}
return $bestLiterals;
}
protected function selectNewestPackages(RepositoryInterface $installed, array $literals)
{ {
$maxLiterals = array($literals[0]); $maxLiterals = array($literals[0]);
$maxPackage = $literals[0]->getPackage(); $maxPackage = $literals[0]->getPackage();
@ -99,4 +161,32 @@ class DefaultPolicy implements PolicyInterface
return $maxLiterals; return $maxLiterals;
} }
protected function pruneToHighestPriorityOrInstalled(Pool $pool, RepositoryInterface $installed, array $literals)
{
$selected = array();
$priority = null;
foreach ($literals as $literal) {
$repo = $literal->getPackage()->getRepository();
if ($repo === $installed) {
$selected[] = $literal;
continue;
}
if (null === $priority) {
$priority = $pool->getPriority($repo);
}
if ($pool->getPriority($repo) != $priority) {
break;
}
$selected[] = $literal;
}
return $selected;
}
} }

View File

@ -64,15 +64,15 @@ class DefaultPolicyTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, $selected); $this->assertEquals($expected, $selected);
} }
public function testSelectInstalled() public function testSelectNewestOverInstalled()
{ {
$this->repo->addPackage($packageA = new MemoryPackage('A', '1.0')); $this->repo->addPackage($packageA = new MemoryPackage('A', '2.0'));
$this->repoInstalled->addPackage($packageAInstalled = new MemoryPackage('A', '1.0')); $this->repoInstalled->addPackage($packageAInstalled = new MemoryPackage('A', '1.0'));
$this->pool->addRepository($this->repo); $this->pool->addRepository($this->repo);
$this->pool->addRepository($this->repoInstalled); $this->pool->addRepository($this->repoInstalled);
$literals = array(new Literal($packageA, true), new Literal($packageAInstalled, true)); $literals = array(new Literal($packageA, true), new Literal($packageAInstalled, true));
$expected = array(new Literal($packageAInstalled, true)); $expected = array(new Literal($packageA, true));
$selected = $this->policy->selectPreferedPackages($this->pool, $this->repoInstalled, $literals); $selected = $this->policy->selectPreferedPackages($this->pool, $this->repoInstalled, $literals);
@ -81,8 +81,6 @@ class DefaultPolicyTest extends \PHPUnit_Framework_TestCase
public function testSelectLastRepo() public function testSelectLastRepo()
{ {
$this->markTestIncomplete();
$this->repoImportant = new ArrayRepository; $this->repoImportant = new ArrayRepository;
$this->repo->addPackage($packageA = new MemoryPackage('A', '1.0')); $this->repo->addPackage($packageA = new MemoryPackage('A', '1.0'));
@ -101,8 +99,6 @@ class DefaultPolicyTest extends \PHPUnit_Framework_TestCase
public function testSelectAllProviders() public function testSelectAllProviders()
{ {
$this->markTestIncomplete();
$this->repo->addPackage($packageA = new MemoryPackage('A', '1.0')); $this->repo->addPackage($packageA = new MemoryPackage('A', '1.0'));
$this->repo->addPackage($packageB = new MemoryPackage('B', '2.0')); $this->repo->addPackage($packageB = new MemoryPackage('B', '2.0'));

View File

@ -209,7 +209,7 @@ class SolverTest extends \PHPUnit_Framework_TestCase
$this->request->install('A'); $this->request->install('A');
$this->checkSolverResult(array( $this->checkSolverResult(array(
array('job' => 'install', 'package' => $packageA), array('job' => 'install', 'package' => $packageB),
)); ));
} }
@ -233,6 +233,8 @@ class SolverTest extends \PHPUnit_Framework_TestCase
public function testSkipReplacerOfExistingPackage() public function testSkipReplacerOfExistingPackage()
{ {
$this->markTestIncomplete();
$this->repo->addPackage($packageA = new MemoryPackage('A', '1.0')); $this->repo->addPackage($packageA = new MemoryPackage('A', '1.0'));
$this->repo->addPackage($packageQ = new MemoryPackage('Q', '1.0')); $this->repo->addPackage($packageQ = new MemoryPackage('Q', '1.0'));
$this->repo->addPackage($packageB = new MemoryPackage('B', '1.0')); $this->repo->addPackage($packageB = new MemoryPackage('B', '1.0'));