ghostzero / semver-resolver
用PHP编写的Semver解析器。
1.0.0
2021-12-14 20:01 UTC
Requires
- php: ^8.0
- composer/semver: ^3.2
- ramsey/uuid: ^4.2
Requires (Dev)
- phpunit/phpunit: ^9
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);
算法
解析器按轮次工作。在每一轮次中发生以下操作
- 未计算依赖被排队以进行计算
- 为尚未缓存的依赖缓存可用版本
- 为排队依赖计算最大满足版本
- 如果由于在早些轮次中固定的依赖版本而无法满足约束,则将冲突依赖的版本回溯到下一个更早的版本(通过添加新的约束),从当前计算状态中删除,并重新排队以进行计算
- 将被重新排队的计算的任何依赖也将被删除并重新排队
- 然后将计算版本添加到队列中,以用其依赖更新状态
- 为尚未缓存的计算版本缓存依赖
- 在删除以前的计算及其依赖后,将新依赖排队以进行重新计算
- 过滤已排队的计算,以确保不会重新计算孤立库 - 递归删除库可能导致已排队的计算不再有效/必需
- 下一轮次再次从步骤2开始
直到不再有排队计算为止,轮次继续
局限性
尽管尝试通过根据语义版本控制规则优先选择最大满足版本来计算'最优'解决方案,但实际解决方案可能被认为是次优的。应考虑以下局限性。
- 在回溯时,假设库的较旧版本将具有较旧的依赖项
- 这意味着我们选择回溯提供上限约束的库
- 如果一个库由于某些问题回滚了依赖项的版本,那么通过回溯具有下限约束的库可能找到新的匹配解决方案
- 然而,在这种情况下,可能不太希望回溯,算法应避免这种情况
- 最优的定义可能不明确,尤其是当存在多个解决方案时
- 该算法不考虑可能的替代解决方案,仅返回找到的第一个解决方案
- 回溯库的选择有些任意,因为在每一轮次中,找到的第一个上限约束将被回溯,直到找到解决方案
- 可能更倾向于以不同的方式回溯(例如,选择不同的库回溯或以不同的顺序回溯)
如果已知更好的解决方案,则应通过在根依赖中固定的版本反映给用户