Auto merge of #11186 - hi-rustin:rustin-patch-add-suggestion, r=epage

Add suggestions when `cargo add` multiple packages

### What does this PR try to resolve?

close https://github.com/rust-lang/cargo/issues/11173
Add suggestions when `cargo add` multiple packages. See https://github.com/rust-lang/cargo/issues/11173#issuecomment-1265692022

### How should we test and review this PR?

- [x] unit test
This commit is contained in:
bors 2022-11-22 14:10:58 +00:00
commit 995f5efcc2
3 changed files with 65 additions and 9 deletions

View File

@ -289,7 +289,7 @@ fn resolve_dependency(
} else {
let mut source = crate::sources::GitSource::new(src.source_id()?, config)?;
let packages = source.read_packages()?;
let package = infer_package(packages, &src)?;
let package = infer_package_for_git_source(packages, &src)?;
Dependency::from(package.summary())
};
selected
@ -313,8 +313,10 @@ fn resolve_dependency(
selected
} else {
let source = crate::sources::PathSource::new(&path, src.source_id()?, config);
let packages = source.read_packages()?;
let package = infer_package(packages, &src)?;
let package = source
.read_packages()?
.pop()
.expect("read_packages errors when no packages");
Dependency::from(package.summary())
};
selected
@ -599,11 +601,15 @@ fn select_package(
}
}
fn infer_package(mut packages: Vec<Package>, src: &dyn std::fmt::Display) -> CargoResult<Package> {
fn infer_package_for_git_source(
mut packages: Vec<Package>,
src: &dyn std::fmt::Display,
) -> CargoResult<Package> {
let package = match packages.len() {
0 => {
anyhow::bail!("no packages found at `{src}`");
}
0 => unreachable!(
"this function should only be called with packages from `GitSource::read_packages` \
and that call should error for us when there are no packages"
),
1 => packages.pop().expect("match ensured element is present"),
_ => {
let mut names: Vec<_> = packages
@ -611,7 +617,19 @@ fn infer_package(mut packages: Vec<Package>, src: &dyn std::fmt::Display) -> Car
.map(|p| p.name().as_str().to_owned())
.collect();
names.sort_unstable();
anyhow::bail!("multiple packages found at `{src}`: {}", names.join(", "));
anyhow::bail!(
"multiple packages found at `{src}`:\n {}\nTo disambiguate, run `cargo add --git {src} <package>`",
names
.iter()
.map(|s| s.to_string())
.coalesce(|x, y| if x.len() + y.len() < 78 {
Ok(format!("{x}, {y}"))
} else {
Err((x, y))
})
.into_iter()
.format("\n "),
);
}
};
Ok(package)

View File

@ -23,6 +23,41 @@ fn git_inferred_name_multiple() {
&cargo_test_support::basic_manifest("my-package2", "0.3.0+my-package2"),
)
.file("p2/src/lib.rs", "")
.file(
"p3/Cargo.toml",
&cargo_test_support::basic_manifest("my-package3", "0.3.0+my-package2"),
)
.file("p3/src/lib.rs", "")
.file(
"p4/Cargo.toml",
&cargo_test_support::basic_manifest("my-package4", "0.3.0+my-package2"),
)
.file("p4/src/lib.rs", "")
.file(
"p5/Cargo.toml",
&cargo_test_support::basic_manifest("my-package5", "0.3.0+my-package2"),
)
.file("p5/src/lib.rs", "")
.file(
"p6/Cargo.toml",
&cargo_test_support::basic_manifest("my-package6", "0.3.0+my-package2"),
)
.file("p6/src/lib.rs", "")
.file(
"p7/Cargo.toml",
&cargo_test_support::basic_manifest("my-package7", "0.3.0+my-package2"),
)
.file("p7/src/lib.rs", "")
.file(
"p8/Cargo.toml",
&cargo_test_support::basic_manifest("my-package8", "0.3.0+my-package2"),
)
.file("p8/src/lib.rs", "")
.file(
"p9/Cargo.toml",
&cargo_test_support::basic_manifest("my-package9", "0.3.0+my-package2"),
)
.file("p9/src/lib.rs", "")
});
let git_url = git_dep.url().to_string();

View File

@ -1,2 +1,5 @@
Updating git repository `[ROOTURL]/git-package`
error: multiple packages found at `[ROOTURL]/git-package`: my-package1, my-package2
error: multiple packages found at `[ROOTURL]/git-package`:
my-package1, my-package2, my-package3, my-package4, my-package5, my-package6
my-package7, my-package8, my-package9
To disambiguate, run `cargo add --git [ROOTURL]/git-package <package>`