From 92a5d5e56ad4a49ae1a37bddfa1d146b20659446 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 11 Mar 2025 11:07:39 -0500 Subject: [PATCH 01/12] test(run): Move run-focused test with rest --- tests/testsuite/run.rs | 149 ++++++++++++++++++++++++++++++++++ tests/testsuite/workspaces.rs | 149 ---------------------------------- 2 files changed, 149 insertions(+), 149 deletions(-) diff --git a/tests/testsuite/run.rs b/tests/testsuite/run.rs index 1804f2c9eae..1755b658502 100644 --- a/tests/testsuite/run.rs +++ b/tests/testsuite/run.rs @@ -783,6 +783,155 @@ Available example targets: .run(); } +// See rust-lang/cargo#14544 +#[cargo_test] +fn print_available_targets_within_virtual_workspace() { + let p = project() + .file( + "Cargo.toml", + r#" + [workspace] + resolver = "3" + members = ["crate1", "crate2", "pattern1", "pattern2"] + + default-members = ["crate1"] + "#, + ) + .file("crate1/src/main.rs", "fn main(){}") + .file( + "crate1/Cargo.toml", + r#" + [package] + name = "crate1" + version = "0.1.0" + edition = "2024" + "#, + ) + .file("crate2/src/main.rs", "fn main(){}") + .file( + "crate2/Cargo.toml", + r#" + [package] + name = "crate2" + version = "0.1.0" + edition = "2024" + "#, + ) + .file("pattern1/src/main.rs", "fn main(){}") + .file( + "pattern1/Cargo.toml", + r#" + [package] + name = "pattern1" + version = "0.1.0" + edition = "2024" + "#, + ) + .file("pattern2/src/main.rs", "fn main(){}") + .file( + "pattern2/Cargo.toml", + r#" + [package] + name = "pattern2" + version = "0.1.0" + edition = "2024" + "#, + ) + .file("another/src/main.rs", "fn main(){}") + .file( + "another/Cargo.toml", + r#" + [package] + name = "another" + version = "0.1.0" + edition = "2024" + "#, + ); + + let p = p.build(); + p.cargo("run --bin") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] "--bin" takes one argument. +Available binaries: + crate1 + + +"#]]) + .run(); + + p.cargo("run -p crate1 --bin crate2") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] no bin target named `crate2` in `crate1` package + +[HELP] a target with a similar name exists: `crate1` +[HELP] Available bin in `crate2` package: + crate2 + +"#]]) + .run(); + + p.cargo("check -p crate1 -p pattern1 -p pattern2 --bin crate2") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] no bin target named `crate2` in `crate1`, ... packages + +[HELP] a target with a similar name exists: `crate1` +[HELP] Available bin in `crate2` package: + crate2 + +"#]]) + .run(); + + p.cargo("run --bin crate2") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] no bin target named `crate2` in default-run packages + +[HELP] a target with a similar name exists: `crate1` +[HELP] Available bin in `crate2` package: + crate2 + +"#]]) + .run(); + + p.cargo("check --bin pattern*") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] no bin target matches pattern `pattern*` in default-run packages. +[HELP] Available bin in `pattern1` package: + pattern1 +[HELP] Available bin in `pattern2` package: + pattern2 + +"#]]) + .run(); + + // This another branch that none of similar name exists, and print available targets in the + // default-members. + p.change_file( + "Cargo.toml", + r#" + [workspace] + resolver = "3" + members = ["crate1", "crate2", "another"] + + default-members = ["another"] + "#, + ); + + p.cargo("run --bin crate2") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] no bin target named `crate2` in default-run packages. +[HELP] Available bin in `crate2` package: + crate2 + +"#]]) + .run(); +} + #[cargo_test] fn either_name_or_example() { let p = project() diff --git a/tests/testsuite/workspaces.rs b/tests/testsuite/workspaces.rs index 7b5a8d71e52..707b81a167c 100644 --- a/tests/testsuite/workspaces.rs +++ b/tests/testsuite/workspaces.rs @@ -2716,152 +2716,3 @@ fn nonexistence_package_together_with_workspace() { "#]]) .run(); } - -// See rust-lang/cargo#14544 -#[cargo_test] -fn print_available_targets_within_virtual_workspace() { - let p = project() - .file( - "Cargo.toml", - r#" - [workspace] - resolver = "3" - members = ["crate1", "crate2", "pattern1", "pattern2"] - - default-members = ["crate1"] - "#, - ) - .file("crate1/src/main.rs", "fn main(){}") - .file( - "crate1/Cargo.toml", - r#" - [package] - name = "crate1" - version = "0.1.0" - edition = "2024" - "#, - ) - .file("crate2/src/main.rs", "fn main(){}") - .file( - "crate2/Cargo.toml", - r#" - [package] - name = "crate2" - version = "0.1.0" - edition = "2024" - "#, - ) - .file("pattern1/src/main.rs", "fn main(){}") - .file( - "pattern1/Cargo.toml", - r#" - [package] - name = "pattern1" - version = "0.1.0" - edition = "2024" - "#, - ) - .file("pattern2/src/main.rs", "fn main(){}") - .file( - "pattern2/Cargo.toml", - r#" - [package] - name = "pattern2" - version = "0.1.0" - edition = "2024" - "#, - ) - .file("another/src/main.rs", "fn main(){}") - .file( - "another/Cargo.toml", - r#" - [package] - name = "another" - version = "0.1.0" - edition = "2024" - "#, - ); - - let p = p.build(); - p.cargo("run --bin") - .with_status(101) - .with_stderr_data(str![[r#" -[ERROR] "--bin" takes one argument. -Available binaries: - crate1 - - -"#]]) - .run(); - - p.cargo("run -p crate1 --bin crate2") - .with_status(101) - .with_stderr_data(str![[r#" -[ERROR] no bin target named `crate2` in `crate1` package - -[HELP] a target with a similar name exists: `crate1` -[HELP] Available bin in `crate2` package: - crate2 - -"#]]) - .run(); - - p.cargo("check -p crate1 -p pattern1 -p pattern2 --bin crate2") - .with_status(101) - .with_stderr_data(str![[r#" -[ERROR] no bin target named `crate2` in `crate1`, ... packages - -[HELP] a target with a similar name exists: `crate1` -[HELP] Available bin in `crate2` package: - crate2 - -"#]]) - .run(); - - p.cargo("run --bin crate2") - .with_status(101) - .with_stderr_data(str![[r#" -[ERROR] no bin target named `crate2` in default-run packages - -[HELP] a target with a similar name exists: `crate1` -[HELP] Available bin in `crate2` package: - crate2 - -"#]]) - .run(); - - p.cargo("check --bin pattern*") - .with_status(101) - .with_stderr_data(str![[r#" -[ERROR] no bin target matches pattern `pattern*` in default-run packages. -[HELP] Available bin in `pattern1` package: - pattern1 -[HELP] Available bin in `pattern2` package: - pattern2 - -"#]]) - .run(); - - // This another branch that none of similar name exists, and print available targets in the - // default-members. - p.change_file( - "Cargo.toml", - r#" - [workspace] - resolver = "3" - members = ["crate1", "crate2", "another"] - - default-members = ["another"] - "#, - ); - - p.cargo("run --bin crate2") - .with_status(101) - .with_stderr_data(str![[r#" -[ERROR] no bin target named `crate2` in default-run packages. -[HELP] Available bin in `crate2` package: - crate2 - -"#]]) - .run(); -} From da833c55be55d292bfdc680cd45f895223eaa4ab Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 11 Mar 2025 11:11:44 -0500 Subject: [PATCH 02/12] test(run): Show ambiguous package name errors --- tests/testsuite/run.rs | 76 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/tests/testsuite/run.rs b/tests/testsuite/run.rs index 1755b658502..3f474621877 100644 --- a/tests/testsuite/run.rs +++ b/tests/testsuite/run.rs @@ -779,6 +779,82 @@ Available example targets: [HELP] a target with a similar name exists: `a` +"#]]) + .run(); +} + +#[cargo_test] +fn ambiguous_bin_name() { + let p = project() + .file( + "Cargo.toml", + r#" + [workspace] + resolver = "3" + members = ["crate1", "crate2", "crate3", "crate4"] + "#, + ) + .file("crate1/src/bin/ambiguous.rs", "fn main(){}") + .file( + "crate1/Cargo.toml", + r#" + [package] + name = "crate1" + version = "0.1.0" + edition = "2024" + "#, + ) + .file("crate2/src/bin/ambiguous.rs", "fn main(){}") + .file( + "crate2/Cargo.toml", + r#" + [package] + name = "crate2" + version = "0.1.0" + edition = "2024" + "#, + ) + .file("crate3/src/bin/ambiguous.rs", "fn main(){}") + .file( + "crate3/Cargo.toml", + r#" + [package] + name = "crate3" + version = "0.1.0" + edition = "2024" + "#, + ) + .file("crate4/src/bin/ambiguous.rs", "fn main(){}") + .file( + "crate4/Cargo.toml", + r#" + [package] + name = "crate4" + version = "0.1.0" + edition = "2024" + "#, + ); + let p = p.build(); + + p.cargo("run --bin ambiguous") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] `cargo run` can run at most one executable, but multiple were specified + +"#]]) + .run(); + + p.cargo("run --bin crate1/ambiguous") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] no bin target named `crate1/ambiguous` in default-run packages. +Available bin targets: + ambiguous + ambiguous + ambiguous + ambiguous + + "#]]) .run(); } From 5375c3f60d00bcc72fda9aa5d01ff11cc4b4d9c8 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 11 Mar 2025 11:14:15 -0500 Subject: [PATCH 03/12] refactor(compile): Pull out common variables --- src/cargo/ops/cargo_compile/unit_generator.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/cargo/ops/cargo_compile/unit_generator.rs b/src/cargo/ops/cargo_compile/unit_generator.rs index 2075cd8794c..82b4de6231b 100644 --- a/src/cargo/ops/cargo_compile/unit_generator.rs +++ b/src/cargo/ops/cargo_compile/unit_generator.rs @@ -289,7 +289,7 @@ impl<'a> UnitGenerator<'a, '_> { CargoResult::Ok(()) }; - let unmatched_packages = || match self.spec { + let unmatched_packages = match self.spec { Packages::Default | Packages::OptOut(_) | Packages::All(_) => { "default-run packages".to_owned() } @@ -305,26 +305,21 @@ impl<'a> UnitGenerator<'a, '_> { } }; + let named = if is_glob { "matches pattern" } else { "named" }; + let mut msg = String::new(); if !suggestion.is_empty() { write!( msg, "no {} target {} `{}` in {}{}", - target_desc, - if is_glob { "matches pattern" } else { "named" }, - target_name, - unmatched_packages(), - suggestion, + target_desc, named, target_name, unmatched_packages, suggestion, )?; append_targets_elsewhere(&mut msg, "\n")?; } else { writeln!( msg, "no {} target {} `{}` in {}.", - target_desc, - if is_glob { "matches pattern" } else { "named" }, - target_name, - unmatched_packages() + target_desc, named, target_name, unmatched_packages )?; append_targets_elsewhere(&mut msg, "")?; From 54dd94b49b1f98442844b27468288e1c0701b09a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 11 Mar 2025 11:15:00 -0500 Subject: [PATCH 04/12] refactor(compile): Use string interpolation --- src/cargo/ops/cargo_compile/unit_generator.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/cargo/ops/cargo_compile/unit_generator.rs b/src/cargo/ops/cargo_compile/unit_generator.rs index 82b4de6231b..77cb549114a 100644 --- a/src/cargo/ops/cargo_compile/unit_generator.rs +++ b/src/cargo/ops/cargo_compile/unit_generator.rs @@ -311,15 +311,13 @@ impl<'a> UnitGenerator<'a, '_> { if !suggestion.is_empty() { write!( msg, - "no {} target {} `{}` in {}{}", - target_desc, named, target_name, unmatched_packages, suggestion, + "no {target_desc} target {named} `{target_name}` in {unmatched_packages}{suggestion}", )?; append_targets_elsewhere(&mut msg, "\n")?; } else { writeln!( msg, - "no {} target {} `{}` in {}.", - target_desc, named, target_name, unmatched_packages + "no {target_desc} target {named} `{target_name}` in {unmatched_packages}.", )?; append_targets_elsewhere(&mut msg, "")?; From c2764576ac37e9528c2b4328602ebe414fc34c35 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 11 Mar 2025 11:19:50 -0500 Subject: [PATCH 05/12] fix(compile): Be consistent in not using period in error Whether a period was used was dependent on whether a `help:` block is present. That shouldn't make a difference and the rustc dev guide says not to use periods unless multiple sentences are used. --- src/cargo/ops/cargo_compile/unit_generator.rs | 2 +- tests/testsuite/build.rs | 4 ++-- tests/testsuite/run.rs | 14 +++++++------- tests/testsuite/test.rs | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/cargo/ops/cargo_compile/unit_generator.rs b/src/cargo/ops/cargo_compile/unit_generator.rs index 77cb549114a..b0f33268755 100644 --- a/src/cargo/ops/cargo_compile/unit_generator.rs +++ b/src/cargo/ops/cargo_compile/unit_generator.rs @@ -317,7 +317,7 @@ impl<'a> UnitGenerator<'a, '_> { } else { writeln!( msg, - "no {target_desc} target {named} `{target_name}` in {unmatched_packages}.", + "no {target_desc} target {named} `{target_name}` in {unmatched_packages}", )?; append_targets_elsewhere(&mut msg, "")?; diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index a67824d0b44..e87fc647f47 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -1337,7 +1337,7 @@ fn cargo_compile_with_filename() { p.cargo("build --bin bin.rs") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] no bin target named `bin.rs` in default-run packages. +[ERROR] no bin target named `bin.rs` in default-run packages Available bin targets: a @@ -1358,7 +1358,7 @@ Available bin targets: p.cargo("build --example example.rs") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] no example target named `example.rs` in default-run packages. +[ERROR] no example target named `example.rs` in default-run packages Available example targets: a diff --git a/tests/testsuite/run.rs b/tests/testsuite/run.rs index 3f474621877..a2e63e4acc8 100644 --- a/tests/testsuite/run.rs +++ b/tests/testsuite/run.rs @@ -623,7 +623,7 @@ automatically infer them to be a target, such as in subfolders. For more information on this warning you can consult https://github.com/rust-lang/cargo/issues/5330 -[ERROR] no example target named `a` in default-run packages. +[ERROR] no example target named `a` in default-run packages Available example targets: do_magic @@ -655,7 +655,7 @@ fn run_example_autodiscover_2015_with_autoexamples_disabled() { p.cargo("run --example a") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] no example target named `a` in default-run packages. +[ERROR] no example target named `a` in default-run packages Available example targets: do_magic @@ -743,7 +743,7 @@ fn run_with_filename() { p.cargo("run --bin bin.rs") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] no bin target named `bin.rs` in default-run packages. +[ERROR] no bin target named `bin.rs` in default-run packages Available bin targets: a @@ -764,7 +764,7 @@ Available bin targets: p.cargo("run --example example.rs") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] no example target named `example.rs` in default-run packages. +[ERROR] no example target named `example.rs` in default-run packages Available example targets: a @@ -847,7 +847,7 @@ fn ambiguous_bin_name() { p.cargo("run --bin crate1/ambiguous") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] no bin target named `crate1/ambiguous` in default-run packages. +[ERROR] no bin target named `crate1/ambiguous` in default-run packages Available bin targets: ambiguous ambiguous @@ -975,7 +975,7 @@ Available binaries: p.cargo("check --bin pattern*") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] no bin target matches pattern `pattern*` in default-run packages. +[ERROR] no bin target matches pattern `pattern*` in default-run packages [HELP] Available bin in `pattern1` package: pattern1 [HELP] Available bin in `pattern2` package: @@ -1000,7 +1000,7 @@ Available binaries: p.cargo("run --bin crate2") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] no bin target named `crate2` in default-run packages. +[ERROR] no bin target named `crate2` in default-run packages [HELP] Available bin in `crate2` package: crate2 diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs index 7f69efb4d9c..5e247f231fe 100644 --- a/tests/testsuite/test.rs +++ b/tests/testsuite/test.rs @@ -2447,7 +2447,7 @@ fn bad_example() { p.cargo("run --example foo") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] no example target named `foo` in default-run packages. +[ERROR] no example target named `foo` in default-run packages "#]]) @@ -2455,7 +2455,7 @@ fn bad_example() { p.cargo("run --bin foo") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] no bin target named `foo` in default-run packages. +[ERROR] no bin target named `foo` in default-run packages "#]]) From fde91dde66e5a2db79bb0437752c6294c1221d14 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 11 Mar 2025 11:28:38 -0500 Subject: [PATCH 06/12] fix(compile): Remove trailing newlines on errors --- src/cargo/ops/cargo_compile/unit_generator.rs | 14 +++++++------- tests/testsuite/build.rs | 2 -- tests/testsuite/run.rs | 5 ----- tests/testsuite/test.rs | 2 -- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/cargo/ops/cargo_compile/unit_generator.rs b/src/cargo/ops/cargo_compile/unit_generator.rs index b0f33268755..5de98e096af 100644 --- a/src/cargo/ops/cargo_compile/unit_generator.rs +++ b/src/cargo/ops/cargo_compile/unit_generator.rs @@ -271,7 +271,7 @@ impl<'a> UnitGenerator<'a, '_> { let suggestion = closest_msg(target_name, targets.iter(), |t| t.name(), "target"); let targets_elsewhere = self.get_targets_from_other_packages(filter)?; let need_append_targets_elsewhere = !targets_elsewhere.is_empty(); - let append_targets_elsewhere = |msg: &mut String, prefix: &str| { + let append_targets_elsewhere = |msg: &mut String| { let mut available_msg = Vec::new(); for (package, targets) in targets_elsewhere { if !targets.is_empty() { @@ -284,7 +284,7 @@ impl<'a> UnitGenerator<'a, '_> { } } if !available_msg.is_empty() { - write!(msg, "{prefix}{}", available_msg.join("\n"))?; + write!(msg, "\n{}", available_msg.join("\n"))?; } CargoResult::Ok(()) }; @@ -313,18 +313,18 @@ impl<'a> UnitGenerator<'a, '_> { msg, "no {target_desc} target {named} `{target_name}` in {unmatched_packages}{suggestion}", )?; - append_targets_elsewhere(&mut msg, "\n")?; + append_targets_elsewhere(&mut msg)?; } else { - writeln!( + write!( msg, "no {target_desc} target {named} `{target_name}` in {unmatched_packages}", )?; - append_targets_elsewhere(&mut msg, "")?; + append_targets_elsewhere(&mut msg)?; if !targets.is_empty() && !need_append_targets_elsewhere { - writeln!(msg, "Available {} targets:", target_desc)?; + write!(msg, "\nAvailable {} targets:", target_desc)?; for target in targets { - writeln!(msg, " {}", target.name())?; + write!(msg, "\n {}", target.name())?; } } } diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index e87fc647f47..2feda6bdf8d 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -1341,7 +1341,6 @@ fn cargo_compile_with_filename() { Available bin targets: a - "#]]) .run(); @@ -1362,7 +1361,6 @@ Available bin targets: Available example targets: a - "#]]) .run(); diff --git a/tests/testsuite/run.rs b/tests/testsuite/run.rs index a2e63e4acc8..8baebe5ec6a 100644 --- a/tests/testsuite/run.rs +++ b/tests/testsuite/run.rs @@ -627,7 +627,6 @@ https://github.com/rust-lang/cargo/issues/5330 Available example targets: do_magic - "#]]) .run(); } @@ -659,7 +658,6 @@ fn run_example_autodiscover_2015_with_autoexamples_disabled() { Available example targets: do_magic - "#]]) .run(); } @@ -747,7 +745,6 @@ fn run_with_filename() { Available bin targets: a - "#]]) .run(); @@ -768,7 +765,6 @@ Available bin targets: Available example targets: a - "#]]) .run(); @@ -854,7 +850,6 @@ Available bin targets: ambiguous ambiguous - "#]]) .run(); } diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs index 5e247f231fe..6d9941f0149 100644 --- a/tests/testsuite/test.rs +++ b/tests/testsuite/test.rs @@ -2449,7 +2449,6 @@ fn bad_example() { .with_stderr_data(str![[r#" [ERROR] no example target named `foo` in default-run packages - "#]]) .run(); p.cargo("run --bin foo") @@ -2457,7 +2456,6 @@ fn bad_example() { .with_stderr_data(str![[r#" [ERROR] no bin target named `foo` in default-run packages - "#]]) .run(); } From 05775e5169262084365c626a42bb3808a6d32d9a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 11 Mar 2025 11:40:40 -0500 Subject: [PATCH 07/12] refactor(compile): Remove layer of abstraction --- src/cargo/ops/cargo_compile/unit_generator.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cargo/ops/cargo_compile/unit_generator.rs b/src/cargo/ops/cargo_compile/unit_generator.rs index 5de98e096af..66f14af8057 100644 --- a/src/cargo/ops/cargo_compile/unit_generator.rs +++ b/src/cargo/ops/cargo_compile/unit_generator.rs @@ -270,10 +270,9 @@ impl<'a> UnitGenerator<'a, '_> { .collect::>(); let suggestion = closest_msg(target_name, targets.iter(), |t| t.name(), "target"); let targets_elsewhere = self.get_targets_from_other_packages(filter)?; - let need_append_targets_elsewhere = !targets_elsewhere.is_empty(); let append_targets_elsewhere = |msg: &mut String| { let mut available_msg = Vec::new(); - for (package, targets) in targets_elsewhere { + for (package, targets) in &targets_elsewhere { if !targets.is_empty() { available_msg.push(format!( "help: Available {target_desc} in `{package}` package:" @@ -321,7 +320,7 @@ impl<'a> UnitGenerator<'a, '_> { )?; append_targets_elsewhere(&mut msg)?; - if !targets.is_empty() && !need_append_targets_elsewhere { + if !targets.is_empty() && targets_elsewhere.is_empty() { write!(msg, "\nAvailable {} targets:", target_desc)?; for target in targets { write!(msg, "\n {}", target.name())?; From 86dcd23f8e31541a26a7b024f34f40d348ee79fa Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 11 Mar 2025 11:48:14 -0500 Subject: [PATCH 08/12] refactor(compile): De-duplicate error generation --- src/cargo/ops/cargo_compile/unit_generator.rs | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/cargo/ops/cargo_compile/unit_generator.rs b/src/cargo/ops/cargo_compile/unit_generator.rs index 66f14af8057..17470b90346 100644 --- a/src/cargo/ops/cargo_compile/unit_generator.rs +++ b/src/cargo/ops/cargo_compile/unit_generator.rs @@ -307,24 +307,16 @@ impl<'a> UnitGenerator<'a, '_> { let named = if is_glob { "matches pattern" } else { "named" }; let mut msg = String::new(); - if !suggestion.is_empty() { - write!( - msg, - "no {target_desc} target {named} `{target_name}` in {unmatched_packages}{suggestion}", - )?; + write!( + msg, + "no {target_desc} target {named} `{target_name}` in {unmatched_packages}{suggestion}", + )?; + if !targets_elsewhere.is_empty() { append_targets_elsewhere(&mut msg)?; - } else { - write!( - msg, - "no {target_desc} target {named} `{target_name}` in {unmatched_packages}", - )?; - - append_targets_elsewhere(&mut msg)?; - if !targets.is_empty() && targets_elsewhere.is_empty() { - write!(msg, "\nAvailable {} targets:", target_desc)?; - for target in targets { - write!(msg, "\n {}", target.name())?; - } + } else if suggestion.is_empty() && !targets.is_empty() { + write!(msg, "\nAvailable {} targets:", target_desc)?; + for target in targets { + write!(msg, "\n {}", target.name())?; } } anyhow::bail!(msg); From 7bf7b2f6845fa16ad7ab3451829ea78de25a23d4 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 11 Mar 2025 11:51:38 -0500 Subject: [PATCH 09/12] fix(compile): Match rustc style guide for help message casing --- src/cargo/ops/cargo_compile/unit_generator.rs | 4 ++-- tests/testsuite/build.rs | 4 ++-- tests/testsuite/run.rs | 22 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/cargo/ops/cargo_compile/unit_generator.rs b/src/cargo/ops/cargo_compile/unit_generator.rs index 17470b90346..2719ce72945 100644 --- a/src/cargo/ops/cargo_compile/unit_generator.rs +++ b/src/cargo/ops/cargo_compile/unit_generator.rs @@ -275,7 +275,7 @@ impl<'a> UnitGenerator<'a, '_> { for (package, targets) in &targets_elsewhere { if !targets.is_empty() { available_msg.push(format!( - "help: Available {target_desc} in `{package}` package:" + "help: available {target_desc} in `{package}` package:" )); for target in targets { available_msg.push(format!(" {target}")); @@ -314,7 +314,7 @@ impl<'a> UnitGenerator<'a, '_> { if !targets_elsewhere.is_empty() { append_targets_elsewhere(&mut msg)?; } else if suggestion.is_empty() && !targets.is_empty() { - write!(msg, "\nAvailable {} targets:", target_desc)?; + write!(msg, "\navailable {} targets:", target_desc)?; for target in targets { write!(msg, "\n {}", target.name())?; } diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index 2feda6bdf8d..a4a2b57bab5 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -1338,7 +1338,7 @@ fn cargo_compile_with_filename() { .with_status(101) .with_stderr_data(str![[r#" [ERROR] no bin target named `bin.rs` in default-run packages -Available bin targets: +available bin targets: a "#]]) @@ -1358,7 +1358,7 @@ Available bin targets: .with_status(101) .with_stderr_data(str![[r#" [ERROR] no example target named `example.rs` in default-run packages -Available example targets: +available example targets: a "#]]) diff --git a/tests/testsuite/run.rs b/tests/testsuite/run.rs index 8baebe5ec6a..b2c223520df 100644 --- a/tests/testsuite/run.rs +++ b/tests/testsuite/run.rs @@ -624,7 +624,7 @@ automatically infer them to be a target, such as in subfolders. For more information on this warning you can consult https://github.com/rust-lang/cargo/issues/5330 [ERROR] no example target named `a` in default-run packages -Available example targets: +available example targets: do_magic "#]]) @@ -655,7 +655,7 @@ fn run_example_autodiscover_2015_with_autoexamples_disabled() { .with_status(101) .with_stderr_data(str![[r#" [ERROR] no example target named `a` in default-run packages -Available example targets: +available example targets: do_magic "#]]) @@ -742,7 +742,7 @@ fn run_with_filename() { .with_status(101) .with_stderr_data(str![[r#" [ERROR] no bin target named `bin.rs` in default-run packages -Available bin targets: +available bin targets: a "#]]) @@ -762,7 +762,7 @@ Available bin targets: .with_status(101) .with_stderr_data(str![[r#" [ERROR] no example target named `example.rs` in default-run packages -Available example targets: +available example targets: a "#]]) @@ -844,7 +844,7 @@ fn ambiguous_bin_name() { .with_status(101) .with_stderr_data(str![[r#" [ERROR] no bin target named `crate1/ambiguous` in default-run packages -Available bin targets: +available bin targets: ambiguous ambiguous ambiguous @@ -937,7 +937,7 @@ Available binaries: [ERROR] no bin target named `crate2` in `crate1` package [HELP] a target with a similar name exists: `crate1` -[HELP] Available bin in `crate2` package: +[HELP] available bin in `crate2` package: crate2 "#]]) @@ -949,7 +949,7 @@ Available binaries: [ERROR] no bin target named `crate2` in `crate1`, ... packages [HELP] a target with a similar name exists: `crate1` -[HELP] Available bin in `crate2` package: +[HELP] available bin in `crate2` package: crate2 "#]]) @@ -961,7 +961,7 @@ Available binaries: [ERROR] no bin target named `crate2` in default-run packages [HELP] a target with a similar name exists: `crate1` -[HELP] Available bin in `crate2` package: +[HELP] available bin in `crate2` package: crate2 "#]]) @@ -971,9 +971,9 @@ Available binaries: .with_status(101) .with_stderr_data(str![[r#" [ERROR] no bin target matches pattern `pattern*` in default-run packages -[HELP] Available bin in `pattern1` package: +[HELP] available bin in `pattern1` package: pattern1 -[HELP] Available bin in `pattern2` package: +[HELP] available bin in `pattern2` package: pattern2 "#]]) @@ -996,7 +996,7 @@ Available binaries: .with_status(101) .with_stderr_data(str![[r#" [ERROR] no bin target named `crate2` in default-run packages -[HELP] Available bin in `crate2` package: +[HELP] available bin in `crate2` package: crate2 "#]]) From b20edd42261f9349790e961c7b264e5aa89dcdbd Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 11 Mar 2025 11:54:00 -0500 Subject: [PATCH 10/12] fix(compile): Consistently use help prefix in errors --- src/cargo/ops/cargo_compile/unit_generator.rs | 2 +- tests/testsuite/build.rs | 4 ++-- tests/testsuite/run.rs | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cargo/ops/cargo_compile/unit_generator.rs b/src/cargo/ops/cargo_compile/unit_generator.rs index 2719ce72945..df6154290fe 100644 --- a/src/cargo/ops/cargo_compile/unit_generator.rs +++ b/src/cargo/ops/cargo_compile/unit_generator.rs @@ -314,7 +314,7 @@ impl<'a> UnitGenerator<'a, '_> { if !targets_elsewhere.is_empty() { append_targets_elsewhere(&mut msg)?; } else if suggestion.is_empty() && !targets.is_empty() { - write!(msg, "\navailable {} targets:", target_desc)?; + write!(msg, "\nhelp: available {} targets:", target_desc)?; for target in targets { write!(msg, "\n {}", target.name())?; } diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index a4a2b57bab5..2bdf2b26d18 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -1338,7 +1338,7 @@ fn cargo_compile_with_filename() { .with_status(101) .with_stderr_data(str![[r#" [ERROR] no bin target named `bin.rs` in default-run packages -available bin targets: +[HELP] available bin targets: a "#]]) @@ -1358,7 +1358,7 @@ available bin targets: .with_status(101) .with_stderr_data(str![[r#" [ERROR] no example target named `example.rs` in default-run packages -available example targets: +[HELP] available example targets: a "#]]) diff --git a/tests/testsuite/run.rs b/tests/testsuite/run.rs index b2c223520df..e9c7fb68522 100644 --- a/tests/testsuite/run.rs +++ b/tests/testsuite/run.rs @@ -624,7 +624,7 @@ automatically infer them to be a target, such as in subfolders. For more information on this warning you can consult https://github.com/rust-lang/cargo/issues/5330 [ERROR] no example target named `a` in default-run packages -available example targets: +[HELP] available example targets: do_magic "#]]) @@ -655,7 +655,7 @@ fn run_example_autodiscover_2015_with_autoexamples_disabled() { .with_status(101) .with_stderr_data(str![[r#" [ERROR] no example target named `a` in default-run packages -available example targets: +[HELP] available example targets: do_magic "#]]) @@ -742,7 +742,7 @@ fn run_with_filename() { .with_status(101) .with_stderr_data(str![[r#" [ERROR] no bin target named `bin.rs` in default-run packages -available bin targets: +[HELP] available bin targets: a "#]]) @@ -762,7 +762,7 @@ available bin targets: .with_status(101) .with_stderr_data(str![[r#" [ERROR] no example target named `example.rs` in default-run packages -available example targets: +[HELP] available example targets: a "#]]) @@ -844,7 +844,7 @@ fn ambiguous_bin_name() { .with_status(101) .with_stderr_data(str![[r#" [ERROR] no bin target named `crate1/ambiguous` in default-run packages -available bin targets: +[HELP] available bin targets: ambiguous ambiguous ambiguous From b06e29c72a2a027be664822b5886e2876c3a5162 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 11 Mar 2025 13:02:55 -0500 Subject: [PATCH 11/12] fix(compile): Specify packages ambiguous targets come from --- src/cargo/ops/cargo_compile/unit_generator.rs | 35 ++++++++++++------- tests/testsuite/run.rs | 8 ++--- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/cargo/ops/cargo_compile/unit_generator.rs b/src/cargo/ops/cargo_compile/unit_generator.rs index df6154290fe..588581457b2 100644 --- a/src/cargo/ops/cargo_compile/unit_generator.rs +++ b/src/cargo/ops/cargo_compile/unit_generator.rs @@ -259,16 +259,20 @@ impl<'a> UnitGenerator<'a, '_> { }; let proposals = self.filter_targets(filter, true, mode); if proposals.is_empty() { - let targets = self - .packages - .iter() - .flat_map(|pkg| { - pkg.targets() - .iter() - .filter(|target| is_expected_kind(target)) - }) - .collect::>(); - let suggestion = closest_msg(target_name, targets.iter(), |t| t.name(), "target"); + let mut targets = std::collections::BTreeMap::new(); + for (pkg, target) in self.packages.iter().flat_map(|pkg| { + pkg.targets() + .iter() + .filter(|target| is_expected_kind(target)) + .map(move |t| (pkg, t)) + }) { + targets + .entry(target.name()) + .or_insert_with(Vec::new) + .push((pkg, target)); + } + + let suggestion = closest_msg(target_name, targets.keys(), |t| t, "target"); let targets_elsewhere = self.get_targets_from_other_packages(filter)?; let append_targets_elsewhere = |msg: &mut String| { let mut available_msg = Vec::new(); @@ -315,8 +319,15 @@ impl<'a> UnitGenerator<'a, '_> { append_targets_elsewhere(&mut msg)?; } else if suggestion.is_empty() && !targets.is_empty() { write!(msg, "\nhelp: available {} targets:", target_desc)?; - for target in targets { - write!(msg, "\n {}", target.name())?; + for (target_name, pkgs) in targets { + if pkgs.len() == 1 { + write!(msg, "\n {target_name}")?; + } else { + for (pkg, _) in pkgs { + let pkg_name = pkg.name(); + write!(msg, "\n {target_name} in package {pkg_name}")?; + } + } } } anyhow::bail!(msg); diff --git a/tests/testsuite/run.rs b/tests/testsuite/run.rs index e9c7fb68522..5978c49af49 100644 --- a/tests/testsuite/run.rs +++ b/tests/testsuite/run.rs @@ -845,10 +845,10 @@ fn ambiguous_bin_name() { .with_stderr_data(str![[r#" [ERROR] no bin target named `crate1/ambiguous` in default-run packages [HELP] available bin targets: - ambiguous - ambiguous - ambiguous - ambiguous + ambiguous in package crate1 + ambiguous in package crate2 + ambiguous in package crate3 + ambiguous in package crate4 "#]]) .run(); From d29a7cb5d7cbaaeba2f647a534a9d44d7382cd5e Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 11 Mar 2025 13:15:54 -0500 Subject: [PATCH 12/12] fix(run): Say what the multiple executables are --- src/cargo/ops/cargo_run.rs | 17 ++++++++++++++--- tests/testsuite/run.rs | 8 ++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/cargo/ops/cargo_run.rs b/src/cargo/ops/cargo_run.rs index 46be0291058..25d13e923a3 100644 --- a/src/cargo/ops/cargo_run.rs +++ b/src/cargo/ops/cargo_run.rs @@ -1,4 +1,5 @@ use std::ffi::OsString; +use std::fmt::Write as _; use std::iter; use std::path::Path; @@ -69,10 +70,20 @@ pub fn run( names.join(", ") ) } else { - anyhow::bail!( - "`cargo run` can run at most one executable, but \ + let mut message = "`cargo run` can run at most one executable, but \ multiple were specified" - ) + .to_owned(); + write!(&mut message, "\nhelp: available targets:")?; + for (pkg, bin) in &bins { + write!( + &mut message, + "\n {} `{}` in package `{}`", + bin.kind().description(), + bin.name(), + pkg.name() + )?; + } + anyhow::bail!(message) } } diff --git a/tests/testsuite/run.rs b/tests/testsuite/run.rs index 5978c49af49..271b8e7acd1 100644 --- a/tests/testsuite/run.rs +++ b/tests/testsuite/run.rs @@ -836,6 +836,11 @@ fn ambiguous_bin_name() { .with_status(101) .with_stderr_data(str![[r#" [ERROR] `cargo run` can run at most one executable, but multiple were specified +[HELP] available targets: + bin `ambiguous` in package `crate1` + bin `ambiguous` in package `crate2` + bin `ambiguous` in package `crate3` + bin `ambiguous` in package `crate4` "#]]) .run(); @@ -1014,6 +1019,9 @@ fn either_name_or_example() { .with_status(101) .with_stderr_data(str![[r#" [ERROR] `cargo run` can run at most one executable, but multiple were specified +[HELP] available targets: + bin `a` in package `foo` + example `b` in package `foo` "#]]) .run();