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
- packageC@1.0.0
- packageD@latest
- packageB@latest
- packageC@2.0.0
- 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:
- Refuse to install/compile (php, ruby, python?, others?)
- Don't care, let the developer deal with potential compiler errors (???)
- 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.