In this discussion I've ended up with the following idea. I think it's worth to flesh out it a bit more and have more eyes on it.
Motivation
Recently the problem of "dependencies explosion" have been raised many times. A natural reaction is to push for limiting or even reversing split of projects into smaller crates (e.g. tokio).
While small-crate approach indeed has its issues (e.g. in some cases it can increase maintenance cost a bit or make reviews harder, makes life of Linux package maintainers harder), it also has its undeniable advantages (e.g. in some cases it allows to dramatically reduce a total amount of LoC in user projects, thus making it easier to do reviews, opens doors to incremental stabilization, faster API iterations, etc.). So as usual there is a golden middle way between huge monolithic crates and one-liner "nano" crates to be found, which will vary between projects.
But in addition to technical merits and demerits, I think there is a significant hidden factor which influences discussions of this problem: a total number of crates is the only metric which users constantly see when they build Rust projects. So instead of focusing on (arguably) far more important metrics like total amount of LoC in a project or number of groups which maintain project dependencies, they tend to use size of project's dependency tree as a complexity metric. So when a monolithic crate in a dependency tree splits into a number of smaller crates, they perceive it as an unwarranted complexity explosion which increases risks for their project, even though a total amount of code and a number of maintainers who you have to trust haven't changed. Thus in my opinion this psychological factor has a significant influence other people position in micro-crates discussions, which ideally should be suppressed in order for people to focus on technical points more.
Proposed Solution
I propose to add the project
field to Cargo.toml:
[package]
name = "rand_core"
version = "0.5.1"
project = "rand"
This field will be used to indicate that this crate is part of the given crates umbrella, thus it will be much easier to establish that for example rand
, 'rand_chacha', rand_core
and getrandom
are all part of the single project and thus can be essentially viewed as a single crate when analyzing risks for a project.
To make this information more visible cargo
can by default group crates using the project name. For example if we'll take sha3
crate as an example, instead of:
Compiling typenum v1.11.2
Compiling byteorder v1.3.2
Compiling byte-tools v0.3.1
Compiling opaque-debug v0.2.3
Compiling keccak v0.1.0
Compiling block-padding v0.1.4
Compiling generic-array v0.12.3
Compiling block-buffer v0.7.3
Compiling digest v0.8.1
Compiling sha3 v0.8.2
You will see:
Compiling typenum v1.11.2
Compiling byteorder v1.3.2
Compiling generic-array v0.12.3
Compiling project crates: crypto (byte-tools v0.3.1, opaque-debug v0.2.3,
keccak v0.1.0, block-padding v0.1.4, block-buffer v0.7.3,
digest v0.8.1, sha3 v0.8.2)
This way users during build will see per-line not a total number of crates, but a number of groups which maintain their dependency trees, which is as stated earlier is a more important metric to look after. If only project has only one crate in a dependency tree, then to make output less noisy grouping will not be used.
To protect from project name hijacks we can mandate that only crate names can be used as a project name. To publish a crate with project name "foo", you have to hold write access to the "foo" crate, otherwise crates.io will deny such upload.
Extension
Since many crates do not belong to a big multi-crate project, it may be useful to add an extension which will allow to use author username as a "project" name, with the same grouping behavior during builds. For example:
[package]
name = "byteorder"
version = "1.3.2"
project = "user:BurntSushi"
You will be able to upload such crates only if "project" user is registered by crates.io as its owner .