Merge branch 'disjunctive'
commit
9d948eb795
|
@ -13,27 +13,41 @@
|
||||||
namespace Composer\Package\LinkConstraint;
|
namespace Composer\Package\LinkConstraint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a conjunctive set of constraints on the target of a package link
|
* Defines a conjunctive or disjunctive set of constraints on the target of a package link
|
||||||
*
|
*
|
||||||
* @author Nils Adermann <naderman@naderman.de>
|
* @author Nils Adermann <naderman@naderman.de>
|
||||||
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||||
*/
|
*/
|
||||||
class MultiConstraint implements LinkConstraintInterface
|
class MultiConstraint implements LinkConstraintInterface
|
||||||
{
|
{
|
||||||
protected $constraints;
|
protected $constraints;
|
||||||
protected $prettyString;
|
protected $prettyString;
|
||||||
|
protected $conjunctive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets operator and version to compare a package with
|
* Sets operator and version to compare a package with
|
||||||
*
|
*
|
||||||
* @param array $constraints A conjunctive set of constraints
|
* @param array $constraints A set of constraints
|
||||||
|
* @param bool $conjunctive Whether the constraints should be treated as conjunctive or disjunctive
|
||||||
*/
|
*/
|
||||||
public function __construct(array $constraints)
|
public function __construct(array $constraints, $conjunctive = true)
|
||||||
{
|
{
|
||||||
$this->constraints = $constraints;
|
$this->constraints = $constraints;
|
||||||
|
$this->conjunctive = $conjunctive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function matches(LinkConstraintInterface $provider)
|
public function matches(LinkConstraintInterface $provider)
|
||||||
{
|
{
|
||||||
|
if (false === $this->conjunctive) {
|
||||||
|
foreach ($this->constraints as $constraint) {
|
||||||
|
if ($constraint->matches($provider)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($this->constraints as $constraint) {
|
foreach ($this->constraints as $constraint) {
|
||||||
if (!$constraint->matches($provider)) {
|
if (!$constraint->matches($provider)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -64,6 +78,6 @@ class MultiConstraint implements LinkConstraintInterface
|
||||||
$constraints[] = $constraint->__toString();
|
$constraints[] = $constraint->__toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return '['.implode(', ', $constraints).']';
|
return '['.implode($this->conjunctive ? ', ' : ' | ', $constraints).']';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,21 +222,33 @@ class VersionParser
|
||||||
$constraints = $match[1];
|
$constraints = $match[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
$constraints = preg_split('{\s*,\s*}', trim($constraints));
|
$orConstraints = preg_split('{\s*\|\s*}', trim($constraints));
|
||||||
|
$orGroups = array();
|
||||||
|
foreach ($orConstraints as $constraints) {
|
||||||
|
$andConstraints = preg_split('{\s*,\s*}', $constraints);
|
||||||
|
|
||||||
if (count($constraints) > 1) {
|
if (count($andConstraints) > 1) {
|
||||||
$constraintObjects = array();
|
$constraintObjects = array();
|
||||||
foreach ($constraints as $constraint) {
|
foreach ($andConstraints as $constraint) {
|
||||||
$constraintObjects = array_merge($constraintObjects, $this->parseConstraint($constraint));
|
$constraintObjects = array_merge($constraintObjects, $this->parseConstraint($constraint));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$constraintObjects = $this->parseConstraint($andConstraints[0]);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$constraintObjects = $this->parseConstraint($constraints[0]);
|
if (1 === count($constraintObjects)) {
|
||||||
|
$constraint = $constraintObjects[0];
|
||||||
|
} else {
|
||||||
|
$constraint = new MultiConstraint($constraintObjects);
|
||||||
|
}
|
||||||
|
|
||||||
|
$orGroups[] = $constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1 === count($constraintObjects)) {
|
if (1 === count($orGroups)) {
|
||||||
$constraint = $constraintObjects[0];
|
$constraint = $orGroups[0];
|
||||||
} else {
|
} else {
|
||||||
$constraint = new MultiConstraint($constraintObjects);
|
$constraint = new MultiConstraint($orGroups, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$constraint->setPrettyString($prettyConstraint);
|
$constraint->setPrettyString($prettyConstraint);
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
--TEST--
|
||||||
|
Disjunctive multi constraints work
|
||||||
|
--COMPOSER--
|
||||||
|
{
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "package",
|
||||||
|
"package": [
|
||||||
|
{ "name": "foo", "version": "1.1.0" },
|
||||||
|
{ "name": "foo", "version": "1.0.0" },
|
||||||
|
{ "name": "bar", "version": "1.1.0", "require": { "foo": "1.0.*" } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"bar": "1.*",
|
||||||
|
"foo": "1.0.*|1.1.*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--RUN--
|
||||||
|
install
|
||||||
|
--EXPECT--
|
||||||
|
Installing foo (1.0.0)
|
||||||
|
Installing bar (1.1.0)
|
|
@ -285,6 +285,17 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertSame((string) $multi, (string) $parser->parseConstraints('>2.0,<=3.0'));
|
$this->assertSame((string) $multi, (string) $parser->parseConstraints('>2.0,<=3.0'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testParseConstraintsMultiDisjunctiveHasPrioOverConjuctive()
|
||||||
|
{
|
||||||
|
$parser = new VersionParser;
|
||||||
|
$first = new VersionConstraint('>', '2.0.0.0');
|
||||||
|
$second = new VersionConstraint('<', '2.0.5.0-dev');
|
||||||
|
$third = new VersionConstraint('>', '2.0.6.0');
|
||||||
|
$multi1 = new MultiConstraint(array($first, $second));
|
||||||
|
$multi2 = new MultiConstraint(array($multi1, $third), false);
|
||||||
|
$this->assertSame((string) $multi2, (string) $parser->parseConstraints('>2.0,<2.0.5 | >2.0.6'));
|
||||||
|
}
|
||||||
|
|
||||||
public function testParseConstraintsMultiWithStabilities()
|
public function testParseConstraintsMultiWithStabilities()
|
||||||
{
|
{
|
||||||
$parser = new VersionParser;
|
$parser = new VersionParser;
|
||||||
|
|
Loading…
Reference in New Issue