Auto merge of #12226 - danilhendrasr:feat/emit-error-on-toolchain-add-and-install, r=weihanglo

Emit error when users try to use a toolchain via the `add` or `install` command

Running `cargo install +nightly` or `cargo add +nightly` does not actually use the nightly toolchain, but the user won't know until the compilation fails. With this PR, an error is emitted if the `install` and `add` command is given a crate name
that starts with a `+` as we assume the user's intention was to use a certain toolchain instead of installing/adding a crate.

Example:
<img width="758" alt="image" src="https://github.com/rust-lang/cargo/assets/45989466/16e59436-32ee-49ee-9933-8b68b176c09d">

Fixes #10362
This commit is contained in:
bors 2023-06-03 14:19:48 +00:00
commit b0fa79679e
9 changed files with 70 additions and 0 deletions

View file

@ -242,7 +242,20 @@ fn parse_dependencies(config: &Config, matches: &ArgMatches) -> CargoResult<Vec<
.flatten()
.map(|c| (Some(c.clone()), None))
.collect::<IndexMap<_, _>>();
let mut infer_crate_name = false;
for (crate_name, _) in crates.iter() {
let crate_name = crate_name.as_ref().unwrap();
if let Some(toolchain) = crate_name.strip_prefix("+") {
anyhow::bail!(
"invalid character `+` in dependency name: `+{toolchain}`
Use `cargo +{toolchain} add` if you meant to use the `{toolchain}` toolchain."
);
}
}
if crates.is_empty() {
if path.is_some() || git.is_some() {
crates.insert(None, None);

View file

@ -1,5 +1,6 @@
use crate::command_prelude::*;
use anyhow::anyhow;
use cargo::core::{GitReference, SourceId, Workspace};
use cargo::ops;
use cargo::util::IntoUrl;
@ -108,6 +109,16 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
.map(|k| resolve_crate(k, version))
.collect::<crate::CargoResult<Vec<_>>>()?;
for (crate_name, _) in krates.iter() {
if let Some(toolchain) = crate_name.strip_prefix("+") {
return Err(anyhow!(
"invalid character `+` in package name: `+{toolchain}`
Use `cargo +{toolchain} install` if you meant to use the `{toolchain}` toolchain."
)
.into());
}
}
let mut from_cwd = false;
let source = if let Some(url) = args.get_one::<String>("git") {

View file

@ -0,0 +1 @@
../add-basic.in

View file

@ -0,0 +1,23 @@
use cargo_test_support::compare::assert_ui;
use cargo_test_support::prelude::*;
use cargo_test_support::Project;
use cargo_test_support::curr_dir;
#[cargo_test]
fn case() {
let project = Project::from_template(curr_dir!().join("in"));
let project_root = project.root();
let cwd = &project_root;
snapbox::cmd::Command::cargo_ui()
.arg("add")
.arg_line("+nightly")
.current_dir(cwd)
.assert()
.failure()
.stdout_matches_path(curr_dir!().join("stdout.log"))
.stderr_matches_path(curr_dir!().join("stderr.log"));
assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
}

View file

@ -0,0 +1,5 @@
[workspace]
[package]
name = "cargo-list-test-fixture"
version = "0.0.0"

View file

@ -0,0 +1,2 @@
error: invalid character `+` in dependency name: `+nightly`
Use `cargo +nightly add` if you meant to use the `nightly` toolchain.

View file

@ -1,6 +1,7 @@
mod add_basic;
mod add_multiple;
mod add_normalized_name_external;
mod add_toolchain;
mod build;
mod build_prefer_existing_version;
mod change_rename_target;

View file

@ -57,6 +57,20 @@ fn simple() {
assert_has_not_installed_exe(cargo_home(), "foo");
}
#[cargo_test]
fn toolchain() {
pkg("foo", "0.0.1");
cargo_process("install +nightly")
.with_status(101)
.with_stderr(
"\
[ERROR] invalid character `+` in package name: `+nightly`
Use `cargo +nightly install` if you meant to use the `nightly` toolchain.",
)
.run();
}
#[cargo_test]
fn simple_with_message_format() {
pkg("foo", "0.0.1");