Package Manager Workspace

I chatted with @NeoNacho, @ddunbar, @rballard and @abertelrud this morning in person about this proposal. We think it may be possible to compose the functionality proposed here using the local dependencies feature. However, there are several open questions:

• This proposal allows cloning packages automatically but there is no such functionality in the local dependencies. The local dependency feature can be extended to include a URL or people can write scripts to perform the cloning operations.

• Users will need to create a target and declare dependency on the products they want to build. This may be a good thing because it allows control over what is actually built. We can add a special case: if there are no targets and all dependencies are local, we build all available products. Or, we can add a flag to SwiftPM to build everything.

• It was also mentioned that people may want a global edit mode for the packages they usually work on. This can be done by a global swiftpm config file, similar to gitconfig. Since this config could be highly personal, there is a concern around sharing that within a team.

One thing to consider: how does the workspace build system handle external library dependencies, especially when there might be conflicts?

For example, consider a workspace with 3 packages: MyFoundation, FooKit, and BarKit.

MyFoundation depends on an external package CoolUtils from [1.0,2.0). FooKit depends on CoolUtils [1.0, 1.1) and BarKit depends on CoolUtils [1.1, 2.0). FooKit and BarKit both depend on MyFoundation, but they do not depend on each other. In the simplest implementation of workspaces this set of packages is simply impossible to build as the combination of dependencies is unsatisfiable. There is a way to satisfy them if we build MyFoundation twice, once against CoolUtils 1.1 and once against CoolUtils 1.0:

CoolUtils 1.1 <- MyFoundation <- BarKit

CoolUtils 1.0 <- MyFoundation <- FooKit

Ankit, do you have any thoughts as to how we could represent this with this proposal?

It is not possible to have different version of the same module in Swift. Your example sounds like dependency hell situation. swift-package-manager/README.md at f303078b2fd2f58e6ab9973442dbde79edfd3e58 · apple/swift-package-manager · GitHub

But the workspace I described is perfectly valid when FooKit and BarKit are developed as separate packages - the problem only arises when I want to place them into the same workspace. If FooKit was actually FooApp, a leaf node that compiled to a static executable it can certainly use its own old version of CoolUtils and not hurt anything around it. There could be major version differences as well, perhaps FooKit is deprecated and supports only swift-4.0, but is kept in the workspace to support easy security fixes. And finally there could be an incremental upgrade problem - perhaps FooKit's constraint came not from itself but from another of its dependencies, CoolerUtils. FooKit would need to wait for upstream to release a new version of CoolerUtils, drop its CoolerUtils dependency altogether, or get kicked out of the workspace so BarKit can upgrade. But we still want to manage FooKit with the rest of the packages we maintain, so soon we'll have a SE-NNNN Meta-Workspaces.

EDIT: I really dislike the date format. I didn't realize that this was an entire year old.

3 Likes