It is quite common for Rust projects to be split into two crates: a library crate and a bin crate (with the bin crate depending on the library crate)[1], so that the CLI can have additional dependencies[2] and that both can have their own independent version.
This does however pose a dilemma for projects where the library and the binary are intended to share the same name:
- For libraries the most intuitive installation procedure is if you can just run
cargo add <library>and then import the library withuse <library>;. - For applications the most intuitive installation procedure is
cargo install <command>and then being able to just run<command>.
While Rust does let libraries and binaries with the same name co-exist (via lib.name or bin.name), to publish both crates on crates.io, one of the crates will have to be named differently than its primary artifact.
Personally the first of the above points takes priority for me, so if I have a project foobar, I'd name the library crate foobar and the CLI crate foobar-cli. This does however result in the following UX problem:
To obtain the foobar command, users will be tempted to run cargo install foobar, which will however inevitably fail with the error message:
$ cargo install foobar
Updating crates.io index
error: there is nothing to install in `foobar v0.1.0`, because it has no binaries
`cargo install` is only for installing programs, and can't be used with libraries.
To use a library crate, add it as a dependency in a Cargo project instead.
My problem with this error message is that it does not tell the user about the existence of the foobar-cli crate. While cargo could check if such a crate existed, it of course should not assume anything about the purpose of crates just by their names.
So I was thinking how we could cleanly[3] solve this UX problem and thought we may want to introduce a new Cargo.toml field package.recommended-bin-crates so that in the above example the Cargo.toml from the foobar library crate could configure:
[package]
name = "foobar"
# etc.
recommended-bin-crates = ["foobar-cli"]
Which could then be picked up by the cargo install command when it detects that the crate doesn't have any binaries, to display a message such as the following to the user:
The developers of
foobarsuggest you may want to installfoobar-cliinstead.
What do you think about this dilemma / my idea? I'd be alright with writing an RFC for such a new recommended-bin-crates field, but I'm posting here first for some initial feedback ![]()
Prominent examples of that are
diesel&diesel-cliorwasm-bindgen&wasm-bindgen-cli. âŠī¸Since cargo currently doesn't support target-specific dependencies, see also the recently started RFC 3374. âŠī¸
The
clippycrate uses a failing build script to makecargo install clippyprint a message about using rustup ... however I'd really rather not resort to such hacks for my own projects, especially because this could also result in some user confusion (e.g. lib.rs would display theapplabel for the library-only crate). âŠī¸