I primarily want to use Debian’s Rust packages, rather than fetching some random code from the wider Internet (I’m old-fashioned, I know, let’s not get into that part). To this end, my ~/.cargo/config.toml
looks like
[net]
offline = true
[source]
[source.crates-io]
replace-with = "debian"
[source.debian]
directory = "/usr/share/cargo/registry"
This works great after I install the librust-*-dev
packages that I desire. However, in some specific projects, I’d like to lift this rule and tell Cargo "hey, you can in fact go wild and get whatever you want from crates.io". According to the Cargo book, a project-specific /project/.cargo/config.toml
should take precedence over my user one. Assume this project-specific .cargo/config.toml
:
[net]
offline = false
[source]
[source.crates-io]
I’m still not able to cargo build
a project with dependencies from outside of my replacement source. If for example, I make a Cargo.toml
that depends on yew
(a randomly chosen crate that I know isn’t available in my replacement source) I get
$ cargo build
error: no matching package found
searched package name: `yew`
What am I misunderstanding about Cargo’s sources, replacement and per-project overrides?
3
Answers
The answer suggested by @blackgreen is one possible workaround for the underlying problem until issues 10045 and 10057 (or a combination thereof) are solved. Another, perhaps slightly less ugly, workaround follows below for those who need it.
I ended up working around the problem using UnionFS (I guess the more modern OverlayFS should work well too).
I simply add
to my
~/.cargo/config.toml
and then doNow
/home/gspr/.cargo-overlay/union-registry
reflects the union of/usr/share/cargo/registry
and/home/gspr/.cargo-overlay/local-registry
, with priority to the former in case of conflicts.So what goes in
~/.cargo-overlay/local-registry
? Individual extra crates, in the same way as in Debian's/usr/share/cargo/registry
. That is to say, directories namedcratename-version
as they are distributed by upstream – but with a single extra file, namely.cargo-checksum.json
added to them. The content of that extra file can be extracted from the crates.io index as follows.Suppose we have cloned the crates.io index into
~/.cargo-overlay/crates.io-index
, i.e.Then suppose we've extracted a crate
foo
at version0.1.2
into~/.cargo-overlay/local-registry/foo-0.1.2
. We can generate the missing.cargo-checksum.json
like so:It looks as if you are suffering from this issue: https://github.com/rust-lang/cargo/issues/8687
You would like to unset a config key on a upper-level
config.toml
but this is not supported.I’ve played a bit with the config, and the only way I got it to work was to overwrite in the project-local
config.toml
the properties that were set in the upper-levelconfig.toml
.In your case your upper-level
config.toml
specifiesreplace-with
, so you have to overwrite that. But you can’t overwrite it withcrates-io
, which is the registry you want to use, because that is exactly the registry with thereplace-with
key.So until the above issue gets acted upon, we have to, essentially, use a mirror, both in the config and as an actual registry to download from:
As we both tested, it seems it’s not possible to reuse the normal crates.io registry url because that is already defined and will fail with:
So instead the URL above is an actual mirror server of crates.io. Then you can run
cargo build
successfully in the local project.The recently released Cargo 1.56 adds a feature that should let one do what my question asks for: patch tables can now be specified in a project-specific
.cargo/config.toml
, which means that[patch]
stanzas can now be introduced outside ofCargo.toml
. That should do the trick! I haven’t yet verified this, as I am stuck with an older Cargo for a little while still.