13

我见过的每个包管理器中最具挑战性的任务之一就是处理相互冲突的依赖关系。

让我们使用以下虚构的应用程序SwiftApp,它依赖于一些 3rd 方包。

- SwiftApp - packageA@latest - packageC@1.0.0 - packageD@latest - packageB@latest - packageC@2.0.0 - packageE@latest

从上面的依赖图中,我们可以看到SwiftApp的两个依赖都使用packageC,但使用不同的主要版本标识符。对于大多数语言生态系统来说,这会成为一个问题——主要版本的提升通常意味着对代码进行了更改,这些更改与以前的主要版本不向后兼容。

根据语言/编译器/其他相关组件的技术能力,包管理器可以通过以下方式之一实现:

  1. 拒绝安装/编译(php、ruby、python?、其他?)
  2. 没关系,让开发者处理潜在的编译器错误(???)
  3. 分别为两个包安装packageC(Node.js,其他?)

第三种选择只能在语言或编译器本身的适当支持下才能实现。

在 Swift 中可以在不破坏的情况下实现这个依赖图吗?

换句话说,packageA是否有可能拥有(并使用)packageC 的 1.0.0 版本,packageB拥有2.0.0 版本?

鉴于最近宣布 Swift 现在是开源的并且带有自己的包管理器,我认为这个问题对于未来对 Swift 包开发感兴趣的读者可能非常有价值。

4

2 回答 2

6

简短的回答:

现在是选项 2,构建失败。
它给出了一个错误: swift-build: The dependency graph could not be satisfied

这是因为 SPM 处于非常早期的开发阶段,非常早期的测试版。
依赖解析

Swift 包管理器目前不提供自动解决依赖树中冲突的机制。但是,这将在未来提供。

长答案:

Swift 有命名空间。这意味着packageCinpackageA将有一个全名packageA.packageCpackageB里面会是packageB.packageC

因此,可以多次包含相同的框架。
SPM 还获取带有版本后缀(packageC-1.0.0)的依赖项。所以我认为应该可以检查特定包中需要什么版本并获取它。

Swift 还支持动态框架。这意味着您可以拥有同一框架的多个版本,并且它们不应相互冲突。

正如我在未来看到的那样,应该可以让 选项 3(为两个独立的包安装 packageC)工作。

概括:

  • 现在:选项 2 - 构建失败。
  • 未来:选项 3 - 独立安装两个版本
于 2015-12-10T07:40:13.473 回答
0

每当我遇到 SPM 问题时,清除 SPM 缓存都会有所帮助。

在 Xcode 中File > Swift Packages > Reset Package Caches

于 2020-10-21T08:59:20.990 回答