summaryrefslogtreecommitdiff
path: root/vendor/composer/semver/src/Constraint/Constraint.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/composer/semver/src/Constraint/Constraint.php')
-rw-r--r--vendor/composer/semver/src/Constraint/Constraint.php181
1 files changed, 181 insertions, 0 deletions
diff --git a/vendor/composer/semver/src/Constraint/Constraint.php b/vendor/composer/semver/src/Constraint/Constraint.php
new file mode 100644
index 00000000..8bc68db7
--- /dev/null
+++ b/vendor/composer/semver/src/Constraint/Constraint.php
@@ -0,0 +1,181 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver\Constraint;
+
+/**
+ * Defines a constraint.
+ */
+class Constraint extends AbstractConstraint
+{
+ /* operator integer values */
+ const OP_EQ = 0;
+ const OP_LT = 1;
+ const OP_LE = 2;
+ const OP_GT = 3;
+ const OP_GE = 4;
+ const OP_NE = 5;
+
+ /**
+ * Operator to integer translation table.
+ *
+ * @var array
+ */
+ 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,
+ );
+
+ /**
+ * Integer to operator translation table.
+ *
+ * @var array
+ */
+ private static $transOpInt = array(
+ self::OP_EQ => '==',
+ self::OP_LT => '<',
+ self::OP_LE => '<=',
+ self::OP_GT => '>',
+ self::OP_GE => '>=',
+ self::OP_NE => '!=',
+ );
+
+ /** @var string */
+ private $operator;
+
+ /** @var string */
+ private $version;
+
+ /**
+ * Get all supported comparison operators.
+ *
+ * @return array
+ */
+ public static function getSupportedOperators()
+ {
+ return array_keys(self::$transOpStr);
+ }
+
+ /**
+ * Sets operator and version to compare with.
+ *
+ * @param string $operator
+ * @param string $version
+ *
+ * @throws \InvalidArgumentException if invalid operator is given.
+ */
+ public function __construct($operator, $version)
+ {
+ if (!isset(self::$transOpStr[$operator])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'Invalid operator "%s" given, expected one of: %s',
+ $operator,
+ implode(', ', self::getSupportedOperators())
+ ));
+ }
+
+ $this->operator = self::$transOpStr[$operator];
+ $this->version = $version;
+ }
+
+ /**
+ * @param string $a
+ * @param string $b
+ * @param string $operator
+ * @param bool $compareBranches
+ *
+ * @throws \InvalidArgumentException if invalid operator is given.
+ *
+ * @return bool
+ */
+ public function versionCompare($a, $b, $operator, $compareBranches = false)
+ {
+ if (!isset(self::$transOpStr[$operator])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'Invalid operator "%s" given, expected one of: %s',
+ $operator,
+ implode(', ', self::getSupportedOperators())
+ ));
+ }
+
+ $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 Constraint $provider
+ * @param bool $compareBranches
+ *
+ * @return bool
+ */
+ public function matchSpecific(Constraint $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;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return self::$transOpInt[$this->operator] . ' ' . $this->version;
+ }
+}