-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Description
Describe the problem you are trying to solve
There are a couple of places in TOML where we need to identify a crate source:
[patch]inCargo.toml[source]in cargo config
The problem is that some crates come from sources that do not have a name:
- Local crates
- Git repos
For the latter case, cargo has introduced a special syntax in order to allow patching:
[patch."<url>"]However, this syntax does not contain all the information necessary to identify the source: it will just match all sources that use the same URL, and this results in bugs like #7670 and #5478. It is also just confusing for users because it doesn't appear as though cargo has all the information needed to figure out which crate to patch.
Describe the solution you'd like
I would like to introduce a standard way to identify unnamed sources that can be applied consistently to both [patch] and [source] keys, and is obvious how to extend to cope with new ways of specifying dependencies in the future (for example if support for other VCSs is added).
The existing [patch."<url>"] syntax would be soft-deprecated in the same way as [replace]. The [patch.<name>] syntax would still be the correct way to patch named sources.
Unnamed dependencies are identified using an array of tables:
[[patch."*"]]
_source = { git = "<url>", branch = "master" }
foo = { path = "../foo" }
bar = { path = "../bar" }
[[patch."*"]]
_source = { path = "../baz" }
baz = { git = "<url>" }The same pattern could be used for source replacement using [[source."*"]].
The following two examples are logically equivalent:
[[patch."*"]]
_source = { registry = "example" }
foo = { path = "../foo" }[patch.example]
foo = { path = "../foo" }Notes
I think we could also improve the way this is documented: I always end up having to look up the syntax for patching git dependencies, because there's no way to extrapolate from a set of rules you can easily remember.
We would define a crate source identifier to be an object with some subset of the following keys:
source_id = {
# Keys for anonymous sources
git = "...",
branch = "...",
rev = "...",
path = "...",
# Key for a named source
registry = "..."
}We define a dependency specification to essentially extend a source_id object with some additional keys:
versionoptionalfeatures- etc.
This way it's easy to figure out how to patch a dependency: you just need to take the dependency object, remove all the keys that are not part of a source_id, and you have the syntax for patching that dependency.
Bikeshedding
The _source key could potentially conflict with a crate name. Either that name or some other name (tbd) would need to be reserved or we could a name that cannot conflict like "@source" with the caveat that you'd then need to quote it.
The "*" could also be substituted for some other key like "unnamed" or something.