From 543a138c285cec20f1454af02b4859cd90a03487 Mon Sep 17 00:00:00 2001 From: Jonas Dohse Date: Thu, 2 May 2024 11:55:43 +0200 Subject: [PATCH] (Unify workspace and package fuzzy dependency lookup) --- src/cargo/ops/cargo_add/mod.rs | 75 +++++++++++++++++----------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/src/cargo/ops/cargo_add/mod.rs b/src/cargo/ops/cargo_add/mod.rs index 3637f9bc30c3..a22e9e42e962 100644 --- a/src/cargo/ops/cargo_add/mod.rs +++ b/src/cargo/ops/cargo_add/mod.rs @@ -364,23 +364,8 @@ fn resolve_dependency( }; selected_dep = populate_dependency(selected_dep, arg); - let mut old_dep = get_existing_dependency(manifest, selected_dep.toml_key(), section)?; - if old_dep.is_none() && selected_dep.source().is_none() && selected_dep.rename().is_none() { - for name_permutation in [ - selected_dep.name.replace('-', "_"), - selected_dep.name.replace('_', "-"), - ] { - old_dep = get_existing_dependency(manifest, &name_permutation, section)?; - if old_dep.is_some() { - gctx.shell().warn(format!( - "translating `{}` to `{}`", - selected_dep.name, &name_permutation, - ))?; - selected_dep.name = name_permutation; - break; - } - } - } + 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 { @@ -403,26 +388,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 - let mut workspace_dep = find_workspace_dep(dependency.toml_key(), ws.root_manifest()).ok(); - if workspace_dep.is_none() && dependency.rename.is_none() { - for name_permutation in [ - dependency.name.replace('-', "_"), - dependency.name.replace('_', "-"), - ] { - workspace_dep = find_workspace_dep(&name_permutation, ws.root_manifest()).ok(); - if let Some(workspace_dep) = &workspace_dep { - if let Some(Source::Registry(_source)) = &workspace_dep.source { - gctx.shell().warn(format!( - "translating `{}` to `{}`", - dependency.name, &name_permutation, - ))?; - dependency.name = name_permutation; - break; - } - } - } - } - if let Some(_dep) = workspace_dep { + 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 @@ -488,6 +455,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