我见过的每个包管理器中最具挑战性的任务之一就是处理相互冲突的依赖关系。
让我们使用以下虚构的应用程序SwiftApp,它依赖于一些 3rd 方包。
- SwiftApp
- packageA@latest
- packageC@1.0.0
- packageD@latest
- packageB@latest
- packageC@2.0.0
- packageE@latest
从上面的依赖图中,我们可以看到SwiftApp的两个依赖都使用packageC,但使用不同的主要版本标识符。对于大多数语言生态系统来说,这会成为一个问题——主要版本的提升通常意味着对代码进行了更改,这些更改与以前的主要版本不向后兼容。
根据语言/编译器/其他相关组件的技术能力,包管理器可以通过以下方式之一实现:
- 拒绝安装/编译(php、ruby、python?、其他?)
- 没关系,让开发者处理潜在的编译器错误(???)
- 分别为两个包安装packageC(Node.js,其他?)
第三种选择只能在语言或编译器本身的适当支持下才能实现。
在 Swift 中可以在不破坏的情况下实现这个依赖图吗?
换句话说,packageA是否有可能拥有(并使用)packageC 的 1.0.0 版本,而packageB拥有2.0.0 版本?
鉴于最近宣布 Swift 现在是开源的并且带有自己的包管理器,我认为这个问题对于未来对 Swift 包开发感兴趣的读者可能非常有价值。