【问题标题】:How to verify a required version is supported in Composer version constraint?如何验证 Composer 版本约束支持所需的版本?
【发布时间】:2022-01-20 03:47:35
【问题描述】:

鉴于composer.json 中需求的任何版本约束,我想验证需求定义是否支持给定版本。假设composer.json 需要"php": "^7.4"。然后我希望检查版本7.4 会成功,8.0 会失败。

到目前为止,我的实现是使用composer/semver

version-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)
        );
    }
}

输出是:

无法用实际版本 (^7.3 || ~8.0.0 || ~8.1.0) 断言所需版本 (8.1.0) 为真。
无法断言所需版本 (8.1.0) 与实际版本 (>=7.2.5) 为真。

如何进行正确的验证?

【问题讨论】:

    标签: php composer-php


    【解决方案1】:

    你有两个问题。

    首先,错误的期望。

    这四个,错了:

    [
        [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)
            );
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-02
      • 2022-01-23
      • 2019-06-28
      • 1970-01-01
      • 2020-01-20
      相关资源
      最近更新 更多