Description
Right now it's far too easy to grab a package name and hold it hostage, even if the name is generally recognized as belonging to another project, or even if you don't actually have anything to publish yet. For example, both bindgen
and irc
have been claimed, apparently by @mahkoh (which isn't even exposed in the interface).
The proper solution to this is to namespace packages. They can be namespace using the GitHub user/organization name of the publisher. This way everyone can publish their own package, without worrying about collisions, and without any confusion when depending on a package as to whether it's the "official" package or not (well, for packages whose repositories are hosted on GitHub, which is likely to be most of them).
Packages with multiple owners can be deal with as follows:
- Anyone added as an owner to a package can still have their own namespaced version of the package, i.e. if the user
bob
adds the useralice
as an owner tobob/crypto
, thenalice
can still have an independentalice/crypto
package. This is important because the new owner might have already had a package with that name, and that needs to be preserved. Similarly, they may wish to keep a parallel fork for other reasons, or may wish to simply be able to use that name later if they are removed from the ownership list at a later date. - People who are owners on a package under someone else's namespace can publish using an extra flag to
cargo publish
that identifies the namespace. Similarly,.cargo/config
could learn how to record the namespace of a given package (presumably identified by path) to avoid having to remember to use the flag every time. I don't think it makes sense to put the owner name intoCargo.toml
because you probably don't want to commit this to git (if for no other reason than anyone who forks your git repo will not want that owner information because they can't publish your package). - Any original owner who is removed from the owner list of a package does not regain use of the name. Because crates.io wants to be a permanent archive, the namespaced package name must continue to identify that package. However, it should be rare for someone to want to be removed from the owner list of a package under their namespace, so that's unlikely to be an issue.
- Any package that wishes to switch namespaces, because of an ownership transfer, can simply be published to the new namespace. The existing package will remain the old namespace, for archival reasons.
We may wish to more formally support the idea of moving a package to another namespace. That could be accomplished as follows:
- Copy the entire history of the package to the new namespace. This means anyone depending on any existing version of the package at the old namespace can update to the new namespace and get the same package.
- "close" the old namespaced package, such that no new versions can be submitted, and display this on the package page, with information on where the new package can be found.
- When updating
Cargo.lock
, any package that is found that is closed can continue to be used, but cargo should display a warning telling the user that the package has moved and they should update theirCargo.toml
. - We may wish to support the ability for a user to reopen a "closed" package, but that should be rare enough that it can be handled manually. My recommendation would be to at least require any new published package be at least one "breaking change" higher than the highest version that existed when it was closed (so any
~
version specs will not pick up the new version).
With these changes in place, we could still support un-namespaced packages. These would be manually curated so as to ensure that nobody takes a name that is reasonably understood to refer to some other package (such as taking bindgen
). These top-level packages would really be aliases for the namespaced version, and Cargo.lock
would identify the namespace that it resolves to (and cargo
would either warn or error when updating a lockfile if any top-level package resolves to a different namespace than before).
This would serve as a weaker form of the archival guarantee of namespaced packages. A top-level package can change to identify a different package than before, if it makes sense to do so (e.g. an error was made, or an unofficial package gets claimed by the actual owning organization). For this reason it is recommended that libraries always use the namespaced name (since they aren't supposed to check their Cargo.lock
into version control), but binaries are free to use the top-level name (since cargo
will warn/error if the namespace resolution changes). This top-level naming is intended to be primarily useful for people trying to find packages. And the web UI can be updated to make it easier to avoid mistakes, by using the full namespaced name in the "Depend" code snippet.