-
Notifications
You must be signed in to change notification settings - Fork 1.7k
recommended-bin-packages field in Cargo.toml
#3383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
9c15ddc
1eaca13
d1515f2
9e15043
91dd59d
3bfc362
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,162 @@ | ||
| - Feature Name: recommended-bin-crates | ||
| - Start Date: 2023-01-04 | ||
| - RFC PR: [rust-lang/rfcs#3383](https://github.com/rust-lang/rfcs/pull/3383) | ||
|
|
||
| # Summary | ||
| [summary]: #summary | ||
|
|
||
| Add an optional `recommended-bin-crates` field to the `[package]` | ||
| section of `Cargo.toml`, to enable crate authors to point out related | ||
| binary crates in the error message Cargo users get when attempting to | ||
| `cargo install` a crate without binaries. | ||
|
|
||
| # Motivation | ||
| [motivation]: #motivation | ||
|
|
||
| Command-line tools written in Rust are often published in crates named | ||
| different than the command, since that name is already occupied by a | ||
| related library crate, for instance: | ||
|
|
||
| * the `diesel` command is provided by the `diesel_cli` binary crate, | ||
| that depends on the `diesel` library crate | ||
|
|
||
| * the `wasm-bindgen` command is provided by the `wasm-bindgen-cli` | ||
| binary crate, which is different from the `wasm-bindgen` library crate | ||
|
|
||
| While such a setup has several benefits, it currently leads to a | ||
| user experience problem with Cargo: To obtain a command, users will be | ||
| tempted to run `cargo install <command>`, which will however inevitably fail: | ||
|
|
||
| ``` | ||
| $ cargo install diesel | ||
| error: there is nothing to install in `diesel v2.0.3`, 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. | ||
| ``` | ||
|
|
||
| The idea of this RFC is that the `Cargo.toml` of such | ||
| a library-only crate could specify for instance: | ||
|
|
||
| ```toml | ||
| [package] | ||
| name = "diesel" | ||
| # ... | ||
| recommended-bin-crates = ["diesel-cli"] | ||
| ``` | ||
|
|
||
| which could be picked up by Cargo in order to additionally include | ||
| a note such as the following in the above error message: | ||
|
|
||
| > The developers of `diesel` suggest you may want to install `diesel-cli` instead. | ||
|
|
||
| resulting in a more seamless user experience. | ||
|
|
||
| # Guide-level explanation | ||
| [guide-level-explanation]: #guide-level-explanation | ||
|
|
||
| The following is written as if it was part of the [manifest page] of the Cargo Book. | ||
|
|
||
| ## The `recommended-bin-crates` field | ||
|
|
||
| The `recommended-bin-crates` field is an array of names of related binary crates. | ||
|
|
||
| ```toml | ||
| [package] | ||
| name = "foobar" | ||
| # ... | ||
| recommended-bin-crates = ["foobar-cli"] | ||
| ``` | ||
|
|
||
| Specifying this field for a library-only crate, enables Cargo to print | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens when this field is specified in a package with bins?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question. I'd say the field is specifically meant for crates without binaries. Specifying it for a crate with binaries wouldn't have any effect unless websites for crates would decide to display the field regardless. I'll clarify the Guide-level explanation accordingly. |
||
| a more user-friendly error message for `cargo install`, for example: | ||
|
|
||
| ``` | ||
| $ cargo install foobar | ||
| error: there is nothing to install in `foobar v1.2.3`, 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. | ||
|
|
||
| The developers of `foobar` suggest you may want to install `foobar-cli` instead. | ||
| ``` | ||
|
|
||
| (Notice the last line in the above output, which is enabled by the | ||
| `recommended-bin-crates` field.) | ||
|
|
||
| # Reference-level explanation | ||
| [reference-level-explanation]: #reference-level-explanation | ||
|
|
||
| The `cargo install` command has already parsed the `Cargo.toml` manifest | ||
| file when it prints this error message, so it would simply have to | ||
| additionally check for this new field when printing the error message. | ||
|
|
||
| `cargo publish` should assert that the referenced | ||
| crates already exist and have not been yanked. | ||
|
|
||
| # Drawbacks | ||
| [drawbacks]: #drawbacks | ||
|
|
||
| * It introduces yet another manifest `field`. | ||
|
|
||
| * The crates referenced by this field could become abandoned, out-of-date or yanked | ||
| (although the referencing and referenced crate will presumably often be published | ||
| by the same person/group, in which case this can be simply avoided). | ||
|
|
||
| * Like any other manifest field, updating the field requires you to publish | ||
| a new version of the crate (a patch version bump suffices). | ||
|
|
||
| # Rationale and alternatives | ||
| [rationale-and-alternatives]: #rationale-and-alternatives | ||
|
|
||
| The problem addressed by this RFC can be sidestepped by publishing the | ||
| library along with the binary in a single crate. This does however come | ||
| with two disadvantages: | ||
|
|
||
| * Cargo currently doesn't support artifact-specific dependencies | ||
| (although that may change, see [RFC 2887] & [RFC 3374]). | ||
|
|
||
| * You would have to bump the library version each time you want to | ||
| publish a new version of the binary. If you want independently | ||
| incrementable versions for your library and your binary, you have to | ||
| publish them in separate crates. | ||
|
|
||
| The problem could also be sidestepped by publishing the command in a | ||
| crate with the same name as the command and using a different name for | ||
| the library crate. (While `cargo add` currently does not fail for | ||
| binary-only crates that could very well be addressed without an RFC.) | ||
| A disparity between crate name and library name again comes with its | ||
| own disadvantages, e.g. Rust users often expect libraries published | ||
| on crates.io to be documented at docs.rs/{lib_name}. | ||
|
|
||
| So while these two alternatives have their own disadvantages, they are | ||
| also generally not an option for projects that have already been published | ||
| using the described naming convention, since converting a library-only | ||
| crate to a binary-only crate is bound to result in confusion. | ||
|
|
||
| The proposed field provides a simple solution to a rather annoying | ||
| problem and could be easily applied to existing projects using this | ||
| common naming convention to solve the described user experience problem. | ||
|
|
||
| # Prior art | ||
| [prior-art]: #prior-art | ||
|
|
||
| Most other package managers do not have such a problem since their | ||
| install command does not mandate that the package contains binaries. | ||
|
|
||
| # Unresolved questions | ||
| [unresolved-questions]: #unresolved-questions | ||
|
|
||
| * Is `recommended-bin-crates` a good name for the field? | ||
|
not-my-profile marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Future possibilities | ||
| [future-possibilities]: #future-possibilities | ||
|
|
||
| * crates.io and/or lib.rs could additionally link crates referenced via | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. aside: #3243 could offer another way to link these crates together in the UI |
||
| this new field on their library web pages | ||
|
|
||
| * Clippy could gain a lint to check that the referenced crates actually | ||
| exist, have not been yanked and are actually binary crates. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At least as of today, clippy does not lint Another problem is whatever does the linting would need to update and check the index. Also, is the "actually exist" check just to move the
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you are mistaken about clippy currently not linting You are right about the indexing part ... I can add a respective note to the RFC. Since this is the Future possibilities section, I think it's fine that some things would still need to be figured out. My reasoning for suggesting such a clippy lint is that the referenced packages may change after the referencing package has been published. E.g. if we publish a lib-only crate with a valid reference and the referenced crate gets yanked after, that wouldn't be picked up until we do a new
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are some clippy lints but the team seems hesitant about each new cargo clippy lint.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As an update, cargo's linting system is moving forward, see rust-lang/cargo#12235 The main question at this time is always-run lints (like rustc) vs on-demand lints (like clippy) |
||
|
|
||
|
|
||
| [manifest page]: https://doc.rust-lang.org/cargo/reference/manifest.html | ||
| [RFC 2887]: https://github.com/rust-lang/rfcs/pull/2887 | ||
| [RFC 3374]: https://github.com/rust-lang/rfcs/pull/3374 | ||
Uh oh!
There was an error while loading. Please reload this page.