If I understand correctly, this let's a user explicitly replace A with B. The problem at hand however is if Amoves to C. Of course, every user everywhere could now explicitly replace A with C but ideally a user of A wouldn't need to change anything just because the source code now lives at C.
The problem of packages moving places is solved with Vanity URLs in Go I believe. That works but only if everybody creates a vanity URL to start with. If you start off with githu.com/... then that's a problem because you can't retroactively add a vanity URL.
On top of that, if in Go the system fails and both A and C (the same package which moved) are in the build graph, that may well work fine in Go (because Go name-mangles the URL into all symbols). Swift itself could also do that for Swift symbols. But apart from Swift, SwiftPM can also build (Obj)C(++) and Assembly modules. And unfortunately for these languages we cannot add name-magling that adds the SwiftPM target. That then means that if we have both A and C in the build graph (which can work in Go), it would fail for SwiftPM because the (Obj)C(++) symbols would clash.
Of course, if the git hosting product no longer redirected you from A to C, that's a problem. But in this case, a Vanity URL seems to be a good solution.
As for the Obj/C/++ situation, I can definitely see how this can be an issue but I'm not familiar enough to suggest anything noteworthy. Thanks again for the explanation
Right, because it was from GitHub to GitHub. If it moved to gitlab or your personal git host, that wouldn't work. And again, in Go's case putting both github.com/docker/docker and github.com/moby/moby into one binary may work but in Swift's case it likely won't ((Obj)C(++)).
Only if you start with the Vanity URL to start with and you convince your users to not put the github.com link in there directly. You know if you host (to start with) at github.com/my/package but you have a vanity url my.pk/my/package then you will need everybody to put in my.pk/my/package and notgithub.com/my/package despite the fact that both work (until you move...).
In Modules (and even in pre modules through the // import comment), Go actually enforces the import path to be the same as how people are importing it. In other words, if you have a vanity URL and you declare your library to be of that URL, anybody else trying to use github directly to import it will not be able to.
But your points are very well taken. Thanks again!
The beauty of Swift is we can avoid strings. So why if we stop using strong and like said above have SPM manage it.
1 create repo on GitHub and allow push to master and name in SPMIdentity
2. Every push creates minor update
3.What to push? Well the GitHub repo simply has an enum with identities and a public key in a set that contains a mapping of identity and public key
4. Go back to your project and Swift package update
5. Import in package.Swift SPMIdentity
6. Name your project from the enum
Done for the name part
For the version it could stil be that a fork has the same version as the origin.
So maybe for that point location is not a problem. The combination of a version and a url is less problematic?
How do you prevent a repo from picking anathema name? That is maybe best done with the public key approache. Only allow the orininal owner to change the name, any others cannot change the name by some public key check in SPM?
How to prevent somebody from changing things in enum and mapping? A git hook could check the incoming commit on push to only add an identity and mapping or reject the push.
How to delete an identity? You cannot.
Can you move SPMIdenty to a different location? Best not but let the url be baked into SPM and SPM can change it on a major release?
I have been wondering if we could take some inspiration from Named Data Networking which is a "future internet architecture" that's currently in trial.
The above link has a good summary, but in short: it is a networking protocol (meant to replace TCP/IP) where the focus is on "names" that point to the immutable data itself, not to "communication endpoints" as IP addresses do today.
The important points I see are:
Names are hierarchical, which helps with name spacing, discovery, and caching, but they can be structured however is best suited to the application.
Names uniquely identify immutable data; that data is always findable if you have the name and it exists on some NDN server.
Updating a data chunk means explicitly providing a new version of it, where the "version" is just part of the name.
An example they use is /parc/videos/WidgetA.mpg/1/1 but for SPM's purposes, we could use whatever format we want. The important thing is the name must uniquely identify the data requested — in our case this would be a specific release version of the code in the identified package. Once a package version is published, the (versioned) name could no longer be used for anything else.
Just for sake of illustration, we could use names like these:
/spm/mklbtz/MyPackage/version/1/0/0
/spm/mklbtz/MyPackage/sha/deadbeef
Once "data" was published with these names, the names would be permanently locked to that code or binary. For ergonomics, only the inner part (mklbtz/MyPackage) would be specified in the Package.swift (I think?), the rest is just part of the spec or interpreted by the package host.
To be honest, I'm not sure if an NDN-like system would work or not. It might only be feasible if all the package hosts explicitly coordinated with each other to reach consensus the way DNS servers do — and that is probably unreasonable. Still, I thought it was a cool concept and hopefully it sparks some ideas.