ghostzero/semver-resolver

用PHP编写的Semver解析器。

1.0.0 2021-12-14 20:01 UTC

This package is not auto-updated.

Last update: 2024-09-19 08:39:38 UTC


README

使用语义版本控制计算依赖树的一个'最优'解。

此包具有单元测试,代码覆盖率100%。

用法

composer require ghostzero/semver-resolver
$versionRepository = // implement version resolver
$dependencyRepository = ...; // implement dependencies repository

$resolver = new SemverResolver([
    'test1' => '^0.1.0',
    'test2' => '0.1.0'
], $versionRepository, $dependencyRepository);

$resolved = $resolver->resolve();

$this->assertEquals([
    'test1' => '0.1.1',
    'test2' => '0.1.0'
], $resolved);

算法

解析器按轮次工作。在每一轮次中发生以下操作

  1. 未计算依赖被排队以进行计算
  2. 为尚未缓存的依赖缓存可用版本
  3. 为排队依赖计算最大满足版本
  4. 如果由于在早些轮次中固定的依赖版本而无法满足约束,则将冲突依赖的版本回溯到下一个更早的版本(通过添加新的约束),从当前计算状态中删除,并重新排队以进行计算
  5. 将被重新排队的计算的任何依赖也将被删除并重新排队
  6. 然后将计算版本添加到队列中,以用其依赖更新状态
  7. 为尚未缓存的计算版本缓存依赖
  8. 在删除以前的计算及其依赖后,将新依赖排队以进行重新计算
  9. 过滤已排队的计算,以确保不会重新计算孤立库 - 递归删除库可能导致已排队的计算不再有效/必需
  10. 下一轮次再次从步骤2开始

直到不再有排队计算为止,轮次继续

局限性

尽管尝试通过根据语义版本控制规则优先选择最大满足版本来计算'最优'解决方案,但实际解决方案可能被认为是次优的。应考虑以下局限性。

  • 在回溯时,假设库的较旧版本将具有较旧的依赖项
    • 这意味着我们选择回溯提供上限约束的库
    • 如果一个库由于某些问题回滚了依赖项的版本,那么通过回溯具有下限约束的库可能找到新的匹配解决方案
    • 然而,在这种情况下,可能不太希望回溯,算法应避免这种情况
  • 最优的定义可能不明确,尤其是当存在多个解决方案时
    • 该算法不考虑可能的替代解决方案,仅返回找到的第一个解决方案
    • 回溯库的选择有些任意,因为在每一轮次中,找到的第一个上限约束将被回溯,直到找到解决方案
    • 可能更倾向于以不同的方式回溯(例如,选择不同的库回溯或以不同的顺序回溯)

如果已知更好的解决方案,则应通过在根依赖中固定的版本反映给用户