Skip to content

Commit 5ad084c

Browse files
author
Yihai Lin
committed
feat(workspace): Search other crates if the default-members doesn't have the Target
1 parent 3824d83 commit 5ad084c

File tree

2 files changed

+68
-10
lines changed

2 files changed

+68
-10
lines changed

src/cargo/ops/cargo_compile/unit_generator.rs

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::util::{closest_msg, CargoResult};
1717

1818
use super::compile_filter::{CompileFilter, FilterRule, LibRule};
1919
use super::packages::build_glob;
20+
use super::Packages;
2021

2122
/// A proposed target.
2223
///
@@ -267,14 +268,37 @@ impl<'a> UnitGenerator<'a, '_> {
267268
})
268269
.collect::<Vec<_>>();
269270
let suggestion = closest_msg(target_name, targets.iter(), |t| t.name(), "target");
271+
let targets_elsewhere = self.get_targets_from_other_packages(filter)?;
272+
let need_append_targets_elsewhere = !targets_elsewhere.is_empty();
273+
let append_targets_elsewhere = |msg: &mut String, prefix: &str| {
274+
let mut available_msg = Vec::new();
275+
for (package, targets) in targets_elsewhere {
276+
if !targets.is_empty() {
277+
available_msg.push(format!(
278+
"help: Available {target_desc} in `{package}` package:"
279+
));
280+
for target in targets {
281+
available_msg.push(format!(" {target}"));
282+
}
283+
}
284+
}
285+
if !available_msg.is_empty() {
286+
write!(msg, "{prefix}{}", available_msg.join("\n"))?;
287+
}
288+
CargoResult::Ok(())
289+
};
270290
if !suggestion.is_empty() {
271-
anyhow::bail!(
291+
let mut msg = String::new();
292+
write!(
293+
msg,
272294
"no {} target {} `{}`{}",
273295
target_desc,
274296
if is_glob { "matches pattern" } else { "named" },
275297
target_name,
276-
suggestion
277-
);
298+
suggestion,
299+
)?;
300+
append_targets_elsewhere(&mut msg, "\n")?;
301+
anyhow::bail!(msg);
278302
} else {
279303
let mut msg = String::new();
280304
writeln!(
@@ -284,7 +308,9 @@ impl<'a> UnitGenerator<'a, '_> {
284308
if is_glob { "matches pattern" } else { "named" },
285309
target_name,
286310
)?;
287-
if !targets.is_empty() {
311+
312+
append_targets_elsewhere(&mut msg, "")?;
313+
if !targets.is_empty() && !need_append_targets_elsewhere {
288314
writeln!(msg, "Available {} targets:", target_desc)?;
289315
for target in targets {
290316
writeln!(msg, " {}", target.name())?;
@@ -296,6 +322,32 @@ impl<'a> UnitGenerator<'a, '_> {
296322
Ok(proposals)
297323
}
298324

325+
fn get_targets_from_other_packages(
326+
&self,
327+
filter_fn: impl Fn(&Target) -> bool,
328+
) -> CargoResult<Vec<(&str, Vec<&str>)>> {
329+
let packages = Packages::All(Vec::new()).get_packages(self.ws)?;
330+
let targets = packages
331+
.into_iter()
332+
.filter_map(|pkg| {
333+
let mut targets: Vec<_> = pkg
334+
.manifest()
335+
.targets()
336+
.iter()
337+
.filter_map(|target| filter_fn(target).then(|| target.name()))
338+
.collect();
339+
if targets.is_empty() {
340+
None
341+
} else {
342+
targets.sort();
343+
Some((pkg.name().as_str(), targets))
344+
}
345+
})
346+
.collect();
347+
348+
Ok(targets)
349+
}
350+
299351
/// Returns a list of proposed targets based on command-line target selection flags.
300352
fn list_rule_targets(
301353
&self,

tests/testsuite/workspaces.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2800,6 +2800,8 @@ Available binaries:
28002800
[ERROR] no bin target named `crate2`
28012801
28022802
[HELP] a target with a similar name exists: `crate1`
2803+
[HELP] Available bin in `crate2` package:
2804+
crate2
28032805
28042806
"#]])
28052807
.run();
@@ -2810,6 +2812,8 @@ Available binaries:
28102812
[ERROR] no bin target named `crate2`
28112813
28122814
[HELP] a target with a similar name exists: `crate1`
2815+
[HELP] Available bin in `crate2` package:
2816+
crate2
28132817
28142818
"#]])
28152819
.run();
@@ -2820,6 +2824,8 @@ Available binaries:
28202824
[ERROR] no bin target named `crate2`
28212825
28222826
[HELP] a target with a similar name exists: `crate1`
2827+
[HELP] Available bin in `crate2` package:
2828+
crate2
28232829
28242830
"#]])
28252831
.run();
@@ -2828,9 +2834,10 @@ Available binaries:
28282834
.with_status(101)
28292835
.with_stderr_data(str![[r#"
28302836
[ERROR] no bin target matches pattern `pattern*`.
2831-
Available bin targets:
2832-
crate1
2833-
2837+
[HELP] Available bin in `pattern1` package:
2838+
pattern1
2839+
[HELP] Available bin in `pattern2` package:
2840+
pattern2
28342841
28352842
"#]])
28362843
.run();
@@ -2852,9 +2859,8 @@ Available bin targets:
28522859
.with_status(101)
28532860
.with_stderr_data(str![[r#"
28542861
[ERROR] no bin target named `crate2`.
2855-
Available bin targets:
2856-
another
2857-
2862+
[HELP] Available bin in `crate2` package:
2863+
crate2
28582864
28592865
"#]])
28602866
.run();

0 commit comments

Comments
 (0)