AFAIK the suggestion is not to hide subcrates, but to group them together so they get less visual emphasis than “non-sub” crates.
I think that packs solve two problems:
- The scattered trust problem that you mention here: instead of trusting 30 groups of developers, you only trust 2 or 3 groups of maintainers.
- The scattered version problem: instead of having to talk about 30 different crate versions, you only need to talk about 2 or 3 versions.
I want to keep the advantages of microcrates too; which is why after listing a pack you should be able to list which sub-parts you depend on:
[dependencies] tokio = "0.1.22" tokio-core = "tokio" tokio-io = "tokio" tokio-net = "tokio"
And the "publish" action should mandate listing all parts directly depended on.
You on the other hand try to move trust points from crate maintainers to meta/pack maintainers, so instead of trusting 10 developers, you will have to trust just a couple of crate reviewers instead. It's indeed a viable approach, which tackles the issue from a different angle. And I don't think that both approaches are mutually exclusive.
Note that in practice I'd expect significant overlap. For example, sticking with the example of tokio, I'd expect the tokio developers to release the tokio pack which would contain all "official" tokio crates that they develop, and possibly a few other tokio addons they do not develop themselves.
On the other hand, it may be that an alliance of multiple crypto libraries developers would form to create a maintainer group publishing a crypto pack. You'd essentially trust into the same group of developers, but as one group instead of 10 separate groups.
I would also note that this is really just the other side of the coin of your "project" proposal; except that instead of annotating each crate of the project, you'd create a meta-crate that list all parts of the project. The main advantage I see over the "project" approach is preventing squatting by design: in the project approach it's not clear who is responsible for the project, and thus who you trust, and how rogue crates are prevented from claiming to be part of the "project", with a meta-crate/pack, the set of maintainers of the pack is immediately visible on the crates.io page.
You could even combine the two approaches and declare that a crate can only be part of a pack if it declares
project = "<name-of-project>" in its Cargo.toml.
Projects/Packs are just a convenient way of managing dependencies by reducing the number of moving parts. They may help reducing the trust-base a bit, depending on which projects/packs you should to depend on, but you may still be at the mercy of a rogue maintainer uploading a malicious library, or a tired maintainer uploading a faulty one.
As such, review frameworks, CVE databases, etc... are still necessary regardless.
On the other hand, since you have less dependencies to track; it becomes easier to talk about them. You only need to check that the handful of projects/packs you use are up-to-date/reviewed/not-known-to-be-vulnerable, rather than having to check each and every crate independently. So it's helpful, but does not substitute for something else.
In this vein, there are micro crates that exist solely for visibility control, which sounds silly since submodules control visibility sufficiently well. We might however consider visibilities like
pub(feature = "feature_flag")makes the item nominally public, but only importable if feature_flag is present. In principle, crates might define their own semver properties for feature flags, so long as they warn users.
pub(crate macro), or
pub(macro)for short, makes the item public but only namable from macros defined in the current crate.
pub(repository macro)could work as expected, but probably redundant with the above two working together.
There is a high degree of similarity between crate tree and module tree. The line between them is blurry, but if Rust adds more crate-like features to modules, it'll be even blurrier.
So I'd say that if you need to version a module, it should have been a crate.