[patch.dummyregistry] doesn't work properly

I'm working on some crates that are planned to become Open Source, though I currently do not plan to publish them on crates.io, due to the reasons outlined here (I do like crates.io, but I want to be able to update metadata, etc. when needed, and crates.io doesn't fit my own needs).

So the long-term plan is to run an individual registry and/or to use Cargo's possibility to include crates by specifying a repository (sadly only Git is supported here!).

Regarding individual registries, I went ahead and created an entry for a dummy registry in my ~/.cargo/config.toml:

[registries]
jbe = { index = "https://example.com/" }

[patch.jbe]
somecrate = { path = "/home/jbe/work/somecrate" }

Note that there doesn't exist any repository at example.com; it's just a dummy as I want to override via [patch.jbe].

If I have an othercrate, which uses somecrate, then it works (sometimes). Suppose my crate othercrate has the following Cargo.toml:

[dependencies]
somecrate = { version = "0.0.0", registry = "jbe" }

Unfortunately, this only sometimes works (if I have previously built othercrate by specifying a path in the dependencies sections and keeping the created Cargo.lock file).

And this always fails once I try to add another crate which uses these two. Even just adding the following line to my ~/.cargo/config.toml will make othercrate fail to compile if it did build previously:

 somecrate = { path = "/home/jbe/work/somecrate" }
+othercrate = { path = "/home/jbe/work/othercrate" }

I assume my mistake is to use a registry that doesn't exist? But it's strange how it sometimes works and sometimes not, and how the line above makes it not working after it previously worked.

What is the proper way to do what I want? Which is:

  • Not including (host dependent) paths in my crates' Config.toml files
  • Overriding the sources for crates on my (and other) development machines

In the Cargo Book, I read there was a [replace] section, which is now deprecated.

I also tried with paths overrides, but the Cargo Book doesn't even specify the section where these paths have to be set. I tried the root level, the [package] section, and creating a [dependencies] sections. All without success.

Any help is appreciated!


Update 1:

I just wondered if workspaces could fix my problem, but apparently, here also [patch] sections are used:

The [patch] , [replace] and [profile.*] sections in Cargo.toml are only recognized in the root manifest, and ignored in member crates' manifests.

So I don't think this would help either.

What's the idiomatic way to override dependencies locally when depending on crates which aren't published (publicly or locally) in any registry or git repository? Is there a way at all? Am I the only one who needs/wants this? Do I want something wrong?

The crate system is really nice, but I feel like when I don't use crates.io (or a Git server), then things get unnecessarily complicated. :frowning_face:

(I guess this isn't better in other languages either.)


Update 2:

I found some answers (but didn't like them).

First of all, the paths override mechanism has to be specified in the root level of Cargo's config.toml, as the example suggests. (Note that this is not mentioned where the paths overrides are explained; it's just what the example suggests.)

But re-reading the paths override section carefully, it ends with:

Note: using a local configuration to override paths will only work for crates that have been published to crates.io. You cannot use this feature to tell Cargo how to find local unpublished crates.

In other words: I cannot use this feature unless I'd publish a dummy crate on crates.io (which I will not do, of course).

Why? :angry:


Update 3:

I found a workaround to use a [patch.dummyregistry] section in Cargo's config.toml.

I have to create a Git repository with a single config.json file at the repository root:

{
    "dl": "https://registry.invalid/",
}

And place that Git repository somewhere on my file system, e.g. /opt/dummyregistry.

Then I can include the following in Cargo's config.toml file:

[registries]
dummyregistry = { index = "file:///opt/dummyregistry/" }

[patch.dummyregistry]
somecrate = { path = "…" }
anothercrate = { path = "…" }

I guess I don't need this anymore when/if I have setup my own registry. But I wonder why cargo accesses the registry when it doesn't need to (i.e. when there are patch entries for all involved packages). It makes me wonder if my build process will fail when I don't have access to the registry (e.g. because my internet is down) even when all dependencies are overridden with patch entries.

Either way, I feel like using anything else than crates.io is a hassle. But I'm thankful that Cargo supports alternative registries at all. Maybe setting up one isn't so difficult after all, once I read more about it.

I don't think I'm the only person who works with creates that are not yet released publicly (and who hasn't setup an own registry yet).

I wished things were easier, and I still believe the paths override should also work for not-yet-existing crates, which it currently doesn't. I don't understand why. Is there any good (technical) reason why it doesn't?