Skip to content

Commit b0fa796

Browse files
committed
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
2 parents ab0e1f7 + 58b7bce commit b0fa796

File tree

9 files changed

+70
-0
lines changed

9 files changed

+70
-0
lines changed

src/bin/cargo/commands/add.rs

+13
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,20 @@ fn parse_dependencies(config: &Config, matches: &ArgMatches) -> CargoResult<Vec<
242242
.flatten()
243243
.map(|c| (Some(c.clone()), None))
244244
.collect::<IndexMap<_, _>>();
245+
245246
let mut infer_crate_name = false;
247+
248+
for (crate_name, _) in crates.iter() {
249+
let crate_name = crate_name.as_ref().unwrap();
250+
251+
if let Some(toolchain) = crate_name.strip_prefix("+") {
252+
anyhow::bail!(
253+
"invalid character `+` in dependency name: `+{toolchain}`
254+
Use `cargo +{toolchain} add` if you meant to use the `{toolchain}` toolchain."
255+
);
256+
}
257+
}
258+
246259
if crates.is_empty() {
247260
if path.is_some() || git.is_some() {
248261
crates.insert(None, None);

src/bin/cargo/commands/install.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::command_prelude::*;
22

3+
use anyhow::anyhow;
34
use cargo::core::{GitReference, SourceId, Workspace};
45
use cargo::ops;
56
use cargo::util::IntoUrl;
@@ -108,6 +109,16 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
108109
.map(|k| resolve_crate(k, version))
109110
.collect::<crate::CargoResult<Vec<_>>>()?;
110111

112+
for (crate_name, _) in krates.iter() {
113+
if let Some(toolchain) = crate_name.strip_prefix("+") {
114+
return Err(anyhow!(
115+
"invalid character `+` in package name: `+{toolchain}`
116+
Use `cargo +{toolchain} install` if you meant to use the `{toolchain}` toolchain."
117+
)
118+
.into());
119+
}
120+
}
121+
111122
let mut from_cwd = false;
112123

113124
let source = if let Some(url) = args.get_one::<String>("git") {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../add-basic.in
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use cargo_test_support::compare::assert_ui;
2+
use cargo_test_support::prelude::*;
3+
use cargo_test_support::Project;
4+
5+
use cargo_test_support::curr_dir;
6+
7+
#[cargo_test]
8+
fn case() {
9+
let project = Project::from_template(curr_dir!().join("in"));
10+
let project_root = project.root();
11+
let cwd = &project_root;
12+
13+
snapbox::cmd::Command::cargo_ui()
14+
.arg("add")
15+
.arg_line("+nightly")
16+
.current_dir(cwd)
17+
.assert()
18+
.failure()
19+
.stdout_matches_path(curr_dir!().join("stdout.log"))
20+
.stderr_matches_path(curr_dir!().join("stderr.log"));
21+
22+
assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[workspace]
2+
3+
[package]
4+
name = "cargo-list-test-fixture"
5+
version = "0.0.0"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
error: invalid character `+` in dependency name: `+nightly`
2+
Use `cargo +nightly add` if you meant to use the `nightly` toolchain.

tests/testsuite/cargo_add/add_toolchain/stdout.log

Whitespace-only changes.

tests/testsuite/cargo_add/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod add_basic;
22
mod add_multiple;
33
mod add_normalized_name_external;
4+
mod add_toolchain;
45
mod build;
56
mod build_prefer_existing_version;
67
mod change_rename_target;

tests/testsuite/install.rs

+14
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,20 @@ fn simple() {
5757
assert_has_not_installed_exe(cargo_home(), "foo");
5858
}
5959

60+
#[cargo_test]
61+
fn toolchain() {
62+
pkg("foo", "0.0.1");
63+
64+
cargo_process("install +nightly")
65+
.with_status(101)
66+
.with_stderr(
67+
"\
68+
[ERROR] invalid character `+` in package name: `+nightly`
69+
Use `cargo +nightly install` if you meant to use the `nightly` toolchain.",
70+
)
71+
.run();
72+
}
73+
6074
#[cargo_test]
6175
fn simple_with_message_format() {
6276
pkg("foo", "0.0.1");

0 commit comments

Comments
 (0)