cargo and how crates.io doesn’t like cyclic dev-dependencies

cargo and how crates.io doesn’t like cyclic dev-dependencies

cargo, crates.io, hack, cyclic dependencies

2019-08-23 12:00:00 UTC, by Dimitri Sabadie


This is a very short blog article about a problem I found lately with cargo.

The problem

Imagine you have a crate A and a crate B and you want to upload them to crates.io. There is a context setup:

The main problem is that currently, you cannot do anything with such a setup. If you try to upload A to crates.io, crates.io will reject the crate because B doesn’t exist. That might be stunning, but yes, cargo also check that your [dev-dependencies] are correctly aligned with your A’s Cargo.toml. Meh.

If you try to upload B, obviously, since A is not there, crates.io will complain.

What should we do?

The (dirty) solution

First thing first, here’s a discussion that helped me figure out how to solve that issue. Disclaimer, though: it’s neither elegant and satisfying.

The first thing to do is to edit A’s Cargo.toml in order to completely strip its [dev-dependencies] section. Just remove it. All of it.

Then, and that’s the tricky part: do not git commit the change. At that point, you have removed the dependency from A to B, which is not mandatory for people getting the crate from crates.io. That’s the nasty part. You’re about to upload a crate which metadata are not aligned with your repository. I don’t like it, but I don’t see any other way to do it — however, you’ll see we can fix it afterwards.

Then, upload A to crates.io:

cd A
cargo publish --allow-dirty

The --allow-dirty switch is needed because cargo would complain about your working tree not being clean otherwise.

Now, you have A on crates.io. Just go on with B: it can now be uploaded:

cd ../B
cargo publish

Now you have, on crates.io:

The final part of the trick is to restore the sanity of A. Because, yes, I don’t like having something on crates.io that is not exactly the same thing as my repository.

Edit A’s Cargo.toml or check it out:

cd ..
git checkout .

Now you are exactly in the same situation as before trying anything to solve the problem. Edit A’s Cargo.toml and increment its patch version. In my case, I would get version X.Y.(Z+1). git commit your changes, git push. You’re ready to patch crates.io:

cd A
cargo publish

Now you have:

Conclusion

I know it’s not an ideal fix, but at least we end up on our (clean) feets. I really really think the cargo team should fix that issue, though. In that case, A and B were actually luminance and luminance-derive. I will make a long article very soon about them to introduce new versions, new crates and complete graphics tutorials on how to have fun with luminance.

I hope you liked that article and as always, keep the vibes.