如何验证 Composer 版本约束是否支持所需版本?
How to verify a required version is supported in Composer version constraint?
鉴于 composer.json
中要求的任何版本限制,我想验证要求定义是否支持给定版本。假设 composer.json
需要 "php": "^7.4"
。然后我希望检查版本 7.4
会成功并且 8.0
会失败。
到目前为止我的实现是使用 composer/semver
。
版本-checker.php
use Composer\Semver\Comparator;
use Composer\Semver\VersionParser;
require_once __DIR__ . '/vendor/autoload.php';
$expectations = [
[true, '7.3.0', '^7.3 || ~8.0.0 || ~8.1.0'],
[true, '7.3.0', '^7.3 || ^8.0'],
[false, '7.3.0', '^7.2'],
[false, '7.3.0', '^7.1'],
[false, '7.3.0', '^5.6 || ^7.0'],
[true, '8.1.0', '^7.3 || ~8.0.0 || ~8.1.0'],
[true, '8.1.0', '>=7.2.5'],
[false, '8.1.0', '^7.3 || ^8.0'],
[false, '8.1.0', '^7.2'],
[false, '8.1.0', '^7.1'],
[false, '8.1.0', '^5.6 || ^7.0'],
];
$versionParser = new VersionParser();
foreach ($expectations as [$expected, $requiredVersion, $actualVersion]) {
$constraint = $versionParser->parseConstraints($actualVersion);
$lowerVersion = $constraint->getLowerBound()->getVersion();
$compareResult = Comparator::greaterThanOrEqualTo($lowerVersion, $requiredVersion);
if ($expected !== $compareResult) {
printf(
'Failed to assert that required version (%s) with actual version (%s) is %s.' . PHP_EOL,
$requiredVersion,
$actualVersion,
var_export($expected, true)
);
}
}
输出为:
Failed to assert that required version (8.1.0) with actual version (^7.3 || ~8.0.0 || ~8.1.0) is true.
Failed to assert that required version (8.1.0) with actual version (>=7.2.5) is true.
如何实现正确的验证?
你有两个问题。
第一,错误的期望。
这四个,错的是:
[
[false, '7.3.0', '^7.2'],
[false, '7.3.0', '^7.1'],
[false, '7.3.0', '^5.6 || ^7.0'],
[false, '8.1.0', '^7.3 || ^8.0'],
]
这些约束确实匹配版本。
这里有 caret version range 的文档。基本上,^7.2
等于 >=7.2 && < 8
(等等)。
第二个问题是您使用了错误的方法来检查约束的有效性:
而不是使用这个:
$compareResult = Comparator::greaterThanOrEqualTo($lowerVersion, $requiredVersion);
(请注意,您使用的操作数是错误的,因为这等同于说 $lowerVersion >= $requiredVersion
,这是没有意义的)。
你应该做的:
$actualConstraint = $versionParser->parseConstraints($actualVersion);
$compareResult = $actualConstraint->matches($requiredConstraint);
整个事情放在一起就是:
use Composer\Semver\VersionParser;
require_once __DIR__ . '/vendor/autoload.php';
$expectations = [
[true, '7.3.0', '^7.3 || ~8.0.0 || ~8.1.0'],
[true, '7.3.0', '^7.3 || ^8.0'],
[true, '8.1.0', '^7.3 || ~8.0.0 || ~8.1.0'],
[true, '8.1.0', '>=7.2.5'],
[true, '7.3.0', '^7.2'],
[true, '7.3.0', '^7.1'],
[true, '7.3.0', '^5.6 || ^7.0'],
[true, '8.1.0', '^7.3 || ^8.0'],
[false, '8.1.0', '^7.2'],
[false, '8.1.0', '^7.1'],
[false, '8.1.0', '^5.6 || ^7.0'],
];
$versionParser = new VersionParser();
foreach ($expectations as [$expected, $requiredVersion, $actualVersion]) {
$actualConstraint = $versionParser->parseConstraints($actualVersion);
$requiredConstraint = $versionParser->parseConstraints($requiredVersion);
$compareResult = $actualConstraint->matches($requiredConstraint);
if ($expected !== $compareResult) {
printf(
'Failed to assert that required version (%s) with actual version (%s) is %s.' . PHP_EOL,
$requiredVersion,
$actualVersion,
var_export($expected, true)
);
}
}
鉴于 composer.json
中要求的任何版本限制,我想验证要求定义是否支持给定版本。假设 composer.json
需要 "php": "^7.4"
。然后我希望检查版本 7.4
会成功并且 8.0
会失败。
到目前为止我的实现是使用 composer/semver
。
版本-checker.php
use Composer\Semver\Comparator;
use Composer\Semver\VersionParser;
require_once __DIR__ . '/vendor/autoload.php';
$expectations = [
[true, '7.3.0', '^7.3 || ~8.0.0 || ~8.1.0'],
[true, '7.3.0', '^7.3 || ^8.0'],
[false, '7.3.0', '^7.2'],
[false, '7.3.0', '^7.1'],
[false, '7.3.0', '^5.6 || ^7.0'],
[true, '8.1.0', '^7.3 || ~8.0.0 || ~8.1.0'],
[true, '8.1.0', '>=7.2.5'],
[false, '8.1.0', '^7.3 || ^8.0'],
[false, '8.1.0', '^7.2'],
[false, '8.1.0', '^7.1'],
[false, '8.1.0', '^5.6 || ^7.0'],
];
$versionParser = new VersionParser();
foreach ($expectations as [$expected, $requiredVersion, $actualVersion]) {
$constraint = $versionParser->parseConstraints($actualVersion);
$lowerVersion = $constraint->getLowerBound()->getVersion();
$compareResult = Comparator::greaterThanOrEqualTo($lowerVersion, $requiredVersion);
if ($expected !== $compareResult) {
printf(
'Failed to assert that required version (%s) with actual version (%s) is %s.' . PHP_EOL,
$requiredVersion,
$actualVersion,
var_export($expected, true)
);
}
}
输出为:
Failed to assert that required version (8.1.0) with actual version (^7.3 || ~8.0.0 || ~8.1.0) is true.
Failed to assert that required version (8.1.0) with actual version (>=7.2.5) is true.
如何实现正确的验证?
你有两个问题。
第一,错误的期望。
这四个,错的是:
[
[false, '7.3.0', '^7.2'],
[false, '7.3.0', '^7.1'],
[false, '7.3.0', '^5.6 || ^7.0'],
[false, '8.1.0', '^7.3 || ^8.0'],
]
这些约束确实匹配版本。
这里有 caret version range 的文档。基本上,^7.2
等于 >=7.2 && < 8
(等等)。
第二个问题是您使用了错误的方法来检查约束的有效性:
而不是使用这个:
$compareResult = Comparator::greaterThanOrEqualTo($lowerVersion, $requiredVersion);
(请注意,您使用的操作数是错误的,因为这等同于说 $lowerVersion >= $requiredVersion
,这是没有意义的)。
你应该做的:
$actualConstraint = $versionParser->parseConstraints($actualVersion);
$compareResult = $actualConstraint->matches($requiredConstraint);
整个事情放在一起就是:
use Composer\Semver\VersionParser;
require_once __DIR__ . '/vendor/autoload.php';
$expectations = [
[true, '7.3.0', '^7.3 || ~8.0.0 || ~8.1.0'],
[true, '7.3.0', '^7.3 || ^8.0'],
[true, '8.1.0', '^7.3 || ~8.0.0 || ~8.1.0'],
[true, '8.1.0', '>=7.2.5'],
[true, '7.3.0', '^7.2'],
[true, '7.3.0', '^7.1'],
[true, '7.3.0', '^5.6 || ^7.0'],
[true, '8.1.0', '^7.3 || ^8.0'],
[false, '8.1.0', '^7.2'],
[false, '8.1.0', '^7.1'],
[false, '8.1.0', '^5.6 || ^7.0'],
];
$versionParser = new VersionParser();
foreach ($expectations as [$expected, $requiredVersion, $actualVersion]) {
$actualConstraint = $versionParser->parseConstraints($actualVersion);
$requiredConstraint = $versionParser->parseConstraints($requiredVersion);
$compareResult = $actualConstraint->matches($requiredConstraint);
if ($expected !== $compareResult) {
printf(
'Failed to assert that required version (%s) with actual version (%s) is %s.' . PHP_EOL,
$requiredVersion,
$actualVersion,
var_export($expected, true)
);
}
}