Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift packages and conflicting dependencies

One of the most challenging tasks of every package manager I have seen is handling conflicting dependencies.

Let's work with the following imaginary application SwiftApp, which depends on some 3rd party packages.

- SwiftApp - packageA@latest - [email protected] - packageD@latest - packageB@latest - [email protected] - packageE@latest

From the dependency graph above, we can see that both of SwiftApp's dependencies use packageC, but with different major version identifiers. For most language ecosystems, this becomes a problem - a major version bump usually means there have been made changes to the code which are not backwards-compatible with the previous major version.

Depending on technical capabilities of the language/compiler/other relevant component, the package manager can be implemented in one of the following ways:

  1. Refuse to install/compile (php, ruby, python?, others?)
  2. Don't care, let the developer deal with potential compiler errors (???)
  3. Install packageC for both packages independently (Node.js, others?)

The third option can only be achieved with proper support by the language or compiler itself.

Can this dependency graph be achieved without breakage in Swift?

In other words, is it technically possible for packageA to have (and use) version 1.0.0 of packageC while packageB will have version 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.

like image 841
Robert Rossmann Avatar asked Dec 03 '15 22:12

Robert Rossmann


People also ask

Where are swift package dependencies stored?

In order to cache the dependencies, they should be located in the project directory, but by default, SPM downloads the dependencies into the system folder: ~/Library/Developer/Xcode/DerivedData.

How do I add a package to Swiftui?

Install a PackageIn the toolbar, click on File → Swift Packages > Add Package.... In the modal, enter the GitHub URL in the input field. Click Next for the next two modals and then Finish.


1 Answers

Short answer:

Now it's option 2, fail to build.
It gives an error: swift-build: The dependency graph could not be satisfied

It's because SPM is on very early stage of development, very early beta.
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.

Long answer:

Swift has namespaces. It means that packageC in packageA would have a full name packageA.packageC. And in packageB it would be packageB.packageC

Because of that, it is possible to have the same framework included more than once.
SPM also fetch dependencies with version suffix (packageC-1.0.0). So I think It should be possible to check what version is required in particular package and fetch it.

Also Swift supports Dynamic frameworks. It means that you can have many version of the same framework and they should not conflict with each other.

As I see it in the future it should be possible to have Option 3 (Install packageC for both packages independent) working.

Summary:

  • Now: Option 2 - fail to build.
  • Future: Option 3 - install both versions independently
like image 144
Kostiantyn Koval Avatar answered Sep 19 '22 22:09

Kostiantyn Koval