Swift 包和冲突的依赖项

Swift packages and conflicting dependencies

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

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

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

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

根据 language/compiler/other 相关组件的技术能力,包管理器可以通过以下方式之一实现:

  1. 拒绝install/compile(php,ruby,python?,其他?)
  2. 不用管,让开发者处理潜在的编译错误(???)
  3. 为两个软件包独立安装 packageC(Node.js,其他?)

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

能否在 Swift 中不破坏地实现此依赖关系图?

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

Given the recent announcement of Swift being now open-source and coming with a package manager of its own, I think that this question might be very valuable for future readers interested in Swift package development.

简答:

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

这是因为 SPM 处于非常早期的开发阶段,非常早期的测试版。
Dependency Resolution

The Swift Package Manager does not currently provide a mechanism for automatically resolving conflicts in a dependency tree. However, this will be provided in the future.

长答案:

Swift 有命名空间。这意味着 packageA 中的 packageC 将具有全名 packageA.packageC。在 packageB 中它将是 packageB.packageC

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

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

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

总结:

  • 现在:选项 2 - 构建失败。
  • 未来:选项 3 - 独立安装两个版本

每当我遇到 SPM 问题时,它有助于清除 SPM 缓存。

在 Xcode File > Swift Packages > Reset Package Caches