From 9c15ddc04e5868f097b5e03e95b589bf6f6319f9 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Sat, 4 Feb 2023 09:21:57 +0100 Subject: [PATCH 1/6] recommended-bin-crates: Initial draft --- text/3383-recommended-bin-crates.md | 145 ++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 text/3383-recommended-bin-crates.md diff --git a/text/3383-recommended-bin-crates.md b/text/3383-recommended-bin-crates.md new file mode 100644 index 00000000000..9500d078238 --- /dev/null +++ b/text/3383-recommended-bin-crates.md @@ -0,0 +1,145 @@ +- 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 `, 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 +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. + +# Drawbacks +[drawbacks]: #drawbacks + +* It introduces yet another manifest `field`. +* The crates referenced by this field could become abandoned, out-of-date or yanked. +* Updating this field for a library crate requires you to bump its version. + +# 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, but this does arguably result in a worse user +experience problem since `cargo add` does not fail for binary-only +crates. + +This RFC poses a simple solution to a rather annoying 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? + +# Future possibilities +[future-possibilities]: #future-possibilities + +* crates.io and/or lib.rs could additionally link crates referenced via + 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. + + +[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 From 1eaca1384e5ae56293bb563de0dfff17b1e4361d Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Sat, 4 Feb 2023 18:42:21 +0100 Subject: [PATCH 2/6] recommended-bin-crates: Address feedback by Steffahn --- text/3383-recommended-bin-crates.md | 31 ++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/text/3383-recommended-bin-crates.md b/text/3383-recommended-bin-crates.md index 9500d078238..a06492e70c7 100644 --- a/text/3383-recommended-bin-crates.md +++ b/text/3383-recommended-bin-crates.md @@ -89,12 +89,20 @@ 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. -* Updating this field for a library crate requires you to bump its version. + +* 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 @@ -113,11 +121,20 @@ with two disadvantages: 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, but this does arguably result in a worse user -experience problem since `cargo add` does not fail for binary-only -crates. - -This RFC poses a simple solution to a rather annoying problem. +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 From d1515f250ffbb25a8161e67c480e7f976a72da53 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Sat, 4 Feb 2023 20:14:29 +0100 Subject: [PATCH 3/6] recommended-bin-crates: Stylize Cargo subcommands without dash --- text/3383-recommended-bin-crates.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/3383-recommended-bin-crates.md b/text/3383-recommended-bin-crates.md index a06492e70c7..dce7fbeced3 100644 --- a/text/3383-recommended-bin-crates.md +++ b/text/3383-recommended-bin-crates.md @@ -85,11 +85,11 @@ The developers of `foobar` suggest you may want to install `foobar-cli` instead. # Reference-level explanation [reference-level-explanation]: #reference-level-explanation -The `cargo-install` command has already parsed the `Cargo.toml` manifest +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 +`cargo publish` should assert that the referenced crates already exist and have not been yanked. # Drawbacks From 9e15043de0ce4adb684e16f7372bdd1b5f921de7 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Wed, 15 Feb 2023 18:07:37 +0100 Subject: [PATCH 4/6] recommended-bin-crates: Rename to recommended-bin-packages See https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html. --- ...rates.md => 3383-recommended-bin-packages.md} | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) rename text/{3383-recommended-bin-crates.md => 3383-recommended-bin-packages.md} (93%) diff --git a/text/3383-recommended-bin-crates.md b/text/3383-recommended-bin-packages.md similarity index 93% rename from text/3383-recommended-bin-crates.md rename to text/3383-recommended-bin-packages.md index dce7fbeced3..4695cce793b 100644 --- a/text/3383-recommended-bin-crates.md +++ b/text/3383-recommended-bin-packages.md @@ -1,11 +1,11 @@ -- Feature Name: recommended-bin-crates +- Feature Name: recommended-bin-packages - 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]` +Add an optional `recommended-bin-packages` 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. @@ -41,7 +41,7 @@ a library-only crate could specify for instance: [package] name = "diesel" # ... -recommended-bin-crates = ["diesel-cli"] +recommended-bin-packages = ["diesel-cli"] ``` which could be picked up by Cargo in order to additionally include @@ -56,15 +56,15 @@ resulting in a more seamless user experience. 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-packages` field -The `recommended-bin-crates` field is an array of names of related binary crates. +The `recommended-bin-packages` field is an array of names of related binary crates. ```toml [package] name = "foobar" # ... -recommended-bin-crates = ["foobar-cli"] +recommended-bin-packages = ["foobar-cli"] ``` Specifying this field for a library-only crate, enables Cargo to print @@ -80,7 +80,7 @@ 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.) +`recommended-bin-packages` field.) # Reference-level explanation [reference-level-explanation]: #reference-level-explanation @@ -145,7 +145,7 @@ 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? +* Is `recommended-bin-packages` a good name for the field? # Future possibilities [future-possibilities]: #future-possibilities From 91dd59de0c8ab768feb7bbcb89a454eef753cc91 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Wed, 15 Feb 2023 18:13:17 +0100 Subject: [PATCH 5/6] recommended-bin-packages: Fix terminology crate -> package See https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html. --- text/3383-recommended-bin-packages.md | 50 +++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/text/3383-recommended-bin-packages.md b/text/3383-recommended-bin-packages.md index 4695cce793b..3e617b866b1 100644 --- a/text/3383-recommended-bin-packages.md +++ b/text/3383-recommended-bin-packages.md @@ -6,22 +6,22 @@ [summary]: #summary Add an optional `recommended-bin-packages` 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. +section of `Cargo.toml`, to enable package authors to point out related +binary packages in the error message Cargo users get when attempting to +`cargo install` a package without binaries. # Motivation [motivation]: #motivation -Command-line tools written in Rust are often published in crates named +Command-line tools written in Rust are often published in packages named different than the command, since that name is already occupied by a -related library crate, for instance: +related library package, for instance: -* the `diesel` command is provided by the `diesel_cli` binary crate, - that depends on the `diesel` library crate +* the `diesel` command is provided by the `diesel_cli` binary package, + that depends on the `diesel` library package * the `wasm-bindgen` command is provided by the `wasm-bindgen-cli` - binary crate, which is different from the `wasm-bindgen` library crate + binary package, which is different from the `wasm-bindgen` library package While such a setup has several benefits, it currently leads to a user experience problem with Cargo: To obtain a command, users will be @@ -35,7 +35,7 @@ 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: +a library-only package could specify for instance: ```toml [package] @@ -58,7 +58,7 @@ The following is written as if it was part of the [manifest page] of the Cargo B ## The `recommended-bin-packages` field -The `recommended-bin-packages` field is an array of names of related binary crates. +The `recommended-bin-packages` field is an array of names of related binary packages. ```toml [package] @@ -67,7 +67,7 @@ name = "foobar" recommended-bin-packages = ["foobar-cli"] ``` -Specifying this field for a library-only crate, enables Cargo to print +Specifying this field for a library-only package, enables Cargo to print a more user-friendly error message for `cargo install`, for example: ``` @@ -90,25 +90,25 @@ 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. +packages 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 +* The packages referenced by this field could become abandoned, out-of-date or yanked + (although the referencing and referenced package 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). + a new version of the package (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 +library along with the binary in a single package. This does however come with two disadvantages: * Cargo currently doesn't support artifact-specific dependencies @@ -117,20 +117,20 @@ with two disadvantages: * 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. + publish them in separate packages. 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 +package with the same name as the command and using a different name for +the library package. (While `cargo add` currently does not fail for +binary-only packages that could very well be addressed without an RFC.) +A disparity between package 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. +package to a binary-only package 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 @@ -150,11 +150,11 @@ install command does not mandate that the package contains binaries. # Future possibilities [future-possibilities]: #future-possibilities -* crates.io and/or lib.rs could additionally link crates referenced via +* crates.io and/or lib.rs could additionally link packages referenced via 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. +* Clippy could gain a lint to check that the referenced packages actually + exist, have not been yanked and actually contain binary targets. [manifest page]: https://doc.rust-lang.org/cargo/reference/manifest.html From 3bfc36235e8ffb1b10fc2b23916e13d17ab617b2 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Wed, 15 Feb 2023 18:15:01 +0100 Subject: [PATCH 6/6] recommended-bin-packages: Clarify that packages are in the same registry --- text/3383-recommended-bin-packages.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/text/3383-recommended-bin-packages.md b/text/3383-recommended-bin-packages.md index 3e617b866b1..00963b83571 100644 --- a/text/3383-recommended-bin-packages.md +++ b/text/3383-recommended-bin-packages.md @@ -58,7 +58,8 @@ The following is written as if it was part of the [manifest page] of the Cargo B ## The `recommended-bin-packages` field -The `recommended-bin-packages` field is an array of names of related binary packages. +The `recommended-bin-packages` field is an array of names of related +binary packages that have been published in the same registry. ```toml [package]