add semver, deprecated existing classes
parent
15face5432
commit
1ccfc8eb96
|
@ -24,7 +24,8 @@
|
|||
"require": {
|
||||
"php": ">=5.3.2",
|
||||
"justinrainbow/json-schema": "^1.4.4",
|
||||
"composer/spdx-licenses": "~1.0",
|
||||
"composer/spdx-licenses": "^1.0",
|
||||
"composer/semver": "^1.0",
|
||||
"seld/jsonlint": "~1.0",
|
||||
"symfony/console": "~2.5",
|
||||
"symfony/finder": "~2.2",
|
||||
|
|
|
@ -4,9 +4,69 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "3024e89a7e808b8dece156112459a7ea",
|
||||
"content-hash": "01608741fe66bb9528d7c77c0a422965",
|
||||
"hash": "af3956ae4c1a09e3e72cd66346a6176d",
|
||||
"packages": [
|
||||
{
|
||||
"name": "composer/semver",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/semver.git",
|
||||
"reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/semver/zipball/d0e1ccc6d44ab318b758d709e19176037da6b1ba",
|
||||
"reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.5",
|
||||
"phpunit/phpunit-mock-objects": "~2.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\Semver\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Rob Bast",
|
||||
"email": "rob.bast@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nils Adermann",
|
||||
"email": "naderman@naderman.de",
|
||||
"homepage": "http://www.naderman.de"
|
||||
},
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"description": "Semver library that offers utilities, version constraint parsing and validation.",
|
||||
"keywords": [
|
||||
"semantic",
|
||||
"semver",
|
||||
"validation",
|
||||
"versioning"
|
||||
],
|
||||
"time": "2015-09-21 09:42:36"
|
||||
},
|
||||
{
|
||||
"name": "composer/spdx-licenses",
|
||||
"version": "1.1.1",
|
||||
|
|
|
@ -12,36 +12,13 @@
|
|||
|
||||
namespace Composer\Package\LinkConstraint;
|
||||
|
||||
use Composer\Semver\Constraint\EmptyConstraint as BaseEmptyConstraint;
|
||||
|
||||
@trigger_error('The ' . __NAMESPACE__ . '\EmptyConstraint class is deprecated, use Composer\Semver\Constraint\EmptyConstraint instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Defines an absence of constraints
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @deprecated use Composer\Semver\Constraint\EmptyConstraint instead
|
||||
*/
|
||||
class EmptyConstraint implements LinkConstraintInterface
|
||||
class EmptyConstraint extends BaseEmptyConstraint
|
||||
{
|
||||
protected $prettyString;
|
||||
|
||||
public function matches(LinkConstraintInterface $provider)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setPrettyString($prettyString)
|
||||
{
|
||||
$this->prettyString = $prettyString;
|
||||
}
|
||||
|
||||
public function getPrettyString()
|
||||
{
|
||||
if ($this->prettyString) {
|
||||
return $this->prettyString;
|
||||
}
|
||||
|
||||
return $this->__toString();
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return '[]';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,15 +12,13 @@
|
|||
|
||||
namespace Composer\Package\LinkConstraint;
|
||||
|
||||
use Composer\Semver\Constraint\ConstraintInterface;
|
||||
|
||||
@trigger_error('The ' . __NAMESPACE__ . '\LinkConstraintInterface interface is deprecated, use Composer\Semver\Constraint\ConstraintInterface instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Defines a constraint on a link between two packages.
|
||||
*
|
||||
* @author Nils Adermann <naderman@naderman.de>
|
||||
* @deprecated use Composer\Semver\Constraint\ConstraintInterface instead
|
||||
*/
|
||||
interface LinkConstraintInterface
|
||||
interface LinkConstraintInterface extends ConstraintInterface
|
||||
{
|
||||
public function matches(LinkConstraintInterface $provider);
|
||||
public function setPrettyString($prettyString);
|
||||
public function getPrettyString();
|
||||
public function __toString();
|
||||
}
|
||||
|
|
|
@ -12,72 +12,13 @@
|
|||
|
||||
namespace Composer\Package\LinkConstraint;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
use Composer\Semver\Constraint\MultiConstraint as BaseMultiConstraint;
|
||||
|
||||
@trigger_error('The ' . __NAMESPACE__ . '\MultiConstraint class is deprecated, use Composer\Semver\Constraint\MultiConstraint instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Sets operator and version to compare a package with
|
||||
*
|
||||
* @param array $constraints A set of constraints
|
||||
* @param bool $conjunctive Whether the constraints should be treated as conjunctive or disjunctive
|
||||
* @deprecated use Composer\Semver\Constraint\MultiConstraint instead
|
||||
*/
|
||||
public function __construct(array $constraints, $conjunctive = true)
|
||||
class MultiConstraint extends BaseMultiConstraint
|
||||
{
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setPrettyString($prettyString)
|
||||
{
|
||||
$this->prettyString = $prettyString;
|
||||
}
|
||||
|
||||
public function getPrettyString()
|
||||
{
|
||||
if ($this->prettyString) {
|
||||
return $this->prettyString;
|
||||
}
|
||||
|
||||
return $this->__toString();
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
$constraints = array();
|
||||
foreach ($this->constraints as $constraint) {
|
||||
$constraints[] = $constraint->__toString();
|
||||
}
|
||||
|
||||
return '['.implode($this->conjunctive ? ' ' : ' || ', $constraints).']';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,42 +12,13 @@
|
|||
|
||||
namespace Composer\Package\LinkConstraint;
|
||||
|
||||
use Composer\Semver\Constraint\AbstractConstraint;
|
||||
|
||||
@trigger_error('The ' . __NAMESPACE__ . '\SpecificConstraint abstract class is deprecated, use Composer\Semver\Constraint\AbstractConstraint instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Provides a common basis for specific package link constraints
|
||||
*
|
||||
* @author Nils Adermann <naderman@naderman.de>
|
||||
* @deprecated use Composer\Semver\Constraint\AbstractConstraint instead
|
||||
*/
|
||||
abstract class SpecificConstraint implements LinkConstraintInterface
|
||||
abstract class SpecificConstraint extends AbstractConstraint
|
||||
{
|
||||
protected $prettyString;
|
||||
|
||||
public function matches(LinkConstraintInterface $provider)
|
||||
{
|
||||
if ($provider instanceof MultiConstraint) {
|
||||
// turn matching around to find a match
|
||||
return $provider->matches($this);
|
||||
} elseif ($provider instanceof $this) {
|
||||
return $this->matchSpecific($provider);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setPrettyString($prettyString)
|
||||
{
|
||||
$this->prettyString = $prettyString;
|
||||
}
|
||||
|
||||
public function getPrettyString()
|
||||
{
|
||||
if ($this->prettyString) {
|
||||
return $this->prettyString;
|
||||
}
|
||||
|
||||
return $this->__toString();
|
||||
}
|
||||
|
||||
// implementations must implement a method of this format:
|
||||
// not declared abstract here because type hinting violates parameter coherence (TODO right word?)
|
||||
// public function matchSpecific(<SpecificConstraintType> $provider);
|
||||
}
|
||||
|
|
|
@ -12,116 +12,13 @@
|
|||
|
||||
namespace Composer\Package\LinkConstraint;
|
||||
|
||||
/**
|
||||
* Constrains a package link based on package version
|
||||
*
|
||||
* Version numbers must be compatible with version_compare
|
||||
*
|
||||
* @author Nils Adermann <naderman@naderman.de>
|
||||
*/
|
||||
class VersionConstraint extends SpecificConstraint
|
||||
{
|
||||
const OP_EQ = 0;
|
||||
const OP_LT = 1;
|
||||
const OP_LE = 2;
|
||||
const OP_GT = 3;
|
||||
const OP_GE = 4;
|
||||
const OP_NE = 5;
|
||||
use Composer\Semver\Constraint\Constraint;
|
||||
|
||||
private static $transOpStr = array(
|
||||
'=' => self::OP_EQ,
|
||||
'==' => self::OP_EQ,
|
||||
'<' => self::OP_LT,
|
||||
'<=' => self::OP_LE,
|
||||
'>' => self::OP_GT,
|
||||
'>=' => self::OP_GE,
|
||||
'<>' => self::OP_NE,
|
||||
'!=' => self::OP_NE,
|
||||
);
|
||||
|
||||
private static $transOpInt = array(
|
||||
self::OP_EQ => '==',
|
||||
self::OP_LT => '<',
|
||||
self::OP_LE => '<=',
|
||||
self::OP_GT => '>',
|
||||
self::OP_GE => '>=',
|
||||
self::OP_NE => '!=',
|
||||
);
|
||||
|
||||
private $operator;
|
||||
private $version;
|
||||
@trigger_error('The ' . __NAMESPACE__ . '\VersionConstraint class is deprecated, use Composer\Semver\Constraint\Constraint instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Sets operator and version to compare a package with
|
||||
*
|
||||
* @param string $operator A comparison operator
|
||||
* @param string $version A version to compare to
|
||||
* @deprecated use Composer\Semver\Constraint\Constraint instead
|
||||
*/
|
||||
public function __construct($operator, $version)
|
||||
class VersionConstraint extends Constraint
|
||||
{
|
||||
$this->operator = self::$transOpStr[$operator];
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
public function versionCompare($a, $b, $operator, $compareBranches = false)
|
||||
{
|
||||
$aIsBranch = 'dev-' === substr($a, 0, 4);
|
||||
$bIsBranch = 'dev-' === substr($b, 0, 4);
|
||||
if ($aIsBranch && $bIsBranch) {
|
||||
return $operator == '==' && $a === $b;
|
||||
}
|
||||
|
||||
// when branches are not comparable, we make sure dev branches never match anything
|
||||
if (!$compareBranches && ($aIsBranch || $bIsBranch)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return version_compare($a, $b, $operator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param VersionConstraint $provider
|
||||
* @param bool $compareBranches
|
||||
* @return bool
|
||||
*/
|
||||
public function matchSpecific(VersionConstraint $provider, $compareBranches = false)
|
||||
{
|
||||
$noEqualOp = str_replace('=', '', self::$transOpInt[$this->operator]);
|
||||
$providerNoEqualOp = str_replace('=', '', self::$transOpInt[$provider->operator]);
|
||||
|
||||
$isEqualOp = self::OP_EQ === $this->operator;
|
||||
$isNonEqualOp = self::OP_NE === $this->operator;
|
||||
$isProviderEqualOp = self::OP_EQ === $provider->operator;
|
||||
$isProviderNonEqualOp = self::OP_NE === $provider->operator;
|
||||
|
||||
// '!=' operator is match when other operator is not '==' operator or version is not match
|
||||
// these kinds of comparisons always have a solution
|
||||
if ($isNonEqualOp || $isProviderNonEqualOp) {
|
||||
return !$isEqualOp && !$isProviderEqualOp
|
||||
|| $this->versionCompare($provider->version, $this->version, '!=', $compareBranches);
|
||||
}
|
||||
|
||||
// an example for the condition is <= 2.0 & < 1.0
|
||||
// these kinds of comparisons always have a solution
|
||||
if ($this->operator !== self::OP_EQ && $noEqualOp == $providerNoEqualOp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->versionCompare($provider->version, $this->version, self::$transOpInt[$this->operator], $compareBranches)) {
|
||||
// special case, e.g. require >= 1.0 and provide < 1.0
|
||||
// 1.0 >= 1.0 but 1.0 is outside of the provided interval
|
||||
if ($provider->version == $this->version && self::$transOpInt[$provider->operator] == $providerNoEqualOp && self::$transOpInt[$this->operator] != $noEqualOp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return self::$transOpInt[$this->operator].' '.$this->version;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,513 +12,14 @@
|
|||
|
||||
namespace Composer\Package\Version;
|
||||
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\Link;
|
||||
use Composer\Package\LinkConstraint\EmptyConstraint;
|
||||
use Composer\Package\LinkConstraint\MultiConstraint;
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
use Composer\Package\Loader\ArrayLoader;
|
||||
use Composer\Semver\VersionParser as BaseVersionParser;
|
||||
|
||||
class VersionParser extends BaseVersionParser
|
||||
{
|
||||
/**
|
||||
* Version parser
|
||||
* @param array $pairs
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class VersionParser
|
||||
{
|
||||
private static $modifierRegex = '[._-]?(?:(stable|beta|b|RC|alpha|a|patch|pl|p)(?:[.-]?(\d+))?)?([.-]?dev)?';
|
||||
|
||||
private static $stabilities = array(
|
||||
'stable', 'RC', 'beta', 'alpha', 'dev',
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the stability of a version
|
||||
*
|
||||
* @param string $version
|
||||
* @return string
|
||||
*/
|
||||
public static function parseStability($version)
|
||||
{
|
||||
$version = preg_replace('{#.+$}i', '', $version);
|
||||
|
||||
if ('dev-' === substr($version, 0, 4) || '-dev' === substr($version, -4)) {
|
||||
return 'dev';
|
||||
}
|
||||
|
||||
preg_match('{'.self::$modifierRegex.'$}i', strtolower($version), $match);
|
||||
if (!empty($match[3])) {
|
||||
return 'dev';
|
||||
}
|
||||
|
||||
if (!empty($match[1])) {
|
||||
if ('beta' === $match[1] || 'b' === $match[1]) {
|
||||
return 'beta';
|
||||
}
|
||||
if ('alpha' === $match[1] || 'a' === $match[1]) {
|
||||
return 'alpha';
|
||||
}
|
||||
if ('rc' === $match[1]) {
|
||||
return 'RC';
|
||||
}
|
||||
}
|
||||
|
||||
return 'stable';
|
||||
}
|
||||
|
||||
public static function normalizeStability($stability)
|
||||
{
|
||||
$stability = strtolower($stability);
|
||||
|
||||
return $stability === 'rc' ? 'RC' : $stability;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use PackageInterface::getFullPrettyVersion instead
|
||||
*/
|
||||
public static function formatVersion(PackageInterface $package, $truncate = true)
|
||||
{
|
||||
trigger_error(__METHOD__.' is deprecated. Use '.
|
||||
'\Composer\Package\PackageInterface::getFullPrettyVersion() instead', E_USER_DEPRECATED);
|
||||
|
||||
return $package->getFullPrettyVersion($truncate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a version string to be able to perform comparisons on it
|
||||
*
|
||||
* @param string $version
|
||||
* @param string $fullVersion optional complete version string to give more context
|
||||
* @throws \UnexpectedValueException
|
||||
* @return string
|
||||
*/
|
||||
public function normalize($version, $fullVersion = null)
|
||||
{
|
||||
$version = trim($version);
|
||||
if (null === $fullVersion) {
|
||||
$fullVersion = $version;
|
||||
}
|
||||
|
||||
// ignore aliases and just assume the alias is required instead of the source
|
||||
if (preg_match('{^([^,\s]+) +as +([^,\s]+)$}', $version, $match)) {
|
||||
$version = $match[1];
|
||||
}
|
||||
|
||||
// ignore build metadata
|
||||
if (preg_match('{^([^,\s+]+)\+[^\s]+$}', $version, $match)) {
|
||||
$version = $match[1];
|
||||
}
|
||||
|
||||
// match master-like branches
|
||||
if (preg_match('{^(?:dev-)?(?:master|trunk|default)$}i', $version)) {
|
||||
return '9999999-dev';
|
||||
}
|
||||
|
||||
if ('dev-' === strtolower(substr($version, 0, 4))) {
|
||||
return 'dev-'.substr($version, 4);
|
||||
}
|
||||
|
||||
// match classical versioning
|
||||
if (preg_match('{^v?(\d{1,3})(\.\d+)?(\.\d+)?(\.\d+)?'.self::$modifierRegex.'$}i', $version, $matches)) {
|
||||
$version = $matches[1]
|
||||
.(!empty($matches[2]) ? $matches[2] : '.0')
|
||||
.(!empty($matches[3]) ? $matches[3] : '.0')
|
||||
.(!empty($matches[4]) ? $matches[4] : '.0');
|
||||
$index = 5;
|
||||
} elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)'.self::$modifierRegex.'$}i', $version, $matches)) { // match date-based versioning
|
||||
$version = preg_replace('{\D}', '-', $matches[1]);
|
||||
$index = 2;
|
||||
} elseif (preg_match('{^v?(\d{4,})(\.\d+)?(\.\d+)?(\.\d+)?'.self::$modifierRegex.'$}i', $version, $matches)) {
|
||||
$version = $matches[1]
|
||||
.(!empty($matches[2]) ? $matches[2] : '.0')
|
||||
.(!empty($matches[3]) ? $matches[3] : '.0')
|
||||
.(!empty($matches[4]) ? $matches[4] : '.0');
|
||||
$index = 5;
|
||||
}
|
||||
|
||||
// add version modifiers if a version was matched
|
||||
if (isset($index)) {
|
||||
if (!empty($matches[$index])) {
|
||||
if ('stable' === $matches[$index]) {
|
||||
return $version;
|
||||
}
|
||||
$version .= '-' . $this->expandStability($matches[$index]) . (!empty($matches[$index + 1]) ? $matches[$index + 1] : '');
|
||||
}
|
||||
|
||||
if (!empty($matches[$index + 2])) {
|
||||
$version .= '-dev';
|
||||
}
|
||||
|
||||
return $version;
|
||||
}
|
||||
|
||||
// match dev branches
|
||||
if (preg_match('{(.*?)[.-]?dev$}i', $version, $match)) {
|
||||
try {
|
||||
return $this->normalizeBranch($match[1]);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
$extraMessage = '';
|
||||
if (preg_match('{ +as +'.preg_quote($version).'$}', $fullVersion)) {
|
||||
$extraMessage = ' in "'.$fullVersion.'", the alias must be an exact version';
|
||||
} elseif (preg_match('{^'.preg_quote($version).' +as +}', $fullVersion)) {
|
||||
$extraMessage = ' in "'.$fullVersion.'", the alias source must be an exact version, if it is a branch name you should prefix it with dev-';
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('Invalid version string "'.$version.'"'.$extraMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract numeric prefix from alias, if it is in numeric format, suitable for
|
||||
* version comparison
|
||||
*
|
||||
* @param string $branch Branch name (e.g. 2.1.x-dev)
|
||||
* @return string|false Numeric prefix if present (e.g. 2.1.) or false
|
||||
*/
|
||||
public function parseNumericAliasPrefix($branch)
|
||||
{
|
||||
if (preg_match('/^(?P<version>(\d+\\.)*\d+)(?:\.x)?-dev$/i', $branch, $matches)) {
|
||||
return $matches['version'].".";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a branch name to be able to perform comparisons on it
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function normalizeBranch($name)
|
||||
{
|
||||
$name = trim($name);
|
||||
|
||||
if (in_array($name, array('master', 'trunk', 'default'))) {
|
||||
return $this->normalize($name);
|
||||
}
|
||||
|
||||
if (preg_match('#^v?(\d+)(\.(?:\d+|[xX*]))?(\.(?:\d+|[xX*]))?(\.(?:\d+|[xX*]))?$#i', $name, $matches)) {
|
||||
$version = '';
|
||||
for ($i = 1; $i < 5; $i++) {
|
||||
$version .= isset($matches[$i]) ? str_replace(array('*', 'X'), 'x', $matches[$i]) : '.x';
|
||||
}
|
||||
|
||||
return str_replace('x', '9999999', $version).'-dev';
|
||||
}
|
||||
|
||||
return 'dev-'.$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use ArrayLoader::parseLinks() instead
|
||||
* @param string $source source package name
|
||||
* @param string $sourceVersion source package version (pretty version ideally)
|
||||
* @param string $description link description (e.g. requires, replaces, ..)
|
||||
* @param array $links array of package name => constraint mappings
|
||||
* @return Link[]
|
||||
*/
|
||||
public function parseLinks($source, $sourceVersion, $description, $links)
|
||||
{
|
||||
trigger_error(__METHOD__.' is deprecated. Use '.
|
||||
'\Composer\Package\Loader\ArrayLoader::parseLinks() instead', E_USER_DEPRECATED);
|
||||
$loader = new ArrayLoader($this, false);
|
||||
|
||||
return $loader->parseLinks($source, $sourceVersion, $description, $links);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses as constraint string into LinkConstraint objects
|
||||
*
|
||||
* @param string $constraints
|
||||
* @return \Composer\Package\LinkConstraint\LinkConstraintInterface
|
||||
*/
|
||||
public function parseConstraints($constraints)
|
||||
{
|
||||
$prettyConstraint = $constraints;
|
||||
|
||||
if (preg_match('{^([^,\s]*?)@('.implode('|', self::$stabilities).')$}i', $constraints, $match)) {
|
||||
$constraints = empty($match[1]) ? '*' : $match[1];
|
||||
}
|
||||
|
||||
if (preg_match('{^(dev-[^,\s@]+?|[^,\s@]+?\.x-dev)#.+$}i', $constraints, $match)) {
|
||||
$constraints = $match[1];
|
||||
}
|
||||
|
||||
$orConstraints = preg_split('{\s*\|\|?\s*}', trim($constraints));
|
||||
$orGroups = array();
|
||||
foreach ($orConstraints as $constraints) {
|
||||
$andConstraints = preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $constraints);
|
||||
if (count($andConstraints) > 1) {
|
||||
$constraintObjects = array();
|
||||
foreach ($andConstraints as $constraint) {
|
||||
foreach ($this->parseConstraint($constraint) as $parsedConstraint) {
|
||||
$constraintObjects[] = $parsedConstraint;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$constraintObjects = $this->parseConstraint($andConstraints[0]);
|
||||
}
|
||||
|
||||
if (1 === count($constraintObjects)) {
|
||||
$constraint = $constraintObjects[0];
|
||||
} else {
|
||||
$constraint = new MultiConstraint($constraintObjects);
|
||||
}
|
||||
|
||||
$orGroups[] = $constraint;
|
||||
}
|
||||
|
||||
if (1 === count($orGroups)) {
|
||||
$constraint = $orGroups[0];
|
||||
} else {
|
||||
$constraint = new MultiConstraint($orGroups, false);
|
||||
}
|
||||
|
||||
$constraint->setPrettyString($prettyConstraint);
|
||||
|
||||
return $constraint;
|
||||
}
|
||||
|
||||
private function parseConstraint($constraint)
|
||||
{
|
||||
if (preg_match('{^([^,\s]+?)@('.implode('|', self::$stabilities).')$}i', $constraint, $match)) {
|
||||
$constraint = $match[1];
|
||||
if ($match[2] !== 'stable') {
|
||||
$stabilityModifier = $match[2];
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match('{^[xX*](\.[xX*])*$}i', $constraint)) {
|
||||
return array(new EmptyConstraint);
|
||||
}
|
||||
|
||||
$versionRegex = '(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?'.self::$modifierRegex;
|
||||
|
||||
// match tilde constraints
|
||||
// like wildcard constraints, unsuffixed tilde constraints say that they must be greater than the previous
|
||||
// version, to ensure that unstable instances of the current version are allowed.
|
||||
// however, if a stability suffix is added to the constraint, then a >= match on the current version is
|
||||
// used instead
|
||||
if (preg_match('{^~>?'.$versionRegex.'$}i', $constraint, $matches)) {
|
||||
if (substr($constraint, 0, 2) === '~>') {
|
||||
throw new \UnexpectedValueException(
|
||||
'Could not parse version constraint '.$constraint.': '.
|
||||
'Invalid operator "~>", you probably meant to use the "~" operator'
|
||||
);
|
||||
}
|
||||
|
||||
// Work out which position in the version we are operating at
|
||||
if (isset($matches[4]) && '' !== $matches[4]) {
|
||||
$position = 4;
|
||||
} elseif (isset($matches[3]) && '' !== $matches[3]) {
|
||||
$position = 3;
|
||||
} elseif (isset($matches[2]) && '' !== $matches[2]) {
|
||||
$position = 2;
|
||||
} else {
|
||||
$position = 1;
|
||||
}
|
||||
|
||||
// Calculate the stability suffix
|
||||
$stabilitySuffix = '';
|
||||
if (!empty($matches[5])) {
|
||||
$stabilitySuffix .= '-' . $this->expandStability($matches[5]) . (!empty($matches[6]) ? $matches[6] : '');
|
||||
}
|
||||
|
||||
if (!empty($matches[7])) {
|
||||
$stabilitySuffix .= '-dev';
|
||||
}
|
||||
|
||||
if (!$stabilitySuffix) {
|
||||
$stabilitySuffix = "-dev";
|
||||
}
|
||||
$lowVersion = $this->manipulateVersionString($matches, $position, 0) . $stabilitySuffix;
|
||||
$lowerBound = new VersionConstraint('>=', $lowVersion);
|
||||
|
||||
// For upper bound, we increment the position of one more significance,
|
||||
// but highPosition = 0 would be illegal
|
||||
$highPosition = max(1, $position - 1);
|
||||
$highVersion = $this->manipulateVersionString($matches, $highPosition, 1) . '-dev';
|
||||
$upperBound = new VersionConstraint('<', $highVersion);
|
||||
|
||||
return array(
|
||||
$lowerBound,
|
||||
$upperBound
|
||||
);
|
||||
}
|
||||
|
||||
// match caret constraints
|
||||
if (preg_match('{^\^'.$versionRegex.'($)}i', $constraint, $matches)) {
|
||||
// Work out which position in the version we are operating at
|
||||
if ('0' !== $matches[1] || '' === $matches[2]) {
|
||||
$position = 1;
|
||||
} elseif ('0' !== $matches[2] || '' === $matches[3]) {
|
||||
$position = 2;
|
||||
} else {
|
||||
$position = 3;
|
||||
}
|
||||
|
||||
// Calculate the stability suffix
|
||||
$stabilitySuffix = '';
|
||||
if (empty($matches[5]) && empty($matches[7])) {
|
||||
$stabilitySuffix .= '-dev';
|
||||
}
|
||||
|
||||
$lowVersion = $this->normalize(substr($constraint . $stabilitySuffix, 1));
|
||||
$lowerBound = new VersionConstraint('>=', $lowVersion);
|
||||
|
||||
// For upper bound, we increment the position of one more significance,
|
||||
// but highPosition = 0 would be illegal
|
||||
$highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
|
||||
$upperBound = new VersionConstraint('<', $highVersion);
|
||||
|
||||
return array(
|
||||
$lowerBound,
|
||||
$upperBound
|
||||
);
|
||||
}
|
||||
|
||||
// match wildcard constraints
|
||||
if (preg_match('{^(\d+)(?:\.(\d+))?(?:\.(\d+))?\.[xX*]$}', $constraint, $matches)) {
|
||||
if (isset($matches[3]) && '' !== $matches[3]) {
|
||||
$position = 3;
|
||||
} elseif (isset($matches[2]) && '' !== $matches[2]) {
|
||||
$position = 2;
|
||||
} else {
|
||||
$position = 1;
|
||||
}
|
||||
|
||||
$lowVersion = $this->manipulateVersionString($matches, $position) . "-dev";
|
||||
$highVersion = $this->manipulateVersionString($matches, $position, 1) . "-dev";
|
||||
|
||||
if ($lowVersion === "0.0.0.0-dev") {
|
||||
return array(new VersionConstraint('<', $highVersion));
|
||||
}
|
||||
|
||||
return array(
|
||||
new VersionConstraint('>=', $lowVersion),
|
||||
new VersionConstraint('<', $highVersion),
|
||||
);
|
||||
}
|
||||
|
||||
// match hyphen constraints
|
||||
if (preg_match('{^(?P<from>'.$versionRegex.') +- +(?P<to>'.$versionRegex.')($)}i', $constraint, $matches)) {
|
||||
// Calculate the stability suffix
|
||||
$lowStabilitySuffix = '';
|
||||
if (empty($matches[6]) && empty($matches[8])) {
|
||||
$lowStabilitySuffix = '-dev';
|
||||
}
|
||||
|
||||
$lowVersion = $this->normalize($matches['from']);
|
||||
$lowerBound = new VersionConstraint('>=', $lowVersion . $lowStabilitySuffix);
|
||||
|
||||
$empty = function ($x) {
|
||||
return ($x === 0 || $x === "0") ? false : empty($x);
|
||||
};
|
||||
|
||||
if ((!$empty($matches[11]) && !$empty($matches[12])) || !empty($matches[14]) || !empty($matches[16])) {
|
||||
$highVersion = $this->normalize($matches['to']);
|
||||
$upperBound = new VersionConstraint('<=', $highVersion);
|
||||
} else {
|
||||
$highMatch = array('', $matches[10], $matches[11], $matches[12], $matches[13]);
|
||||
$highVersion = $this->manipulateVersionString($highMatch, $empty($matches[11]) ? 1 : 2, 1) . '-dev';
|
||||
$upperBound = new VersionConstraint('<', $highVersion);
|
||||
}
|
||||
|
||||
return array(
|
||||
$lowerBound,
|
||||
$upperBound
|
||||
);
|
||||
}
|
||||
|
||||
// match operators constraints
|
||||
if (preg_match('{^(<>|!=|>=?|<=?|==?)?\s*(.*)}', $constraint, $matches)) {
|
||||
try {
|
||||
$version = $this->normalize($matches[2]);
|
||||
|
||||
if (!empty($stabilityModifier) && $this->parseStability($version) === 'stable') {
|
||||
$version .= '-' . $stabilityModifier;
|
||||
} elseif ('<' === $matches[1] || '>=' === $matches[1]) {
|
||||
if (!preg_match('/-' . self::$modifierRegex . '$/', strtolower($matches[2]))) {
|
||||
if (substr($matches[2], 0, 4) !== 'dev-') {
|
||||
$version .= '-dev';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array(new VersionConstraint($matches[1] ?: '=', $version));
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
$message = 'Could not parse version constraint '.$constraint;
|
||||
if (isset($e)) {
|
||||
$message .= ': '. $e->getMessage();
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment, decrement, or simply pad a version number.
|
||||
*
|
||||
* Support function for {@link parseConstraint()}
|
||||
*
|
||||
* @param array $matches Array with version parts in array indexes 1,2,3,4
|
||||
* @param int $position 1,2,3,4 - which segment of the version to decrement
|
||||
* @param int $increment
|
||||
* @param string $pad The string to pad version parts after $position
|
||||
* @return string The new version
|
||||
*/
|
||||
private function manipulateVersionString($matches, $position, $increment = 0, $pad = '0')
|
||||
{
|
||||
for ($i = 4; $i > 0; $i--) {
|
||||
if ($i > $position) {
|
||||
$matches[$i] = $pad;
|
||||
} elseif ($i == $position && $increment) {
|
||||
$matches[$i] += $increment;
|
||||
// If $matches[$i] was 0, carry the decrement
|
||||
if ($matches[$i] < 0) {
|
||||
$matches[$i] = $pad;
|
||||
$position--;
|
||||
|
||||
// Return null on a carry overflow
|
||||
if ($i == 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $matches[1] . '.' . $matches[2] . '.' . $matches[3] . '.' . $matches[4];
|
||||
}
|
||||
|
||||
private function expandStability($stability)
|
||||
{
|
||||
$stability = strtolower($stability);
|
||||
|
||||
switch ($stability) {
|
||||
case 'a':
|
||||
return 'alpha';
|
||||
case 'b':
|
||||
return 'beta';
|
||||
case 'p':
|
||||
case 'pl':
|
||||
return 'patch';
|
||||
case 'rc':
|
||||
return 'RC';
|
||||
default:
|
||||
return $stability;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a name/version pairs and returns an array of pairs + the
|
||||
*
|
||||
* @param array $pairs a set of package/version pairs separated by ":", "=" or " "
|
||||
* @return array[] array of arrays containing a name and (if provided) a version
|
||||
* @return array[]
|
||||
*/
|
||||
public function parseNameVersionPairs(array $pairs)
|
||||
{
|
||||
|
|
|
@ -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\Test\Package\LinkConstraint;
|
||||
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
use Composer\Package\LinkConstraint\MultiConstraint;
|
||||
|
||||
class MultiConstraintTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testMultiVersionMatchSucceeds()
|
||||
{
|
||||
$versionRequireStart = new VersionConstraint('>', '1.0');
|
||||
$versionRequireEnd = new VersionConstraint('<', '1.2');
|
||||
$versionProvide = new VersionConstraint('==', '1.1');
|
||||
|
||||
$multiRequire = new MultiConstraint(array($versionRequireStart, $versionRequireEnd));
|
||||
|
||||
$this->assertTrue($multiRequire->matches($versionProvide));
|
||||
}
|
||||
|
||||
public function testMultiVersionProvidedMatchSucceeds()
|
||||
{
|
||||
$versionRequireStart = new VersionConstraint('>', '1.0');
|
||||
$versionRequireEnd = new VersionConstraint('<', '1.2');
|
||||
$versionProvideStart = new VersionConstraint('>=', '1.1');
|
||||
$versionProvideEnd = new VersionConstraint('<', '2.0');
|
||||
|
||||
$multiRequire = new MultiConstraint(array($versionRequireStart, $versionRequireEnd));
|
||||
$multiProvide = new MultiConstraint(array($versionProvideStart, $versionProvideEnd));
|
||||
|
||||
$this->assertTrue($multiRequire->matches($multiProvide));
|
||||
}
|
||||
|
||||
public function testMultiVersionMatchFails()
|
||||
{
|
||||
$versionRequireStart = new VersionConstraint('>', '1.0');
|
||||
$versionRequireEnd = new VersionConstraint('<', '1.2');
|
||||
$versionProvide = new VersionConstraint('==', '1.2');
|
||||
|
||||
$multiRequire = new MultiConstraint(array($versionRequireStart, $versionRequireEnd));
|
||||
|
||||
$this->assertFalse($multiRequire->matches($versionProvide));
|
||||
}
|
||||
}
|
|
@ -1,105 +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\Test\Package\LinkConstraint;
|
||||
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
|
||||
class VersionConstraintTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public static function successfulVersionMatches()
|
||||
{
|
||||
return array(
|
||||
// require provide
|
||||
array('==', '1', '==', '1'),
|
||||
array('>=', '1', '>=', '2'),
|
||||
array('>=', '2', '>=', '1'),
|
||||
array('>=', '2', '>', '1'),
|
||||
array('<=', '2', '>=', '1'),
|
||||
array('>=', '1', '<=', '2'),
|
||||
array('==', '2', '>=', '2'),
|
||||
array('!=', '1', '!=', '1'),
|
||||
array('!=', '1', '==', '2'),
|
||||
array('!=', '1', '<', '1'),
|
||||
array('!=', '1', '<=', '1'),
|
||||
array('!=', '1', '>', '1'),
|
||||
array('!=', '1', '>=', '1'),
|
||||
array('==', 'dev-foo-bar', '==', 'dev-foo-bar'),
|
||||
array('==', 'dev-foo-xyz', '==', 'dev-foo-xyz'),
|
||||
array('>=', 'dev-foo-bar', '>=', 'dev-foo-xyz'),
|
||||
array('<=', 'dev-foo-bar', '<', 'dev-foo-xyz'),
|
||||
array('!=', 'dev-foo-bar', '<', 'dev-foo-xyz'),
|
||||
array('>=', 'dev-foo-bar', '!=', 'dev-foo-bar'),
|
||||
array('!=', 'dev-foo-bar', '!=', 'dev-foo-xyz'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider successfulVersionMatches
|
||||
*/
|
||||
public function testVersionMatchSucceeds($requireOperator, $requireVersion, $provideOperator, $provideVersion)
|
||||
{
|
||||
$versionRequire = new VersionConstraint($requireOperator, $requireVersion);
|
||||
$versionProvide = new VersionConstraint($provideOperator, $provideVersion);
|
||||
|
||||
$this->assertTrue($versionRequire->matches($versionProvide));
|
||||
}
|
||||
|
||||
public static function failingVersionMatches()
|
||||
{
|
||||
return array(
|
||||
// require provide
|
||||
array('==', '1', '==', '2'),
|
||||
array('>=', '2', '<=', '1'),
|
||||
array('>=', '2', '<', '2'),
|
||||
array('<=', '2', '>', '2'),
|
||||
array('>', '2', '<=', '2'),
|
||||
array('<=', '1', '>=', '2'),
|
||||
array('>=', '2', '<=', '1'),
|
||||
array('==', '2', '<', '2'),
|
||||
array('!=', '1', '==', '1'),
|
||||
array('==', '1', '!=', '1'),
|
||||
array('==', 'dev-foo-dist', '==', 'dev-foo-zist'),
|
||||
array('==', 'dev-foo-bist', '==', 'dev-foo-aist'),
|
||||
array('<=', 'dev-foo-bist', '>=', 'dev-foo-aist'),
|
||||
array('>=', 'dev-foo-bist', '<', 'dev-foo-aist'),
|
||||
array('<', '0.12', '==', 'dev-foo'), // branches are not comparable
|
||||
array('>', '0.12', '==', 'dev-foo'), // branches are not comparable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider failingVersionMatches
|
||||
*/
|
||||
public function testVersionMatchFails($requireOperator, $requireVersion, $provideOperator, $provideVersion)
|
||||
{
|
||||
$versionRequire = new VersionConstraint($requireOperator, $requireVersion);
|
||||
$versionProvide = new VersionConstraint($provideOperator, $provideVersion);
|
||||
|
||||
$this->assertFalse($versionRequire->matches($versionProvide));
|
||||
}
|
||||
|
||||
public function testComparableBranches()
|
||||
{
|
||||
$versionRequire = new VersionConstraint('>', '0.12');
|
||||
$versionProvide = new VersionConstraint('==', 'dev-foo');
|
||||
|
||||
$this->assertFalse($versionRequire->matches($versionProvide));
|
||||
$this->assertFalse($versionRequire->matchSpecific($versionProvide, true));
|
||||
|
||||
$versionRequire = new VersionConstraint('<', '0.12');
|
||||
$versionProvide = new VersionConstraint('==', 'dev-foo');
|
||||
|
||||
$this->assertFalse($versionRequire->matches($versionProvide));
|
||||
$this->assertTrue($versionRequire->matchSpecific($versionProvide, true));
|
||||
}
|
||||
}
|
|
@ -1,472 +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\Test\Package\Version;
|
||||
|
||||
use Composer\Package\Link;
|
||||
use Composer\Package\Version\VersionParser;
|
||||
use Composer\Package\LinkConstraint\MultiConstraint;
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
use Composer\Package\LinkConstraint\EmptyConstraint;
|
||||
use Composer\Package\PackageInterface;
|
||||
|
||||
class VersionParserTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @dataProvider numericAliasVersions
|
||||
*/
|
||||
public function testParseNumericAliasPrefix($input, $expected)
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$this->assertSame($expected, $parser->parseNumericAliasPrefix($input));
|
||||
}
|
||||
|
||||
public function numericAliasVersions()
|
||||
{
|
||||
return array(
|
||||
array('0.x-dev', '0.'),
|
||||
array('1.0.x-dev', '1.0.'),
|
||||
array('1.x-dev', '1.'),
|
||||
array('1.2.x-dev', '1.2.'),
|
||||
array('1.2-dev', '1.2.'),
|
||||
array('1-dev', '1.'),
|
||||
array('dev-develop', false),
|
||||
array('dev-master', false),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider successfulNormalizedVersions
|
||||
*/
|
||||
public function testNormalizeSucceeds($input, $expected)
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$this->assertSame($expected, $parser->normalize($input));
|
||||
}
|
||||
|
||||
public function successfulNormalizedVersions()
|
||||
{
|
||||
return array(
|
||||
'none' => array('1.0.0', '1.0.0.0'),
|
||||
'none/2' => array('1.2.3.4', '1.2.3.4'),
|
||||
'parses state' => array('1.0.0RC1dev', '1.0.0.0-RC1-dev'),
|
||||
'CI parsing' => array('1.0.0-rC15-dev', '1.0.0.0-RC15-dev'),
|
||||
'delimiters' => array('1.0.0.RC.15-dev', '1.0.0.0-RC15-dev'),
|
||||
'RC uppercase' => array('1.0.0-rc1', '1.0.0.0-RC1'),
|
||||
'patch replace' => array('1.0.0.pl3-dev', '1.0.0.0-patch3-dev'),
|
||||
'forces w.x.y.z' => array('1.0-dev', '1.0.0.0-dev'),
|
||||
'forces w.x.y.z/2' => array('0', '0.0.0.0'),
|
||||
'parses long' => array('10.4.13-beta', '10.4.13.0-beta'),
|
||||
'parses long/2' => array('10.4.13beta2', '10.4.13.0-beta2'),
|
||||
'parses long/semver' => array('10.4.13beta.2', '10.4.13.0-beta2'),
|
||||
'expand shorthand' => array('10.4.13-b', '10.4.13.0-beta'),
|
||||
'expand shorthand2' => array('10.4.13-b5', '10.4.13.0-beta5'),
|
||||
'strips leading v' => array('v1.0.0', '1.0.0.0'),
|
||||
'strips v/datetime' => array('v20100102', '20100102'),
|
||||
'parses dates y-m' => array('2010.01', '2010-01'),
|
||||
'parses dates w/ .' => array('2010.01.02', '2010-01-02'),
|
||||
'parses dates w/ -' => array('2010-01-02', '2010-01-02'),
|
||||
'parses numbers' => array('2010-01-02.5', '2010-01-02-5'),
|
||||
'parses dates y.m.Y' => array('2010.1.555', '2010.1.555.0'),
|
||||
'parses datetime' => array('20100102-203040', '20100102-203040'),
|
||||
'parses dt+number' => array('20100102203040-10', '20100102203040-10'),
|
||||
'parses dt+patch' => array('20100102-203040-p1', '20100102-203040-patch1'),
|
||||
'parses master' => array('dev-master', '9999999-dev'),
|
||||
'parses trunk' => array('dev-trunk', '9999999-dev'),
|
||||
'parses branches' => array('1.x-dev', '1.9999999.9999999.9999999-dev'),
|
||||
'parses arbitrary' => array('dev-feature-foo', 'dev-feature-foo'),
|
||||
'parses arbitrary2' => array('DEV-FOOBAR', 'dev-FOOBAR'),
|
||||
'parses arbitrary3' => array('dev-feature/foo', 'dev-feature/foo'),
|
||||
'ignores aliases' => array('dev-master as 1.0.0', '9999999-dev'),
|
||||
'semver metadata' => array('dev-master+foo.bar', '9999999-dev'),
|
||||
'semver metadata/2' => array('1.0.0-beta.5+foo', '1.0.0.0-beta5'),
|
||||
'semver metadata/3' => array('1.0.0+foo', '1.0.0.0'),
|
||||
'metadata w/ alias' => array('1.0.0+foo as 2.0', '1.0.0.0'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider failingNormalizedVersions
|
||||
* @expectedException UnexpectedValueException
|
||||
*/
|
||||
public function testNormalizeFails($input)
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$parser->normalize($input);
|
||||
}
|
||||
|
||||
public function failingNormalizedVersions()
|
||||
{
|
||||
return array(
|
||||
'empty ' => array(''),
|
||||
'invalid chars' => array('a'),
|
||||
'invalid type' => array('1.0.0-meh'),
|
||||
'too many bits' => array('1.0.0.0.0'),
|
||||
'non-dev arbitrary' => array('feature-foo'),
|
||||
'metadata w/ space' => array('1.0.0+foo bar'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider successfulNormalizedBranches
|
||||
*/
|
||||
public function testNormalizeBranch($input, $expected)
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$this->assertSame((string) $expected, (string) $parser->normalizeBranch($input));
|
||||
}
|
||||
|
||||
public function successfulNormalizedBranches()
|
||||
{
|
||||
return array(
|
||||
'parses x' => array('v1.x', '1.9999999.9999999.9999999-dev'),
|
||||
'parses *' => array('v1.*', '1.9999999.9999999.9999999-dev'),
|
||||
'parses digits' => array('v1.0', '1.0.9999999.9999999-dev'),
|
||||
'parses digits/2' => array('2.0', '2.0.9999999.9999999-dev'),
|
||||
'parses long x' => array('v1.0.x', '1.0.9999999.9999999-dev'),
|
||||
'parses long *' => array('v1.0.3.*', '1.0.3.9999999-dev'),
|
||||
'parses long digits' => array('v2.4.0', '2.4.0.9999999-dev'),
|
||||
'parses long digits/2' => array('2.4.4', '2.4.4.9999999-dev'),
|
||||
'parses master' => array('master', '9999999-dev'),
|
||||
'parses trunk' => array('trunk', '9999999-dev'),
|
||||
'parses arbitrary' => array('feature-a', 'dev-feature-a'),
|
||||
'parses arbitrary/2' => array('FOOBAR', 'dev-FOOBAR'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testParseConstraintsIgnoresStabilityFlag()
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$this->assertSame((string) new VersionConstraint('=', '1.0.0.0'), (string) $parser->parseConstraints('1.0@dev'));
|
||||
}
|
||||
|
||||
public function testParseConstraintsIgnoresReferenceOnDevVersion()
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$this->assertSame((string) new VersionConstraint('=', '1.0.9999999.9999999-dev'), (string) $parser->parseConstraints('1.0.x-dev#abcd123'));
|
||||
$this->assertSame((string) new VersionConstraint('=', '1.0.9999999.9999999-dev'), (string) $parser->parseConstraints('1.0.x-dev#trunk/@123'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException UnexpectedValueException
|
||||
*/
|
||||
public function testParseConstraintsFailsOnBadReference()
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$this->assertSame((string) new VersionConstraint('=', '1.0.0.0'), (string) $parser->parseConstraints('1.0#abcd123'));
|
||||
$this->assertSame((string) new VersionConstraint('=', '1.0.0.0'), (string) $parser->parseConstraints('1.0#trunk/@123'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException UnexpectedValueException
|
||||
* @expectedExceptionMessage Invalid operator "~>", you probably meant to use the "~" operator
|
||||
*/
|
||||
public function testParseConstraintsNudgesRubyDevsTowardsThePathOfRighteousness()
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$parser->parseConstraints('~>1.2');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider simpleConstraints
|
||||
*/
|
||||
public function testParseConstraintsSimple($input, $expected)
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$this->assertSame((string) $expected, (string) $parser->parseConstraints($input));
|
||||
}
|
||||
|
||||
public function simpleConstraints()
|
||||
{
|
||||
return array(
|
||||
'match any' => array('*', new EmptyConstraint()),
|
||||
'match any/2' => array('*.*', new EmptyConstraint()),
|
||||
'match any/3' => array('*.x.*', new EmptyConstraint()),
|
||||
'match any/4' => array('x.X.x.*', new EmptyConstraint()),
|
||||
'not equal' => array('<>1.0.0', new VersionConstraint('<>', '1.0.0.0')),
|
||||
'not equal/2' => array('!=1.0.0', new VersionConstraint('!=', '1.0.0.0')),
|
||||
'greater than' => array('>1.0.0', new VersionConstraint('>', '1.0.0.0')),
|
||||
'lesser than' => array('<1.2.3.4', new VersionConstraint('<', '1.2.3.4-dev')),
|
||||
'less/eq than' => array('<=1.2.3', new VersionConstraint('<=', '1.2.3.0')),
|
||||
'great/eq than' => array('>=1.2.3', new VersionConstraint('>=', '1.2.3.0-dev')),
|
||||
'equals' => array('=1.2.3', new VersionConstraint('=', '1.2.3.0')),
|
||||
'double equals' => array('==1.2.3', new VersionConstraint('=', '1.2.3.0')),
|
||||
'no op means eq' => array('1.2.3', new VersionConstraint('=', '1.2.3.0')),
|
||||
'completes version' => array('=1.0', new VersionConstraint('=', '1.0.0.0')),
|
||||
'shorthand beta' => array('1.2.3b5', new VersionConstraint('=', '1.2.3.0-beta5')),
|
||||
'accepts spaces' => array('>= 1.2.3', new VersionConstraint('>=', '1.2.3.0-dev')),
|
||||
'accepts spaces/2' => array('< 1.2.3', new VersionConstraint('<', '1.2.3.0-dev')),
|
||||
'accepts spaces/3' => array('> 1.2.3', new VersionConstraint('>', '1.2.3.0')),
|
||||
'accepts master' => array('>=dev-master', new VersionConstraint('>=', '9999999-dev')),
|
||||
'accepts master/2' => array('dev-master', new VersionConstraint('=', '9999999-dev')),
|
||||
'accepts arbitrary' => array('dev-feature-a', new VersionConstraint('=', 'dev-feature-a')),
|
||||
'regression #550' => array('dev-some-fix', new VersionConstraint('=', 'dev-some-fix')),
|
||||
'regression #935' => array('dev-CAPS', new VersionConstraint('=', 'dev-CAPS')),
|
||||
'ignores aliases' => array('dev-master as 1.0.0', new VersionConstraint('=', '9999999-dev')),
|
||||
'lesser than override' => array('<1.2.3.4-stable', new VersionConstraint('<', '1.2.3.4')),
|
||||
'great/eq than override' => array('>=1.2.3.4-stable', new VersionConstraint('>=', '1.2.3.4')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider wildcardConstraints
|
||||
*/
|
||||
public function testParseConstraintsWildcard($input, $min, $max)
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
if ($min) {
|
||||
$expected = new MultiConstraint(array($min, $max));
|
||||
} else {
|
||||
$expected = $max;
|
||||
}
|
||||
|
||||
$this->assertSame((string) $expected, (string) $parser->parseConstraints($input));
|
||||
}
|
||||
|
||||
public function wildcardConstraints()
|
||||
{
|
||||
return array(
|
||||
array('2.*', new VersionConstraint('>=', '2.0.0.0-dev'), new VersionConstraint('<', '3.0.0.0-dev')),
|
||||
array('20.*', new VersionConstraint('>=', '20.0.0.0-dev'), new VersionConstraint('<', '21.0.0.0-dev')),
|
||||
array('2.0.*', new VersionConstraint('>=', '2.0.0.0-dev'), new VersionConstraint('<', '2.1.0.0-dev')),
|
||||
array('2.2.x', new VersionConstraint('>=', '2.2.0.0-dev'), new VersionConstraint('<', '2.3.0.0-dev')),
|
||||
array('2.10.X', new VersionConstraint('>=', '2.10.0.0-dev'), new VersionConstraint('<', '2.11.0.0-dev')),
|
||||
array('2.1.3.*', new VersionConstraint('>=', '2.1.3.0-dev'), new VersionConstraint('<', '2.1.4.0-dev')),
|
||||
array('0.*', null, new VersionConstraint('<', '1.0.0.0-dev')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider tildeConstraints
|
||||
*/
|
||||
public function testParseTildeWildcard($input, $min, $max)
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
if ($min) {
|
||||
$expected = new MultiConstraint(array($min, $max));
|
||||
} else {
|
||||
$expected = $max;
|
||||
}
|
||||
|
||||
$this->assertSame((string) $expected, (string) $parser->parseConstraints($input));
|
||||
}
|
||||
|
||||
public function tildeConstraints()
|
||||
{
|
||||
return array(
|
||||
array('~1', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
|
||||
array('~1.0', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
|
||||
array('~1.0.0', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '1.1.0.0-dev')),
|
||||
array('~1.2', new VersionConstraint('>=', '1.2.0.0-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
|
||||
array('~1.2.3', new VersionConstraint('>=', '1.2.3.0-dev'), new VersionConstraint('<', '1.3.0.0-dev')),
|
||||
array('~1.2.3.4', new VersionConstraint('>=', '1.2.3.4-dev'), new VersionConstraint('<', '1.2.4.0-dev')),
|
||||
array('~1.2-beta',new VersionConstraint('>=', '1.2.0.0-beta'), new VersionConstraint('<', '2.0.0.0-dev')),
|
||||
array('~1.2-b2', new VersionConstraint('>=', '1.2.0.0-beta2'), new VersionConstraint('<', '2.0.0.0-dev')),
|
||||
array('~1.2-BETA2', new VersionConstraint('>=', '1.2.0.0-beta2'), new VersionConstraint('<', '2.0.0.0-dev')),
|
||||
array('~1.2.2-dev', new VersionConstraint('>=', '1.2.2.0-dev'), new VersionConstraint('<', '1.3.0.0-dev')),
|
||||
array('~1.2.2-stable', new VersionConstraint('>=', '1.2.2.0-stable'), new VersionConstraint('<', '1.3.0.0-dev')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider caretConstraints
|
||||
*/
|
||||
public function testParseCaretWildcard($input, $min, $max)
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
if ($min) {
|
||||
$expected = new MultiConstraint(array($min, $max));
|
||||
} else {
|
||||
$expected = $max;
|
||||
}
|
||||
|
||||
$this->assertSame((string) $expected, (string) $parser->parseConstraints($input));
|
||||
}
|
||||
|
||||
public function caretConstraints()
|
||||
{
|
||||
return array(
|
||||
array('^1', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
|
||||
array('^0', new VersionConstraint('>=', '0.0.0.0-dev'), new VersionConstraint('<', '1.0.0.0-dev')),
|
||||
array('^0.0', new VersionConstraint('>=', '0.0.0.0-dev'), new VersionConstraint('<', '0.1.0.0-dev')),
|
||||
array('^1.2', new VersionConstraint('>=', '1.2.0.0-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
|
||||
array('^1.2.3-beta.2', new VersionConstraint('>=', '1.2.3.0-beta2'), new VersionConstraint('<', '2.0.0.0-dev')),
|
||||
array('^1.2.3.4', new VersionConstraint('>=', '1.2.3.4-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
|
||||
array('^1.2.3', new VersionConstraint('>=', '1.2.3.0-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
|
||||
array('^0.2.3', new VersionConstraint('>=', '0.2.3.0-dev'), new VersionConstraint('<', '0.3.0.0-dev')),
|
||||
array('^0.2', new VersionConstraint('>=', '0.2.0.0-dev'), new VersionConstraint('<', '0.3.0.0-dev')),
|
||||
array('^0.2.0', new VersionConstraint('>=', '0.2.0.0-dev'), new VersionConstraint('<', '0.3.0.0-dev')),
|
||||
array('^0.0.3', new VersionConstraint('>=', '0.0.3.0-dev'), new VersionConstraint('<', '0.0.4.0-dev')),
|
||||
array('^0.0.3-alpha', new VersionConstraint('>=', '0.0.3.0-alpha'), new VersionConstraint('<', '0.0.4.0-dev')),
|
||||
array('^0.0.3-dev', new VersionConstraint('>=', '0.0.3.0-dev'), new VersionConstraint('<', '0.0.4.0-dev')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider hyphenConstraints
|
||||
*/
|
||||
public function testParseHyphen($input, $min, $max)
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
if ($min) {
|
||||
$expected = new MultiConstraint(array($min, $max));
|
||||
} else {
|
||||
$expected = $max;
|
||||
}
|
||||
|
||||
$this->assertSame((string) $expected, (string) $parser->parseConstraints($input));
|
||||
}
|
||||
|
||||
public function hyphenConstraints()
|
||||
{
|
||||
return array(
|
||||
array('1 - 2', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '3.0.0.0-dev')),
|
||||
array('1.2.3 - 2.3.4.5', new VersionConstraint('>=', '1.2.3.0-dev'), new VersionConstraint('<=', '2.3.4.5')),
|
||||
array('1.2-beta - 2.3', new VersionConstraint('>=', '1.2.0.0-beta'), new VersionConstraint('<', '2.4.0.0-dev')),
|
||||
array('1.2-beta - 2.3-dev', new VersionConstraint('>=', '1.2.0.0-beta'), new VersionConstraint('<=', '2.3.0.0-dev')),
|
||||
array('1.2-RC - 2.3.1', new VersionConstraint('>=', '1.2.0.0-RC'), new VersionConstraint('<=', '2.3.1.0')),
|
||||
array('1.2.3-alpha - 2.3-RC', new VersionConstraint('>=', '1.2.3.0-alpha'), new VersionConstraint('<=', '2.3.0.0-RC')),
|
||||
array('1 - 2.0', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '2.1.0.0-dev')),
|
||||
array('1 - 2.1', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '2.2.0.0-dev')),
|
||||
array('1.2 - 2.1.0', new VersionConstraint('>=', '1.2.0.0-dev'), new VersionConstraint('<=', '2.1.0.0')),
|
||||
array('1.3 - 2.1.3', new VersionConstraint('>=', '1.3.0.0-dev'), new VersionConstraint('<=', '2.1.3.0')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider multiConstraintProvider
|
||||
*/
|
||||
public function testParseConstraintsMulti($constraint)
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$first = new VersionConstraint('>', '2.0.0.0');
|
||||
$second = new VersionConstraint('<=', '3.0.0.0');
|
||||
$multi = new MultiConstraint(array($first, $second));
|
||||
$this->assertSame((string) $multi, (string) $parser->parseConstraints($constraint));
|
||||
}
|
||||
|
||||
public function multiConstraintProvider()
|
||||
{
|
||||
return array(
|
||||
array('>2.0,<=3.0'),
|
||||
array('>2.0 <=3.0'),
|
||||
array('>2.0 <=3.0'),
|
||||
array('>2.0, <=3.0'),
|
||||
array('>2.0 ,<=3.0'),
|
||||
array('>2.0 , <=3.0'),
|
||||
array('>2.0 , <=3.0'),
|
||||
array('> 2.0 <= 3.0'),
|
||||
array('> 2.0 , <= 3.0'),
|
||||
array(' > 2.0 , <= 3.0 '),
|
||||
);
|
||||
}
|
||||
|
||||
public function testParseConstraintsMultiWithStabilitySuffix()
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$first = new VersionConstraint('>=', '1.1.0.0-alpha4');
|
||||
$second = new VersionConstraint('<', '1.2.9999999.9999999-dev');
|
||||
$multi = new MultiConstraint(array($first, $second));
|
||||
$this->assertSame((string) $multi, (string) $parser->parseConstraints('>=1.1.0-alpha4,<1.2.x-dev'));
|
||||
|
||||
$first = new VersionConstraint('>=', '1.1.0.0-alpha4');
|
||||
$second = new VersionConstraint('<', '1.2.0.0-beta2');
|
||||
$multi = new MultiConstraint(array($first, $second));
|
||||
$this->assertSame((string) $multi, (string) $parser->parseConstraints('>=1.1.0-alpha4,<1.2-beta2'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider multiConstraintProvider2
|
||||
*/
|
||||
public function testParseConstraintsMultiDisjunctiveHasPrioOverConjuctive($constraint)
|
||||
{
|
||||
$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($constraint));
|
||||
}
|
||||
|
||||
public function multiConstraintProvider2()
|
||||
{
|
||||
return array(
|
||||
array('>2.0,<2.0.5 | >2.0.6'),
|
||||
array('>2.0,<2.0.5 || >2.0.6'),
|
||||
array('> 2.0 , <2.0.5 | > 2.0.6'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testParseConstraintsMultiWithStabilities()
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$first = new VersionConstraint('>', '2.0.0.0');
|
||||
$second = new VersionConstraint('<=', '3.0.0.0-dev');
|
||||
$multi = new MultiConstraint(array($first, $second));
|
||||
$this->assertSame((string) $multi, (string) $parser->parseConstraints('>2.0@stable,<=3.0@dev'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider failingConstraints
|
||||
* @expectedException UnexpectedValueException
|
||||
*/
|
||||
public function testParseConstraintsFails($input)
|
||||
{
|
||||
$parser = new VersionParser;
|
||||
$parser->parseConstraints($input);
|
||||
}
|
||||
|
||||
public function failingConstraints()
|
||||
{
|
||||
return array(
|
||||
'empty ' => array(''),
|
||||
'invalid version' => array('1.0.0-meh'),
|
||||
'operator abuse' => array('>2.0,,<=3.0'),
|
||||
'operator abuse/2' => array('>2.0 ,, <=3.0'),
|
||||
'operator abuse/3' => array('>2.0 ||| <=3.0'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider stabilityProvider
|
||||
*/
|
||||
public function testParseStability($expected, $version)
|
||||
{
|
||||
$this->assertSame($expected, VersionParser::parseStability($version));
|
||||
}
|
||||
|
||||
public function stabilityProvider()
|
||||
{
|
||||
return array(
|
||||
array('stable', '1'),
|
||||
array('stable', '1.0'),
|
||||
array('stable', '3.2.1'),
|
||||
array('stable', 'v3.2.1'),
|
||||
array('dev', 'v2.0.x-dev'),
|
||||
array('dev', 'v2.0.x-dev#abc123'),
|
||||
array('dev', 'v2.0.x-dev#trunk/@123'),
|
||||
array('RC', '3.0-RC2'),
|
||||
array('dev', 'dev-master'),
|
||||
array('dev', '3.1.2-dev'),
|
||||
array('stable', '3.1.2-pl2'),
|
||||
array('stable', '3.1.2-patch'),
|
||||
array('alpha', '3.1.2-alpha5'),
|
||||
array('beta', '3.1.2-beta'),
|
||||
array('beta', '2.0B1'),
|
||||
array('alpha', '1.2.0a1'),
|
||||
array('alpha', '1.2_a1'),
|
||||
array('RC', '2.0.0rc1')
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue