Allow Package.swift to not be at the root of the repository

This is an idea already described here:

Description

A Swift package must be released as a git repository with a Package.swift file at its root, and with a specific layout.

There has been discussions about allowing a custom layout years ago (see [SR-29] Support custom directory layouts · Issue #5339 · apple/swift-package-manager · GitHub), but this is slightly different.

Say I have a library that I provide in multiple languages (e.g. c++, java, python, swift), and I have all my code in one repository, like this:

.
├── README.md
├── cpp/
├── java/
├── py/
└── swift/ 

That works for all but swift, because it wants to be at the root. Wouldn't it make sense to allow for that? Then inside of swift/ it would just be a normal swift package (with Package.swift and the required directory layout). It would just not sit at the root.

It feels like it would not require very big changes in SwiftPM, and the syntax for using such a package could be something like:

.package(url: /* package url */, subdir: "swift", from: "1.0.0"),

Would that make sense?

19 Likes

It might be better to describe this as customizing the root of the Swift package, which is otherwise implicitly the root of the Git repository.

.package(url: /* package url */, root: "swift", from: "1.0.0"),

That would also make it more clear that such a package would not be allowed to reference files outside it.


I would caution against monorepos like that, though: they make versioning with tags far more complicated and messy. That isn't a reason not to support this, merely a reason not to encourage it.


If this was implemented, Swift Package Manager could use sparse cloning to skip fetching the rest of the repository entirely.

7 Likes

Would anybody have some suggestions about where to start implementing this? I'd like to get a sense of how difficult this would be.