Mercurial > hg > rc1
comparison vendor/composer/semver/src/Constraint/Constraint.php @ 0:1e000243b222
vanilla 1.3.3 distro, I hope
| author | Charlie Root |
|---|---|
| date | Thu, 04 Jan 2018 15:50:29 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:1e000243b222 |
|---|---|
| 1 <?php | |
| 2 | |
| 3 /* | |
| 4 * This file is part of composer/semver. | |
| 5 * | |
| 6 * (c) Composer <https://github.com/composer> | |
| 7 * | |
| 8 * For the full copyright and license information, please view | |
| 9 * the LICENSE file that was distributed with this source code. | |
| 10 */ | |
| 11 | |
| 12 namespace Composer\Semver\Constraint; | |
| 13 | |
| 14 /** | |
| 15 * Defines a constraint. | |
| 16 */ | |
| 17 class Constraint implements ConstraintInterface | |
| 18 { | |
| 19 /* operator integer values */ | |
| 20 const OP_EQ = 0; | |
| 21 const OP_LT = 1; | |
| 22 const OP_LE = 2; | |
| 23 const OP_GT = 3; | |
| 24 const OP_GE = 4; | |
| 25 const OP_NE = 5; | |
| 26 | |
| 27 /** | |
| 28 * Operator to integer translation table. | |
| 29 * | |
| 30 * @var array | |
| 31 */ | |
| 32 private static $transOpStr = array( | |
| 33 '=' => self::OP_EQ, | |
| 34 '==' => self::OP_EQ, | |
| 35 '<' => self::OP_LT, | |
| 36 '<=' => self::OP_LE, | |
| 37 '>' => self::OP_GT, | |
| 38 '>=' => self::OP_GE, | |
| 39 '<>' => self::OP_NE, | |
| 40 '!=' => self::OP_NE, | |
| 41 ); | |
| 42 | |
| 43 /** | |
| 44 * Integer to operator translation table. | |
| 45 * | |
| 46 * @var array | |
| 47 */ | |
| 48 private static $transOpInt = array( | |
| 49 self::OP_EQ => '==', | |
| 50 self::OP_LT => '<', | |
| 51 self::OP_LE => '<=', | |
| 52 self::OP_GT => '>', | |
| 53 self::OP_GE => '>=', | |
| 54 self::OP_NE => '!=', | |
| 55 ); | |
| 56 | |
| 57 /** @var string */ | |
| 58 protected $operator; | |
| 59 | |
| 60 /** @var string */ | |
| 61 protected $version; | |
| 62 | |
| 63 /** @var string */ | |
| 64 protected $prettyString; | |
| 65 | |
| 66 /** | |
| 67 * @param ConstraintInterface $provider | |
| 68 * | |
| 69 * @return bool | |
| 70 */ | |
| 71 public function matches(ConstraintInterface $provider) | |
| 72 { | |
| 73 if ($provider instanceof $this) { | |
| 74 return $this->matchSpecific($provider); | |
| 75 } | |
| 76 | |
| 77 // turn matching around to find a match | |
| 78 return $provider->matches($this); | |
| 79 } | |
| 80 | |
| 81 /** | |
| 82 * @param string $prettyString | |
| 83 */ | |
| 84 public function setPrettyString($prettyString) | |
| 85 { | |
| 86 $this->prettyString = $prettyString; | |
| 87 } | |
| 88 | |
| 89 /** | |
| 90 * @return string | |
| 91 */ | |
| 92 public function getPrettyString() | |
| 93 { | |
| 94 if ($this->prettyString) { | |
| 95 return $this->prettyString; | |
| 96 } | |
| 97 | |
| 98 return $this->__toString(); | |
| 99 } | |
| 100 | |
| 101 /** | |
| 102 * Get all supported comparison operators. | |
| 103 * | |
| 104 * @return array | |
| 105 */ | |
| 106 public static function getSupportedOperators() | |
| 107 { | |
| 108 return array_keys(self::$transOpStr); | |
| 109 } | |
| 110 | |
| 111 /** | |
| 112 * Sets operator and version to compare with. | |
| 113 * | |
| 114 * @param string $operator | |
| 115 * @param string $version | |
| 116 * | |
| 117 * @throws \InvalidArgumentException if invalid operator is given. | |
| 118 */ | |
| 119 public function __construct($operator, $version) | |
| 120 { | |
| 121 if (!isset(self::$transOpStr[$operator])) { | |
| 122 throw new \InvalidArgumentException(sprintf( | |
| 123 'Invalid operator "%s" given, expected one of: %s', | |
| 124 $operator, | |
| 125 implode(', ', self::getSupportedOperators()) | |
| 126 )); | |
| 127 } | |
| 128 | |
| 129 $this->operator = self::$transOpStr[$operator]; | |
| 130 $this->version = $version; | |
| 131 } | |
| 132 | |
| 133 /** | |
| 134 * @param string $a | |
| 135 * @param string $b | |
| 136 * @param string $operator | |
| 137 * @param bool $compareBranches | |
| 138 * | |
| 139 * @throws \InvalidArgumentException if invalid operator is given. | |
| 140 * | |
| 141 * @return bool | |
| 142 */ | |
| 143 public function versionCompare($a, $b, $operator, $compareBranches = false) | |
| 144 { | |
| 145 if (!isset(self::$transOpStr[$operator])) { | |
| 146 throw new \InvalidArgumentException(sprintf( | |
| 147 'Invalid operator "%s" given, expected one of: %s', | |
| 148 $operator, | |
| 149 implode(', ', self::getSupportedOperators()) | |
| 150 )); | |
| 151 } | |
| 152 | |
| 153 $aIsBranch = 'dev-' === substr($a, 0, 4); | |
| 154 $bIsBranch = 'dev-' === substr($b, 0, 4); | |
| 155 | |
| 156 if ($aIsBranch && $bIsBranch) { | |
| 157 return $operator === '==' && $a === $b; | |
| 158 } | |
| 159 | |
| 160 // when branches are not comparable, we make sure dev branches never match anything | |
| 161 if (!$compareBranches && ($aIsBranch || $bIsBranch)) { | |
| 162 return false; | |
| 163 } | |
| 164 | |
| 165 return version_compare($a, $b, $operator); | |
| 166 } | |
| 167 | |
| 168 /** | |
| 169 * @param Constraint $provider | |
| 170 * @param bool $compareBranches | |
| 171 * | |
| 172 * @return bool | |
| 173 */ | |
| 174 public function matchSpecific(Constraint $provider, $compareBranches = false) | |
| 175 { | |
| 176 $noEqualOp = str_replace('=', '', self::$transOpInt[$this->operator]); | |
| 177 $providerNoEqualOp = str_replace('=', '', self::$transOpInt[$provider->operator]); | |
| 178 | |
| 179 $isEqualOp = self::OP_EQ === $this->operator; | |
| 180 $isNonEqualOp = self::OP_NE === $this->operator; | |
| 181 $isProviderEqualOp = self::OP_EQ === $provider->operator; | |
| 182 $isProviderNonEqualOp = self::OP_NE === $provider->operator; | |
| 183 | |
| 184 // '!=' operator is match when other operator is not '==' operator or version is not match | |
| 185 // these kinds of comparisons always have a solution | |
| 186 if ($isNonEqualOp || $isProviderNonEqualOp) { | |
| 187 return !$isEqualOp && !$isProviderEqualOp | |
| 188 || $this->versionCompare($provider->version, $this->version, '!=', $compareBranches); | |
| 189 } | |
| 190 | |
| 191 // an example for the condition is <= 2.0 & < 1.0 | |
| 192 // these kinds of comparisons always have a solution | |
| 193 if ($this->operator !== self::OP_EQ && $noEqualOp === $providerNoEqualOp) { | |
| 194 return true; | |
| 195 } | |
| 196 | |
| 197 if ($this->versionCompare($provider->version, $this->version, self::$transOpInt[$this->operator], $compareBranches)) { | |
| 198 // special case, e.g. require >= 1.0 and provide < 1.0 | |
| 199 // 1.0 >= 1.0 but 1.0 is outside of the provided interval | |
| 200 if ($provider->version === $this->version | |
| 201 && self::$transOpInt[$provider->operator] === $providerNoEqualOp | |
| 202 && self::$transOpInt[$this->operator] !== $noEqualOp) { | |
| 203 return false; | |
| 204 } | |
| 205 | |
| 206 return true; | |
| 207 } | |
| 208 | |
| 209 return false; | |
| 210 } | |
| 211 | |
| 212 /** | |
| 213 * @return string | |
| 214 */ | |
| 215 public function __toString() | |
| 216 { | |
| 217 return self::$transOpInt[$this->operator] . ' ' . $this->version; | |
| 218 } | |
| 219 } |
