1
0
Fork 0

Rename RelationConstraints to Links in the Package namespace.

Constraints have been generalised to allow matching requiring and providing
constraints against each other.
pull/1/head
Nils Adermann 2011-04-18 00:16:12 +02:00
parent e03983697a
commit 8c9f8fb86f
11 changed files with 214 additions and 116 deletions

View File

@ -1,54 +0,0 @@
<?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\DependencyResolver;
use Composer\DependencyResolver\RelationConstraint\RelationConstraintInterface;
/**
* @author Nils Adermann <naderman@naderman.de>
*/
class PackageRelation
{
protected $fromPackageName;
protected $toPackageName;
protected $constraint;
protected $description;
public function __construct($fromPackageName, $toPackageName, RelationConstraintInterface $constraint, $description = 'relates to')
{
$this->fromPackageName = $fromPackageName;
$this->toPackageName = $toPackageName;
$this->constraint = $constraint;
$this->description = $description;
}
public function getToPackageName()
{
return $this->toPackageName;
}
public function getFromPackageName()
{
return $this->fromPackageName;
}
public function getConstraint()
{
return $this->constraint;
}
public function __toString()
{
return $this->fromPackageName.' '.$this->description.' '.$this->toPackageName.' ('.$this->constraint.')';
}
}

View File

@ -12,7 +12,7 @@
namespace Composer\DependencyResolver;
use Composer\DependencyResolver\RelationConstraint\RelationConstraintInterface;
use Composer\Package\LinkConstraint\LinkConstraintInterface;
use Composer\Repository\RepositoryInterface;
/**
@ -47,12 +47,12 @@ class Pool
/**
* Searches all packages providing the given package name and match the constraint
*
* @param string $name The package name to be searched for
* @param RelationConstraintInterface $constraint A constraint that all returned
* packages must match or null to return all
* @return array A set of packages
* @param string $name The package name to be searched for
* @param LinkConstraintInterface $constraint A constraint that all returned
* packages must match or null to return all
* @return array A set of packages
*/
public function whatProvides($name, RelationConstraintInterface $constraint = null)
public function whatProvides($name, LinkConstraintInterface $constraint = null)
{
if (!isset($this->packageByName[$name])) {
return array();

View File

@ -264,8 +264,8 @@ class Solver
continue;
}
foreach ($package->getRequires() as $relation) {
$possibleRequires = $this->pool->whatProvides($relation->getToPackageName(), $relation->getConstraint());
foreach ($package->getRequires() as $link) {
$possibleRequires = $this->pool->whatProvides($link->getTarget(), $link->getConstraint());
// the strategy here is to not insist on dependencies
// that are already broken. so if we find one provider
@ -286,33 +286,33 @@ class Solver
}
}
$this->addRule(self::TYPE_PACKAGE, $this->createRequireRule($package, $possibleRequires, self::RULE_PACKAGE_REQUIRES, (string) $relation));
$this->addRule(self::TYPE_PACKAGE, $this->createRequireRule($package, $possibleRequires, self::RULE_PACKAGE_REQUIRES, (string) $link));
foreach ($possibleRequires as $require) {
$workQueue->enqueue($require);
}
}
foreach ($package->getConflicts() as $relation) {
$possibleConflicts = $this->pool->whatProvides($relation->getToPackageName(), $relation->getConstraint());
foreach ($package->getConflicts() as $link) {
$possibleConflicts = $this->pool->whatProvides($link->getTarget(), $link->getConstraint());
foreach ($possibleConflicts as $conflict) {
if ($dontfix && $this->installed === $conflict->getRepository()) {
continue;
}
$this->addRule(self::TYPE_PACKAGE, $this->createConflictRule($package, $conflict, self::RULE_PACKAGE_CONFLICT, (string) $relation));
$this->addRule(self::TYPE_PACKAGE, $this->createConflictRule($package, $conflict, self::RULE_PACKAGE_CONFLICT, (string) $link));
}
}
foreach ($package->getRecommends() as $relation) {
foreach ($this->pool->whatProvides($relation->getToPackageName(), $relation->getConstraint()) as $recommend) {
foreach ($package->getRecommends() as $link) {
foreach ($this->pool->whatProvides($link->getTarget(), $link->getConstraint()) as $recommend) {
$workQueue->enqueue($recommend);
}
}
foreach ($package->getSuggests() as $relation) {
foreach ($this->pool->whatProvides($relation->getToPackageName(), $relation->getConstraint()) as $suggest) {
foreach ($package->getSuggests() as $link) {
foreach ($this->pool->whatProvides($link->getTarget(), $link->getConstraint()) as $suggest) {
$workQueue->enqueue($suggest);
}
}

View File

@ -12,7 +12,7 @@
namespace Composer\Package;
use Composer\DependencyResolver\RelationConstraint\RelationConstraintInterface;
use Composer\Package\LinkConstraint\LinkConstraintInterface;
use Composer\Repository\RepositoryInterface;
/**
@ -59,12 +59,12 @@ abstract class BasePackage implements PackageInterface
$this->getName(),
);
foreach ($this->getProvides() as $relation) {
$names[] = $relation->getToPackageName();
foreach ($this->getProvides() as $link) {
$names[] = $link->getTarget();
}
foreach ($this->getReplaces() as $relation) {
$names[] = $relation->getToPackageName();
foreach ($this->getReplaces() as $link) {
$names[] = $link->getTarget();
}
return $names;
@ -74,25 +74,25 @@ abstract class BasePackage implements PackageInterface
* Checks if the package matches the given constraint directly or through
* provided or replaced packages
*
* @param string $name Name of the package to be matched
* @param RelationConstraintInterface $constraint The constraint to verify
* @return bool Whether this package matches the name and constraint
* @param string $name Name of the package to be matched
* @param LinkConstraintInterface $constraint The constraint to verify
* @return bool Whether this package matches the name and constraint
*/
public function matches($name, RelationConstraintInterface $constraint)
public function matches($name, LinkConstraintInterface $constraint)
{
if ($this->name === $name) {
return $constraint->matches($this->getReleaseType(), $this->getVersion());
}
foreach ($this->getProvides() as $relation) {
if ($relation->getToPackageName() === $name) {
return $constraint->matches($relation->getToReleaseType(), $relation->getToVersion());
foreach ($this->getProvides() as $link) {
if ($link->getTarget() === $name) {
return $constraint->matches($link->getConstraint());
}
}
foreach ($this->getReplaces() as $relation) {
if ($relation->getToPackageName() === $name) {
return $constraint->matches($relation->getToReleaseType(), $relation->getToVersion());
foreach ($this->getReplaces() as $link) {
if ($link->getTarget() === $name) {
return $constraint->matches($link->getConstraint());
}
}

View File

@ -0,0 +1,64 @@
<?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\Package;
use Composer\Package\LinkConstraint\LinkConstraintInterface;
/**
* Represents a link between two packages, represented by their names
*
* @author Nils Adermann <naderman@naderman.de>
*/
class Link
{
protected $source;
protected $target;
protected $constraint;
protected $description;
/**
* Creates a new package link.
*
* @param string $source
* @param string $target
* @param LinkConstraintInterface $constraint Constraint applying to the target of this link
* @param string $description Used to create a descriptive string representation
*/
public function __construct($source, $target, LinkConstraintInterface $constraint, $description = 'relates to')
{
$this->source = $source;
$this->target = $target;
$this->constraint = $constraint;
$this->description = $description;
}
public function getSource()
{
return $this->source;
}
public function getTarget()
{
return $this->target;
}
public function getConstraint()
{
return $this->constraint;
}
public function __toString()
{
return $this->source.' '.$this->description.' '.$this->target.' ('.$this->constraint.')';
}
}

View File

@ -10,13 +10,15 @@
* file that was distributed with this source code.
*/
namespace Composer\DependencyResolver\RelationConstraint;
namespace Composer\Package\LinkConstraint;
/**
* Defines a constraint on a link between two packages.
*
* @author Nils Adermann <naderman@naderman.de>
*/
interface RelationConstraintInterface
interface LinkConstraintInterface
{
function matches($releaseType, $version);
function matches(LinkConstraintInterface $provider);
function __toString();
}

View File

@ -0,0 +1,49 @@
<?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\Package\LinkConstraint;
/**
* Defines a conjuctive set of constraints on the target of a package link
*
* @author Nils Adermann <naderman@naderman.de>
*/
class MultiConstraint implements LinkConstraintInterface
{
protected $constraints;
/**
* Sets operator and version to compare a package with
*
* @param array $constraints A conjuctive set of constraints
*/
public function __construct(array $constraints)
{
$this->constraints = $constraints;
}
public function matches(LinkConstraintInterface $provider)
{
foreach ($this->constraints as $constraint) {
if (!$constraint->matches($provider)) {
return false;
}
}
return true;
}
public function __toString()
{
return $this->operator.' '.$this->version;
}
}

View File

@ -0,0 +1,37 @@
<?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\Package\LinkConstraint;
/**
* Provides a common basis for specific package link constraints
*
* @author Nils Adermann <naderman@naderman.de>
*/
class SpecificConstraint implements LinkConstraintInterface
{
public function matches(LinkConstraintInterface $provider)
{
if ($provider instanceof MultiConstraint) {
// turn matching around to find a match
return $provider->matches($this);
} else if ($provider instanceof get_class($this)) {
return $this->matchSpecific($provider);
}
return true;
}
abstract public function matchSpecific($provider);
abstract public function __toString();
}

View File

@ -10,16 +10,16 @@
* file that was distributed with this source code.
*/
namespace Composer\DependencyResolver\RelationConstraint;
namespace Composer\Package\LinkConstraint;
/**
* Constrains a package relation based on package version
* Constrains a package link based on package version
*
* Version numbers must be compatible with version_compare
*
* @author Nils Adermann <naderman@naderman.de>
*/
class VersionConstraint implements RelationConstraintInterface
class VersionConstraint extends SpecificConstraint
{
private $operator;
private $version;
@ -36,9 +36,9 @@ class VersionConstraint implements RelationConstraintInterface
$this->version = $version;
}
public function matches($releaseType, $version)
public function matchSpecific(VersionConstraint $provider)
{
return version_compare($version, $this->version, $this->operator);
return version_compare($provider->version, $this->version, $this->operator);
}
public function __toString()

View File

@ -153,7 +153,7 @@ class MemoryPackage extends BasePackage
/**
* Set the required packages
*
* @param array $requires A set of package relations
* @param array $requires A set of package links
*/
public function setRequires(array $requires)
{
@ -171,7 +171,7 @@ class MemoryPackage extends BasePackage
/**
* Set the conflicting packages
*
* @param array $conflicts A set of package relations
* @param array $conflicts A set of package links
*/
public function setConflicts(array $conflicts)
{
@ -189,7 +189,7 @@ class MemoryPackage extends BasePackage
/**
* Set the provided virtual packages
*
* @param array $conflicts A set of package relations
* @param array $conflicts A set of package links
*/
public function setProvides(array $provides)
{
@ -207,7 +207,7 @@ class MemoryPackage extends BasePackage
/**
* Set the packages this one replaces
*
* @param array $conflicts A set of package relations
* @param array $conflicts A set of package links
*/
public function setReplaces(array $replaces)
{
@ -225,7 +225,7 @@ class MemoryPackage extends BasePackage
/**
* Set the recommended packages
*
* @param array $conflicts A set of package relations
* @param array $conflicts A set of package links
*/
public function setRecommends(array $recommends)
{
@ -243,7 +243,7 @@ class MemoryPackage extends BasePackage
/**
* Set the suggested packages
*
* @param array $conflicts A set of package relations
* @param array $conflicts A set of package links
*/
public function setSuggests(array $suggests)
{

View File

@ -12,7 +12,7 @@
namespace Composer\Package;
use Composer\DependencyResolver\RelationConstraint\RelationConstraintInterface;
use Composer\Package\LinkConstraint\LinkConstraintInterface;
use Composer\Repository\RepositoryInterface;
/**
@ -41,11 +41,11 @@ interface PackageInterface
* Checks if the package matches the given constraint directly or through
* provided or replaced packages
*
* @param string $name Name of the package to be matched
* @param RelationConstraintInterface $constraint The constraint to verify
* @return bool Whether this package matches the name and constraint
* @param string $name Name of the package to be matched
* @param LinkConstraintInterface $constraint The constraint to verify
* @return bool Whether this package matches the name and constraint
*/
function matches($name, RelationConstraintInterface $constraint);
function matches($name, LinkConstraintInterface $constraint);
/**
* Returns the package type, e.g. library
@ -90,50 +90,50 @@ interface PackageInterface
function getLicense();
/**
* Returns a set of relations to packages which need to be installed before
* Returns a set of links to packages which need to be installed before
* this package can be installed
*
* @return array An array of package relations defining required packages
* @return array An array of package links defining required packages
*/
function getRequires();
/**
* Returns a set of relations to packages which must not be installed at the
* Returns a set of links to packages which must not be installed at the
* same time as this package
*
* @return array An array of package relations defining conflicting packages
* @return array An array of package links defining conflicting packages
*/
function getConflicts();
/**
* Returns a set of relations to virtual packages that are provided through
* Returns a set of links to virtual packages that are provided through
* this package
*
* @return array An array of package relations defining provided packages
* @return array An array of package links defining provided packages
*/
function getProvides();
/**
* Returns a set of relations to packages which can alternatively be
* Returns a set of links to packages which can alternatively be
* satisfied by installing this package
*
* @return array An array of package relations defining replaced packages
* @return array An array of package links defining replaced packages
*/
function getReplaces();
/**
* Returns a set of relations to packages which are recommended in
* Returns a set of links to packages which are recommended in
* combination with this package.
*
* @return array An array of package relations defining recommended packages
* @return array An array of package links defining recommended packages
*/
function getRecommends();
/**
* Returns a set of relations to packages which are suggested in combination
* Returns a set of links to packages which are suggested in combination
* with this package.
*
* @return array An array of package relations defining suggested packages
* @return array An array of package links defining suggested packages
*/
function getSuggests();