1
0
Fork 0

Merge branch 'master' of https://github.com/composer/composer into autoload

* 'master' of https://github.com/composer/composer:
  Fix documentation layout
  Add basic specification of the default solver policy behaviour
  DefaultPolicy test: pick package providing newest virtual package version
  Complete the policy tests with provider and replacement tests
  Adding tests for the default policy specifying its desired behaviour
pull/44/head
Igor Wiedler 2011-10-22 15:19:04 +02:00
commit 96104971d0
5 changed files with 219 additions and 4 deletions

56
doc/DefaultPolicy.md Normal file
View File

@ -0,0 +1,56 @@
# Default Solver Policy
A solver policy defines behaviour variables of the dependency solver. It decides
which versions are considered newer than others, which packages should be
prefered over others and whether operations like downgrades or uninstall are
allowed.
## Selection of prefered Packages
The following describe package pool situations with user requests and the
resulting order in which the solver will try to install them.
The rules are to be applied in the order of these descriptions.
### Package versions
Packages: Av1, Av2, Av3
* Installed: Av2
Request: install A
* (Av3)
### Repository priorities
Packages Repo1.Av1, Repo2.Av1
* priority(Repo1) >= priority(Repo2) => (Repo1.Av1, Repo2.Av1)
* priority(Repo2) < priority(Repo2) => (Repo2.Av1, Repo1.Av1)
### Virtual Packages (provides)
Packages Av1, Bv1
* Av1 provides Xv1
* Bv1 provides Xv1
Request: install X
* priority(Av1.repo) >= priority(Bv1.repo) => (Av1, Bv1)
* priority(Av1.repo) < priority(Bv1.repo) => (Bv1, Av1)
### Package replacements
Packages: Av1, Bv2
* Bv2 replaces Av1
Request: install A
* priority(Av1.repo) > priority(Bv2.repo) => (Av1, Bv2)
* priority(Av1.repo) = priority(Bv2.repo) => (Av1, Bv2)
* priority(Av1.repo) < priority(Bv2.repo) => (Bv2, Av1)
Bv2.version is ignored, only the replacement version for A matters.

View File

@ -63,9 +63,8 @@ class DefaultPolicy implements PolicyInterface
return true;
}
public function selectPreferedPackages(Solver $solver, Pool $pool, RepositoryInterface $installed, array $literals)
public function selectPreferedPackages(Pool $pool, RepositoryInterface $installed, array $literals)
{
// prefer installed, newest version, recommended, highest priority repository, ...
$newest = $this->selectNewestPackages($installed, $literals);
$selected = array();

View File

@ -25,5 +25,5 @@ interface PolicyInterface
function versionCompare(PackageInterface $a, PackageInterface $b, $operator);
function findUpdatePackages(Solver $solver, Pool $pool, RepositoryInterface $repo, PackageInterface $package, $allowAll);
function installable(Solver $solver, Pool $pool, RepositoryInterface $repo, PackageInterface $package);
function selectPreferedPackages(Solver $solver, Pool $pool, RepositoryInterface $installed, array $literals);
function selectPreferedPackages(Pool $pool, RepositoryInterface $installed, array $literals);
}

View File

@ -1411,7 +1411,7 @@ class Solver
private function selectAndInstall($level, array $decisionQueue, $disableRules, Rule $rule)
{
// choose best package to install from decisionQueue
$literals = $this->policy->selectPreferedPackages($this, $this->pool, $this->installed, $decisionQueue);
$literals = $this->policy->selectPreferedPackages($this->pool, $this->installed, $decisionQueue);
$selectedLiteral = array_shift($literals);

View File

@ -0,0 +1,160 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Test\DependencyResolver;
use Composer\Repository\ArrayRepository;
use Composer\DependencyResolver\DefaultPolicy;
use Composer\DependencyResolver\Pool;
use Composer\DependencyResolver\Literal;
use Composer\Package\MemoryPackage;
use Composer\Package\Link;
use Composer\Package\LinkConstraint\VersionConstraint;
class DefaultPolicyTest extends \PHPUnit_Framework_TestCase
{
protected $pool;
protected $repo;
protected $repoInstalled;
protected $request;
protected $policy;
public function setUp()
{
$this->pool = new Pool;
$this->repo = new ArrayRepository;
$this->repoInstalled = new ArrayRepository;
$this->policy = new DefaultPolicy;
}
public function testSelectSingle()
{
$this->repo->addPackage($packageA = new MemoryPackage('A', '1.0'));
$this->pool->addRepository($this->repo);
$literals = array(new Literal($packageA, true));
$expected = array(new Literal($packageA, true));
$selected = $this->policy->selectPreferedPackages($this->pool, $this->repoInstalled, $literals);
$this->assertEquals($expected, $selected);
}
public function testSelectNewest()
{
$this->repo->addPackage($packageA1 = new MemoryPackage('A', '1.0'));
$this->repo->addPackage($packageA2 = new MemoryPackage('A', '2.0'));
$this->pool->addRepository($this->repo);
$literals = array(new Literal($packageA1, true), new Literal($packageA2, true));
$expected = array(new Literal($packageA2, true));
$selected = $this->policy->selectPreferedPackages($this->pool, $this->repoInstalled, $literals);
$this->assertEquals($expected, $selected);
}
public function testSelectInstalled()
{
$this->repo->addPackage($packageA = new MemoryPackage('A', '1.0'));
$this->repoInstalled->addPackage($packageAInstalled = new MemoryPackage('A', '1.0'));
$this->pool->addRepository($this->repo);
$this->pool->addRepository($this->repoInstalled);
$literals = array(new Literal($packageA, true), new Literal($packageAInstalled, true));
$expected = array(new Literal($packageAInstalled, true));
$selected = $this->policy->selectPreferedPackages($this->pool, $this->repoInstalled, $literals);
$this->assertEquals($expected, $selected);
}
public function testSelectLastRepo()
{
$this->markTestIncomplete();
$this->repoImportant = new ArrayRepository;
$this->repo->addPackage($packageA = new MemoryPackage('A', '1.0'));
$this->repoImportant->addPackage($packageAImportant = new MemoryPackage('A', '1.0'));
$this->pool->addRepository($this->repo);
$this->pool->addRepository($this->repoImportant);
$literals = array(new Literal($packageA, true), new Literal($packageAImportant, true));
$expected = array(new Literal($packageAImportant, true));
$selected = $this->policy->selectPreferedPackages($this->pool, $this->repoInstalled, $literals);
$this->assertEquals($expected, $selected);
}
public function testSelectAllProviders()
{
$this->markTestIncomplete();
$this->repo->addPackage($packageA = new MemoryPackage('A', '1.0'));
$this->repo->addPackage($packageB = new MemoryPackage('B', '2.0'));
$packageA->setProvides(array(new Link('A', 'X', new VersionConstraint('==', '1.0'), 'provides')));
$packageB->setProvides(array(new Link('B', 'X', new VersionConstraint('==', '1.0'), 'provides')));
$this->pool->addRepository($this->repo);
$literals = array(new Literal($packageA, true), new Literal($packageB, true));
$expected = $literals;
$selected = $this->policy->selectPreferedPackages($this->pool, $this->repoInstalled, $literals);
$this->assertEquals($expected, $selected);
}
public function testSelectNewestProvider()
{
$this->markTestIncomplete();
$this->repo->addPackage($packageA = new MemoryPackage('A', '1.0'));
$this->repo->addPackage($packageB = new MemoryPackage('B', '2.0'));
$packageA->setProvides(array(new Link('A', 'X', new VersionConstraint('==', '2.0'), 'provides')));
$packageB->setProvides(array(new Link('B', 'X', new VersionConstraint('==', '1.0'), 'provides')));
$this->pool->addRepository($this->repo);
$literals = array(new Literal($packageA, true), new Literal($packageB, true));
$expected = array(new Literal($packageA, true));
$selected = $this->policy->selectPreferedPackages($this->pool, $this->repoInstalled, $literals);
$this->assertEquals($expected, $selected);
}
public function testSelectNonReplacingFromSameRepo()
{
$this->markTestIncomplete();
$this->repo->addPackage($packageA = new MemoryPackage('A', '1.0'));
$this->repo->addPackage($packageB = new MemoryPackage('B', '2.0'));
$packageB->setReplaces(array(new Link('B', 'A', new VersionConstraint('==', '1.0'), 'replaces')));
$this->pool->addRepository($this->repo);
$literals = array(new Literal($packageA, true), new Literal($packageB, true));
$expected = array(new Literal($packageA, true));
$selected = $this->policy->selectPreferedPackages($this->pool, $this->repoInstalled, $literals);
$this->assertEquals($expected, $selected);
}
}