diff --git a/src/cargo/ops/cargo_add/mod.rs b/src/cargo/ops/cargo_add/mod.rs index 1efc7bb5e01..a1614f00ec4 100644 --- a/src/cargo/ops/cargo_add/mod.rs +++ b/src/cargo/ops/cargo_add/mod.rs @@ -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, src: &dyn std::fmt::Display) -> CargoResult { +fn infer_package_for_git_source( + mut packages: Vec, + src: &dyn std::fmt::Display, +) -> CargoResult { 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, 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} `", + 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) diff --git a/tests/testsuite/cargo_add/git_inferred_name_multiple/mod.rs b/tests/testsuite/cargo_add/git_inferred_name_multiple/mod.rs index 56aa7b7bece..f5c3f4d036a 100644 --- a/tests/testsuite/cargo_add/git_inferred_name_multiple/mod.rs +++ b/tests/testsuite/cargo_add/git_inferred_name_multiple/mod.rs @@ -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(); diff --git a/tests/testsuite/cargo_add/git_inferred_name_multiple/stderr.log b/tests/testsuite/cargo_add/git_inferred_name_multiple/stderr.log index 829cc67b27a..2e045db6f2c 100644 --- a/tests/testsuite/cargo_add/git_inferred_name_multiple/stderr.log +++ b/tests/testsuite/cargo_add/git_inferred_name_multiple/stderr.log @@ -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 `