Get `cargo install` to fail silently if the binary already exists?

I have a CI job that attempts to install cargo-readme using cargo install. It depends upon another CI job that usually has already installed it, and so I want to run cargo install on the expectation that the binary is probably already present, but that it should install it if it isn't.

Running locally, this works fine:

$ cargo version
cargo 1.74.0-nightly (96fe1c9e1 2023-08-29)
$ cargo install cargo-readme --version 3.2.0
     Ignored package `cargo-readme v3.2.0` is already installed, use --force to override
$ echo $?
0

The CI job, on the other hand, failed with this error:

error: binary `cargo-readme` already exists in destination
Add --force to overwrite

Is there any way to force Cargo to use the graceful behavior rather than emitting an error in this case? I don't want to suppress all errors - if the binary doesn't exist and installation fails, I want to know about it - so I can't just discard all errors from the command entirely.

cargo install keeps track of which binaries it has installed in ~/.cargo/crates.toml and ~/.cargo.crates2.json. (I'm not sure what the difference is; perhaps one is just for other tools to read?)

Therefore, it seems likely that the difference is that you're not preserving that data across jobs and then cargo install is assuming that the binary is managed by something else and should be left alone.

Have you considered using a pre-built binary? cargo install is relatively slow and expensive.

I use Debian in CI, and use cargo-deb to pre-package binaries I need.

1 Like

I'll try caching all of ~/.cargo, thanks!

EDIT: That worked.

Hmmm interesting. When do you generate the deb files? Do you have a repo that uses this for CI that I could take a look at.

Unfortunately I don't have a nice example that I could share. At work I have proper debian repos, but that's an overkill for a single CI. For my personal projects I do things more ad-hoc. I just use git clone; cargo deb locally to prepare packages, and then curl -O deb; dpkg -i *.deb in CI.

1 Like

You can probably hack it out in bash as well with something like

which cargo-readme || cargo install cargo-readme
3 Likes

Where do you host the deb files?

My private vps, but any place that can serve a file will suffice.

Gotcha. For this, I'd rather avoid having to maintain separate infrastructure, but I guess I could see just committing binaries to the Git repo and installing them from there.