Cargo command to just update the registry

I'm building a Rust crate in a Docker container, and iterating on it during development. Doing COPY source . and then RUN cargo build updates the registry and builds the code in one go, and the registry update takes by far the most time - but of course its docker cache is lost when the source changes.

Is there a cargo command I missed that will just checkout/update the crates.io registry? Creating an empty project, adding some dependency and calling cargo update is kind of cumbersome.

1 Like

Is it possible to first copy only Cargo.toml and Cargo.lock, do cargo update, then copy all other sources? AFAIK, that's what is considered "best practice" when building in Docker, no matter the concrete ecosystem.

Sure, that can work, although again checking out the registry does not invalidate when changes are made to Cargo.toml, so I'm not sure why that would be best practice.

When using COPY docker will invalidate all following steps when the copied file is changed. Because you copied Cargo.toml and Cargo.lock, any change to them would cause the registry to be updated again.

note: It is possible to use cargo fetch instead of cargo update in this case.
tip: You can see all cargo subcommands using cargo --list.

1 Like

I know that, and that's why it's not what I want: to just update the registry, not do anything depending on the project I'm working on. I.e. (pseudo-docker):

FROM rust
RUN cargo update-registry  # does not exist
COPY mysource .
RUN cargo build

The "copy Cargo.*; cargo fetch" solution works, with some hacking (e.g. Cargo.toml now needs to specify explicitly the bin/lib target).

I simply wonder if/why there isn't a command to do - independent of any Cargo.toml - just the checkout/update of ~/.cargo.

Hm, I guess when I already have Cargo.toml I can just as well call cargo build with an otherwise empty crate, which will also pre-build the dependencies in addition to downloading them, and ignore the error.

Cargo can't do it.

Copying just Cargo.toml won't work, because Cargo will check whether all related files (src/lib.rs, workspace crates, etc.) exist.

I use a workaround: create a new empty crate by creating Cargo.toml that includes section [lib] path = "/dev/null" and cargo fetch that.

cargo search used to fetch the registry as a side effect, but that helpful bug has been fixed.

Ok, thanks all! Creating a custom command obviously defeats the purpose - or, better, if I do cargo install I might as well install an empty crate :slight_smile:

It actually works, in a way! I'm now quite happily cargo build-ing with just Cargo.toml and Cargo.lock present. If Cargo.toml has an explicit entry for [bin] path = "src/main.rs" cargo/rustc only notices the missing file once all dependencies are fetched and compiled! (And then I can just ignore the resulting error exit.)

Of course my case is quite simple with a single crate, no workspace and only one target. I'm also not expecting this to work for all eternity, but it's good enough for me right now.