Discussion on r/rust:
Say you have a workspace with three crates
A, B, C, with A depending on B and C. If you want to push a new version, you first have to change the version number of B and C, and publish them both. Then you need to change the manifest of A, which holds dependencies on B and C, and change each dependency’s number; the manifest should require exact version numbers, to make sure that users of
A 1.3don’t end up using
B 1.7on accident.
Each of these changes must be done in a specific order; cargo will complain if you try to publish a crate in a repository with uncommitted changes, so you will need to either commit between each change or suppress the error.
This isn't true, you can update all version numbers in the repository in a single commit then release all three crates from that same commit.
The primary reason I see for separating out subcrates is to allow more specific semver implications (ignoring proc-macros where I would like to see the ability to have private library crates in the same package, not as separately published crates). You can have different subcrates progress their breaking changes at different speeds to allow better interoperability between users of those crates. By forcing only lockstep version numbering that usecase isn't catered to.
Note that packages-as-namespaces would help with this.
Well, that actually causes issues with the specific case I'm thinking of. The top-level crate doesn't just
pub use self_core as core;, instead it re-exports a very similar looking API tree as it's core crate (and it has other sub-crates it re-exports components of at points that don't exactly match), it's much closer to
std than the design RFC3243 uses.
New concepts are unnecessary to solve this problem. A Cargo
[package] can contain multiple crates already, which can be published and versioned as a single unit.
What's missing is a support for multiple
[[lib]] crates in a single
[package] the way you can already have multiple
[[bin]] crates in a single
Here's a previous proposal to add such support: Multiple libraries in a cargo project
Can multiple crates be released with a single
If this is possible, it'd be nice to have some kind of atomicity guarantee. I don't want to try and publish a 20-crate workspace and have it fail halfway through (network failure, transient test hiccup, whatever). Do I fix and bump the half that need fixing? Or do I retag everything and yank?
I'm worried that Rust will end up with so many ways to split and organize crates, that it will become a source of confusion and bikeshedding.
We already have one crate with lib+bin vs separate bin and lib crates (with more features proposed to keep lib+bin single crate useful for longer). Then we have splitting into workspace. Then we'll have namespaces. Then we'll have subcrates. And noobs will be asking question what's the difference between module, package, target, crate, inline crate, subcrate, workspace and namespace?