Add disjunctive multi-constraints with |, refs #643, fixes #1342

main
Jordi Boggiano 11 years ago
parent 37894f66a1
commit 0cccafbe81

@ -13,27 +13,41 @@
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 Jordi Boggiano <j.boggiano@seld.be>
*/
class MultiConstraint implements LinkConstraintInterface
{
protected $constraints;
protected $prettyString;
protected $conjunctive;
/**
* 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->conjunctive = $conjunctive;
}
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) {
if (!$constraint->matches($provider)) {
return false;
@ -64,6 +78,6 @@ class MultiConstraint implements LinkConstraintInterface
$constraints[] = $constraint->__toString();
}
return '['.implode(', ', $constraints).']';
return '['.implode($this->conjunctive ? ', ' : ' | ', $constraints).']';
}
}

@ -221,21 +221,33 @@ class VersionParser
$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($andConstraints) > 1) {
$constraintObjects = array();
foreach ($andConstraints as $constraint) {
$constraintObjects = array_merge($constraintObjects, $this->parseConstraint($constraint));
}
} else {
$constraintObjects = $this->parseConstraint($andConstraints[0]);
}
if (count($constraints) > 1) {
$constraintObjects = array();
foreach ($constraints as $constraint) {
$constraintObjects = array_merge($constraintObjects, $this->parseConstraint($constraint));
if (1 === count($constraintObjects)) {
$constraint = $constraintObjects[0];
} else {
$constraint = new MultiConstraint($constraintObjects);
}
} else {
$constraintObjects = $this->parseConstraint($constraints[0]);
$orGroups[] = $constraint;
}
if (1 === count($constraintObjects)) {
$constraint = $constraintObjects[0];
if (1 === count($orGroups)) {
$constraint = $orGroups[0];
} else {
$constraint = new MultiConstraint($constraintObjects);
$constraint = new MultiConstraint($orGroups, false);
}
$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)

@ -284,6 +284,17 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase
$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()
{
$parser = new VersionParser;

Loading…
Cancel
Save