From 1f9446033809b62645f45c628761db57ef7fee9f Mon Sep 17 00:00:00 2001 From: Jonas Dohse Date: Wed, 1 May 2024 15:05:22 +0200 Subject: [PATCH] Fix #10680, Fix #13702 --- src/cargo/ops/cargo_add/mod.rs | 41 ++++++++++++++++++- .../out/primary/Cargo.toml | 2 +- .../stderr.term.svg | 6 +-- .../cargo_add/features_fuzzy/out/Cargo.toml | 2 +- .../cargo_add/features_fuzzy/stderr.term.svg | 8 ++-- 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/cargo/ops/cargo_add/mod.rs b/src/cargo/ops/cargo_add/mod.rs index c6f71847df38..e7da702dbc6d 100644 --- a/src/cargo/ops/cargo_add/mod.rs +++ b/src/cargo/ops/cargo_add/mod.rs @@ -361,7 +361,9 @@ fn resolve_dependency( }; selected_dep = populate_dependency(selected_dep, arg); - let old_dep = get_existing_dependency(manifest, selected_dep.toml_key(), section)?; + let lookup = |dep_key: &_| get_existing_dependency(manifest, dep_key, section); + let old_dep = fuzzy_lookup(&mut selected_dep, lookup, gctx)?; + let mut dependency = if let Some(mut old_dep) = old_dep.clone() { if old_dep.name != selected_dep.name { // Assuming most existing keys are not relevant when the package changes @@ -383,7 +385,8 @@ fn resolve_dependency( if dependency.source().is_none() { // Checking for a workspace dependency happens first since a member could be specified // in the workspace dependencies table as a dependency - if let Some(_dep) = find_workspace_dep(dependency.toml_key(), ws.root_manifest()).ok() { + let lookup = |toml_key: &_| Ok(find_workspace_dep(toml_key, ws.root_manifest()).ok()); + if let Some(_dep) = fuzzy_lookup(&mut dependency, lookup, gctx)? { dependency = dependency.set_source(WorkspaceSource::new()); } else if let Some(package) = ws.members().find(|p| p.name().as_str() == dependency.name) { // Only special-case workspaces when the user doesn't provide any extra @@ -449,6 +452,40 @@ fn resolve_dependency( Ok(dependency) } +fn fuzzy_lookup( + dependency: &mut Dependency, + lookup: impl Fn(&str) -> CargoResult>, + gctx: &GlobalContext, +) -> CargoResult> { + if let Some(rename) = dependency.rename() { + return lookup(rename); + } + + for name_permutation in [ + dependency.name.clone(), + dependency.name.replace('-', "_"), + dependency.name.replace('_', "-"), + ] { + let Some(dep) = lookup(&name_permutation)? else { + continue; + }; + + if dependency.name != name_permutation { + if !matches!(dep.source, Some(Source::Registry(_))) { + continue; + } + gctx.shell().warn(format!( + "translating `{}` to `{}`", + dependency.name, &name_permutation, + ))?; + dependency.name = name_permutation; + } + return Ok(Some(dep)); + } + + Ok(None) +} + /// When { workspace = true } you cannot define other keys that configure /// the source of the dependency such as `version`, `registry`, `registry-index`, /// `path`, `git`, `branch`, `tag`, `rev`, or `package`. You can also not define diff --git a/tests/testsuite/cargo_add/detect_workspace_inherit_fuzzy/out/primary/Cargo.toml b/tests/testsuite/cargo_add/detect_workspace_inherit_fuzzy/out/primary/Cargo.toml index 1ae5f7b63618..22737f576822 100644 --- a/tests/testsuite/cargo_add/detect_workspace_inherit_fuzzy/out/primary/Cargo.toml +++ b/tests/testsuite/cargo_add/detect_workspace_inherit_fuzzy/out/primary/Cargo.toml @@ -4,4 +4,4 @@ version = "0.0.0" edition = "2015" [dependencies] -fuzzy_dependency = "1.0.0" +fuzzy_dependency.workspace = true diff --git a/tests/testsuite/cargo_add/detect_workspace_inherit_fuzzy/stderr.term.svg b/tests/testsuite/cargo_add/detect_workspace_inherit_fuzzy/stderr.term.svg index e5e452f3b051..b9cd1a406608 100644 --- a/tests/testsuite/cargo_add/detect_workspace_inherit_fuzzy/stderr.term.svg +++ b/tests/testsuite/cargo_add/detect_workspace_inherit_fuzzy/stderr.term.svg @@ -19,11 +19,11 @@ - Updating `dummy-registry` index + warning: translating `fuzzy-dependency` to `fuzzy_dependency` - warning: translating `fuzzy-dependency` to `fuzzy_dependency` + Updating `dummy-registry` index - Adding fuzzy_dependency v1.0.0 to dependencies + Adding fuzzy_dependency (workspace) to dependencies Locking 2 packages to latest compatible versions diff --git a/tests/testsuite/cargo_add/features_fuzzy/out/Cargo.toml b/tests/testsuite/cargo_add/features_fuzzy/out/Cargo.toml index a50d1f6d256d..42049792df28 100644 --- a/tests/testsuite/cargo_add/features_fuzzy/out/Cargo.toml +++ b/tests/testsuite/cargo_add/features_fuzzy/out/Cargo.toml @@ -6,4 +6,4 @@ version = "0.0.0" edition = "2015" [dependencies] -your_face = { version = "99999.0.0" } +your_face = { version = "99999.0.0", features = ["eyes"] } diff --git a/tests/testsuite/cargo_add/features_fuzzy/stderr.term.svg b/tests/testsuite/cargo_add/features_fuzzy/stderr.term.svg index b72f0d9965bb..08707c91b71d 100644 --- a/tests/testsuite/cargo_add/features_fuzzy/stderr.term.svg +++ b/tests/testsuite/cargo_add/features_fuzzy/stderr.term.svg @@ -20,17 +20,17 @@ - Updating `dummy-registry` index + warning: translating `your-face` to `your_face` - warning: translating `your-face` to `your_face` + Updating `dummy-registry` index Adding your_face v99999.0.0 to dependencies Features: - - ears + + eyes - - eyes + - ears - mouth