[Pre-RFC] Cargo command to just sync lockfile

I'm in a bit of a pickle: right now, my CI will bump the version number of my --bin package in Cargo.toml after all checks/tests, and commit/push that change. However, if a later job in the pipeline) then attempts to cargo publish this new version, it will fail. This seems to happen because the root version in the lockfile is out-of-date: publish updates Cargo.lock as a first step, but then immediately fails because the repo is not current.

My workaround here is to run a simple command (like cargo fetch) which will update the lockfile as a side effect before committing the version change. However, it seems to me that there should be a low-level cargo command which does only that, so I created one. I've created a simple demo PR (edit: here) for rust-lang/cargo that adds a sync-lockfile command. This command differs from update and generate-lockfile in that if a lockfile already exists, it updates only the root version to match what's in Cargo.toml.

Is there anyone who's experienced this problem? Is there already a solution for me out there? Looking for feedback before making a real RFC; I'm willing to implement--the actual work seems pretty trivial, and my demo probably is 80% the way there.

Edit: changing the PR so that instead of a new top-level command, this becomes cargo update --workspace

I tend to use something like: cargo update -p my-root-crate

I run into this problem too.

I solve it by running cargo test && git commit -am Bump. It's slow and adds more commits than I'd like, but has a nice effect of preventing publishing broken code :slight_smile:

My ideal solution would be to completely remove versions of root/workspace crates from the lockfile. These versions are redundant. These crates are not dependencies. Keeping them in sync with their own lockfile is busywork.

A couple of related issues, first that cargo generate-lockfile should do what you want (though it may be too late to change this without breaking people, so a new command may be needed):

And @kornel’s suggestion:

1 Like

One nice thing about the current Cargo.lock format is all [[package]] entries have a corresponding [[package.version]]. To support versionless [[package]]s, this would mean the version attribute would have to become a fallible Option:

Removing these packages entirely means it's no longer possible to enumerate the "root" packages in a workspace from Cargo.lock alone, which would also be unfortunate. The cargo-lock crate just added detection support for these packages, as it were:

I wonder if a flag could be added to cargo generate-lockfile instead of adding an entirely new command. Like --no-update or something.

My thought was add a --workspace-members flag to cargo update, it is like @cuviper's suggestion in a loop.

Thanks everyone for feedback. The Cargo team gave similar feedback; I'm going to change my PR so as not to add a new command, but a --workspace flag to cargo update. This will only update the workspace version: it won't touch the index unless you don't already have a Cargo.lock, or if your Cargo.lock is missing some new dependencies.

It would be nice to not have to keep the version numbers in Cargo.toml and Cargo.lock in sync at all, but as bascule mentioned, there is probably some value in keeping them in the lock file. At least for now.

Let me know what you think!

2 Likes