mirror of
https://github.com/rust-lang/cargo
synced 2024-10-14 03:32:39 +00:00
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:
commit
b0fa79679e
|
@ -242,7 +242,20 @@ fn parse_dependencies(config: &Config, matches: &ArgMatches) -> CargoResult<Vec<
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|c| (Some(c.clone()), None))
|
.map(|c| (Some(c.clone()), None))
|
||||||
.collect::<IndexMap<_, _>>();
|
.collect::<IndexMap<_, _>>();
|
||||||
|
|
||||||
let mut infer_crate_name = false;
|
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 crates.is_empty() {
|
||||||
if path.is_some() || git.is_some() {
|
if path.is_some() || git.is_some() {
|
||||||
crates.insert(None, None);
|
crates.insert(None, None);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::command_prelude::*;
|
use crate::command_prelude::*;
|
||||||
|
|
||||||
|
use anyhow::anyhow;
|
||||||
use cargo::core::{GitReference, SourceId, Workspace};
|
use cargo::core::{GitReference, SourceId, Workspace};
|
||||||
use cargo::ops;
|
use cargo::ops;
|
||||||
use cargo::util::IntoUrl;
|
use cargo::util::IntoUrl;
|
||||||
|
@ -108,6 +109,16 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
|
||||||
.map(|k| resolve_crate(k, version))
|
.map(|k| resolve_crate(k, version))
|
||||||
.collect::<crate::CargoResult<Vec<_>>>()?;
|
.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 mut from_cwd = false;
|
||||||
|
|
||||||
let source = if let Some(url) = args.get_one::<String>("git") {
|
let source = if let Some(url) = args.get_one::<String>("git") {
|
||||||
|
|
1
tests/testsuite/cargo_add/add_toolchain/in
Symbolic link
1
tests/testsuite/cargo_add/add_toolchain/in
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../add-basic.in
|
23
tests/testsuite/cargo_add/add_toolchain/mod.rs
Normal file
23
tests/testsuite/cargo_add/add_toolchain/mod.rs
Normal 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);
|
||||||
|
}
|
5
tests/testsuite/cargo_add/add_toolchain/out/Cargo.toml
Normal file
5
tests/testsuite/cargo_add/add_toolchain/out/Cargo.toml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "cargo-list-test-fixture"
|
||||||
|
version = "0.0.0"
|
2
tests/testsuite/cargo_add/add_toolchain/stderr.log
Normal file
2
tests/testsuite/cargo_add/add_toolchain/stderr.log
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
error: invalid character `+` in dependency name: `+nightly`
|
||||||
|
Use `cargo +nightly add` if you meant to use the `nightly` toolchain.
|
0
tests/testsuite/cargo_add/add_toolchain/stdout.log
Normal file
0
tests/testsuite/cargo_add/add_toolchain/stdout.log
Normal file
|
@ -1,6 +1,7 @@
|
||||||
mod add_basic;
|
mod add_basic;
|
||||||
mod add_multiple;
|
mod add_multiple;
|
||||||
mod add_normalized_name_external;
|
mod add_normalized_name_external;
|
||||||
|
mod add_toolchain;
|
||||||
mod build;
|
mod build;
|
||||||
mod build_prefer_existing_version;
|
mod build_prefer_existing_version;
|
||||||
mod change_rename_target;
|
mod change_rename_target;
|
||||||
|
|
|
@ -57,6 +57,20 @@ fn simple() {
|
||||||
assert_has_not_installed_exe(cargo_home(), "foo");
|
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]
|
#[cargo_test]
|
||||||
fn simple_with_message_format() {
|
fn simple_with_message_format() {
|
||||||
pkg("foo", "0.0.1");
|
pkg("foo", "0.0.1");
|
||||||
|
|
Loading…
Reference in a new issue