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 } |