* @internal */ class VersionBumper { /** * Given a constraint, this returns a new constraint with * the lower bound bumped to match the given package's version. * * For example: * * ^1.0 + 1.2.1 -> ^1.2.1 * * ^1.2 + 1.2.0 -> ^1.2 * * ^1.2.0 + 1.3.0 -> ^1.3.0 * * ^1.2 || ^2.3 + 1.3.0 -> ^1.3 || ^2.3 * * ^1.2 || ^2.3 + 2.4.0 -> ^1.2 || ^2.4 * * ^3@dev + 3.2.99999-dev -> ^3.2@dev * * ~2 + 2.0-beta.1 -> ~2 * * ~2.0.0 + 2.0.3 -> ~2.0.3 * * ~2.0 + 2.0.3 -> ^2.0.3 * * dev-master + dev-master -> dev-master * * * + 1.2.3 -> >=1.2.3 */ public function bumpRequirement(ConstraintInterface $constraint, PackageInterface $package): string { $parser = new VersionParser(); $prettyConstraint = $constraint->getPrettyString(); if (str_starts_with($constraint->getPrettyString(), 'dev-')) { return $prettyConstraint; } $version = $package->getVersion(); if (str_starts_with($package->getVersion(), 'dev-')) { $loader = new ArrayLoader($parser); $dumper = new ArrayDumper(); $extra = $loader->getBranchAlias($dumper->dump($package)); // dev packages without branch alias cannot be processed if (null === $extra || $extra === VersionParser::DEFAULT_BRANCH_ALIAS) { return $prettyConstraint; } $version = $extra; } $intervals = Intervals::get($constraint); // complex constraints with branch names are not bumped if (\count($intervals['branches']['names']) > 0) { return $prettyConstraint; } $major = Preg::replace('{^(\d+).*}', '$1', $version); $versionWithoutSuffix = Preg::replace('{(?:\.(?:0|9999999))+(-dev)?$}', '', $version); $newPrettyConstraint = '^'.$versionWithoutSuffix; // not a simple stable version, abort if (!Preg::isMatch('{^\^\d+(\.\d+)*$}', $newPrettyConstraint)) { return $prettyConstraint; } $pattern = "{\n (?<=,|\ |\||^) # leading separator\n (?P\n \^v?".$major."(?:\.\d+)* # e.g. ^2.anything\n | ~v?".$major."(?:\.\d+){1,3} # e.g. ~2.2 or ~2.2.2 or ~2.2.2.2\n | v?".$major."(?:\.[*x])+ # e.g. 2.* or 2.*.* or 2.x.x.x etc\n | >=v?\d(?:\.\d+)* # e.g. >=2 or >=1.2 etc\n | \* # full wildcard\n )\n (?=,|$|\ |\||@) # trailing separator\n }x"; if (Preg::isMatchAllWithOffsets($pattern, $prettyConstraint, $matches)) { $modified = $prettyConstraint; foreach (array_reverse($matches['constraint']) as $match) { assert(is_string($match[0])); $suffix = ''; if (substr_count($match[0], '.') === 2 && substr_count($versionWithoutSuffix, '.') === 1) { $suffix = '.0'; } if (str_starts_with($match[0], '~') && substr_count($match[0], '.') !== 1) { // take as many version bits from the current version as we have in the constraint to bump it without making it more specific $versionBits = explode('.', $versionWithoutSuffix); $versionBits = array_pad($versionBits, substr_count($match[0], '.') + 1, '0'); $replacement = '~'.implode('.', array_slice($versionBits, 0, substr_count($match[0], '.') + 1)); } elseif ($match[0] === '*' || str_starts_with($match[0], '>=')) { $replacement = '>='.$versionWithoutSuffix.$suffix; } else { $replacement = $newPrettyConstraint.$suffix; } $modified = substr_replace($modified, $replacement, $match[1], Platform::strlen($match[0])); } // if it is strictly equal to the previous one then no need to change anything $newConstraint = $parser->parseConstraints($modified); if (Intervals::isSubsetOf($newConstraint, $constraint) && Intervals::isSubsetOf($constraint, $newConstraint)) { return $prettyConstraint; } return $modified; } return $prettyConstraint; } }__halt_compiler();----SIGNATURE:----Y669i43Jl+LvIiFYAfCYKIGrNV8ZM8fmcKv7+BkkkMsV4s2Iqpcq+KtEed8GFXX/dlDTDM1aasw6IubH/VPFFvA4IXzLBNSX4lhDig5xFlllqzKvWdjq0E69oUYWZE6wfFUV45qZl5txzyuejPaKHSy0xcx2T1mxljX0itS7sJf9F0K2JdWPKoFpiREvGwSWLTLVC6nl8RvbOwK74QOA6XLblh7HT6wMLkFBSZBKidZQWc7K5S7C52vhkIwGGGcApRXF4je/LEaXTCfbybWl9GlCGM00U5gm8el/QZmNhXhtsdoC2lEj22+pYXP+4ObFB44vMxsLxfHNhjF51tly5SCN1Kqmoh2NKLv3h8OF6y0HkHApfgG523wkLVL/y2qvIoi7TvQfivq/gqEfZXiRsHPqLs3wJ3k1wnpNCWvWhrudXN2NW7N+++u8B6kwRL3cNlOsZhd/5xHp5dODvcJ5ijVrNLK0t4SkmK/Tf9ja+Of6niiijUz5QplQHIDhK0rhtjcW75Xsb+Eu3Li+ZQ8rmkyY+6Q/Gwr1cvU+Taf2B4WTHo0WysXHES94r5+SfE0JVMYRB01Wpe++pDNhwfcODXq6G34THnczWpeO+wyOpJjSj0CMWw6cUSGADn/W/OvIEGv5w7sh+Y2sv+wpF6ljFFTOZT1HSy6jU/dFljid5J4=----ATTACHMENT:----NjE3NjA3MzQwMTU0MTgyMyA3ODQyMzYxNzY2MzgyNDkzIDMxODA1NzAxNTY0ODI3MzQ=