From 74d8fdc8fef42fe47b12d533bb0d58ae024c4c66 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Sat, 11 Nov 2023 13:45:50 +0100 Subject: [PATCH] Update test data for crate deduping Make data reflect a case where dev deps are existent. base-db::CrateGraph::extend now adds dev dependencies for a crate in case of its upgrading from a CrateOrigin::Lib kind of a crate to a CrateOrigin::Local one. --- crates/base-db/src/input.rs | 51 +++++++--- crates/project-model/src/tests.rs | 10 +- .../deduplication_crate_graph_A.json | 94 +++++++++++++++++-- .../deduplication_crate_graph_B.json | 48 ++++++---- 4 files changed, 162 insertions(+), 41 deletions(-) diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs index 7dec01ff4d..cec3e91eee 100644 --- a/crates/base-db/src/input.rs +++ b/crates/base-db/src/input.rs @@ -376,7 +376,7 @@ impl CrateData { let other_deps = other.dependencies.iter(); if ignore_dev_deps { - slf_deps + return slf_deps .clone() .filter(|it| it.kind == DependencyKind::Normal) .eq(other_deps.clone().filter(|it| it.kind == DependencyKind::Normal)); @@ -524,7 +524,7 @@ impl CrateGraph { self.check_cycle_after_dependency(from, dep.crate_id)?; - self.arena[from].add_dep(dep); + self.arena[from].add_dep_unchecked(dep); Ok(()) } @@ -665,16 +665,11 @@ impl CrateGraph { return Some((id, false)); } } - (CrateOrigin::Local { .. }, CrateOrigin::Library { .. }) => { + (a @ CrateOrigin::Local { .. }, CrateOrigin::Library { .. }) + | (a @ CrateOrigin::Library { .. }, CrateOrigin::Local { .. }) => { // See #15656 for a relevant example. if data.eq_ignoring_origin_and_deps(&crate_data, true) { - return Some((id, false)); - } - } - (CrateOrigin::Library { .. }, CrateOrigin::Local { .. }) => { - // See #15656 for a relevant example. - if data.eq_ignoring_origin_and_deps(&crate_data, true) { - return Some((id, true)); + return Some((id, if a.is_local() { false } else { true })); } } (_, _) => return None, @@ -692,6 +687,16 @@ impl CrateGraph { if let CrateOrigin::Library { repo, name } = origin_old { self.arena[res].origin = CrateOrigin::Local { repo, name: Some(name) }; } + + // Move local's dev dependencies into the newly-local-formerly-lib crate. + let dev_deps = crate_data + .dependencies + .clone() + .into_iter() + .filter(|dep| dep.kind() == DependencyKind::Dev) + .collect::>(); + + self.arena[res].add_dep(dev_deps).unwrap_or_default(); } } else { let id = self.arena.alloc(crate_data.clone()); @@ -761,10 +766,34 @@ impl ops::Index for CrateGraph { } } +struct ExistingDepsError(Vec); + impl CrateData { - fn add_dep(&mut self, dep: Dependency) { + /// Add a dependency to `self` without checking if the dependency + // is existent among `self.dependencies`. + fn add_dep_unchecked(&mut self, dep: Dependency) { self.dependencies.push(dep) } + + /// Add `deps` to `self` if the dependency is not already listed. + /// Finally returning an `Err` propagating the dependencies it couldn't add. + fn add_dep(&mut self, deps: Vec) -> Result<(), ExistingDepsError> { + let mut existing_deps: Vec = vec![]; + + deps.into_iter().for_each(|dep| { + if !self.dependencies.contains(&dep) { + self.dependencies.push(dep); + } else { + existing_deps.push(dep); + } + }); + + if !existing_deps.is_empty() { + return Err(ExistingDepsError(existing_deps)); + } + + Ok(()) + } } impl FromStr for Edition { diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs index 65c6f0b256..35ac80eee3 100644 --- a/crates/project-model/src/tests.rs +++ b/crates/project-model/src/tests.rs @@ -3,7 +3,7 @@ use std::{ path::{Path, PathBuf}, }; -use base_db::{CrateGraph, FileId, ProcMacroPaths}; +use base_db::{CrateGraph, DependencyKind, FileId, ProcMacroPaths}; use cfg::{CfgAtom, CfgDiff}; use expect_test::{expect_file, ExpectFile}; use paths::{AbsPath, AbsPathBuf}; @@ -272,7 +272,9 @@ fn test_deduplicate_crate_differing_in_origin() { } assert!(crates_named_p1.len() == 1); - assert!(crates_named_p1[0].origin.is_local()); + let p1 = crates_named_p1[0]; + assert!(p1.dependencies.iter().filter(|dep| dep.kind() == DependencyKind::Dev).count() == 1); + assert!(p1.origin.is_local()); } #[test] @@ -297,5 +299,7 @@ fn test_deduplicate_crate_differing_in_origin_in_rev_resolution_order() { } assert!(crates_named_p1.len() == 1); - assert!(crates_named_p1[0].origin.is_local()); + let p1 = crates_named_p1[0]; + assert!(p1.dependencies.iter().filter(|dep| dep.kind() == DependencyKind::Dev).count() == 1); + assert!(p1.origin.is_local()); } diff --git a/crates/project-model/test_data/deduplication_crate_graph_A.json b/crates/project-model/test_data/deduplication_crate_graph_A.json index 3f627082f9..edaf185fc6 100644 --- a/crates/project-model/test_data/deduplication_crate_graph_A.json +++ b/crates/project-model/test_data/deduplication_crate_graph_A.json @@ -3,7 +3,62 @@ { "name": "p1", "version": "0.1.0", - "id": "p1 0.1.0 (path+file:///path/to/project/projects/p1)", + "id": "p1 0.1.0 (path+file:///path/to/project/example_project/projects/p1)", + "license": null, + "license_file": null, + "description": null, + "source": null, + "dependencies": [ + { + "name": "p3", + "source": null, + "req": "*", + "kind": "dev", + "rename": null, + "optional": false, + "uses_default_features": true, + "features": [], + "target": null, + "registry": null, + "path": "/path/to/project/example_project/projects/p3" + } + ], + "targets": [ + { + "kind": [ + "lib" + ], + "crate_types": [ + "lib" + ], + "name": "p1", + "src_path": "/path/to/project/example_project/projects/p1/src/lib.rs", + "edition": "2021", + "doc": true, + "doctest": true, + "test": true + } + ], + "features": {}, + "manifest_path": "/path/to/project/example_project/projects/p1/Cargo.toml", + "metadata": null, + "publish": null, + "authors": [], + "categories": [], + "keywords": [], + "readme": null, + "repository": null, + "homepage": null, + "documentation": null, + "edition": "2021", + "links": null, + "default_run": null, + "rust_version": null + }, + { + "name": "p3", + "version": "0.1.0", + "id": "p3 0.1.0 (path+file:///path/to/project/example_project/projects/p3)", "license": null, "license_file": null, "description": null, @@ -17,8 +72,8 @@ "crate_types": [ "lib" ], - "name": "p1", - "src_path": "/path/to/project/projects/p1/src/lib.rs", + "name": "p3", + "src_path": "/path/to/project/example_project/projects/p3/src/lib.rs", "edition": "2021", "doc": true, "doctest": true, @@ -26,7 +81,7 @@ } ], "features": {}, - "manifest_path": "/path/to/project/projects/p1/Cargo.toml", + "manifest_path": "/path/to/project/example_project/projects/p3/Cargo.toml", "metadata": null, "publish": null, "authors": [], @@ -43,24 +98,43 @@ } ], "workspace_members": [ - "p1 0.1.0 (path+file:///path/to/project/projects/p1)" + "p1 0.1.0 (path+file:///path/to/project/example_project/projects/p1)" ], "workspace_default_members": [ - "p1 0.1.0 (path+file:///path/to/project/projects/p1)" + "p1 0.1.0 (path+file:///path/to/project/example_project/projects/p1)" ], "resolve": { "nodes": [ { - "id": "p1 0.1.0 (path+file:///path/to/project/projects/p1)", + "id": "p1 0.1.0 (path+file:///path/to/project/example_project/projects/p1)", + "dependencies": [ + "p3 0.1.0 (path+file:///path/to/project/example_project/projects/p3)" + ], + "deps": [ + { + "name": "p3", + "pkg": "p3 0.1.0 (path+file:///path/to/project/example_project/projects/p3)", + "dep_kinds": [ + { + "kind": "dev", + "target": null + } + ] + } + ], + "features": [] + }, + { + "id": "p3 0.1.0 (path+file:///path/to/project/example_project/projects/p3)", "dependencies": [], "deps": [], "features": [] } ], - "root": "p1 0.1.0 (path+file:///path/to/project/projects/p1)" + "root": "p1 0.1.0 (path+file:///path/to/project/example_project/projects/p1)" }, - "target_directory": "/path/to/project/projects/p1/target", + "target_directory": "/path/to/project/example_project/projects/p1/target", "version": 1, - "workspace_root": "/path/to/project/projects/p1", + "workspace_root": "/path/to/project/example_project/projects/p1", "metadata": null } \ No newline at end of file diff --git a/crates/project-model/test_data/deduplication_crate_graph_B.json b/crates/project-model/test_data/deduplication_crate_graph_B.json index a2bf1af044..4f753db71b 100644 --- a/crates/project-model/test_data/deduplication_crate_graph_B.json +++ b/crates/project-model/test_data/deduplication_crate_graph_B.json @@ -3,12 +3,26 @@ { "name": "p1", "version": "0.1.0", - "id": "p1 0.1.0 (path+file:///path/to/project/projects/p1)", + "id": "p1 0.1.0 (path+file:///path/to/project/example_project/projects/p1)", "license": null, "license_file": null, "description": null, "source": null, - "dependencies": [], + "dependencies": [ + { + "name": "p3", + "source": null, + "req": "*", + "kind": "dev", + "rename": null, + "optional": false, + "uses_default_features": true, + "features": [], + "target": null, + "registry": null, + "path": "/path/to/project/example_project/projects/p3" + } + ], "targets": [ { "kind": [ @@ -18,7 +32,7 @@ "lib" ], "name": "p1", - "src_path": "/path/to/project/projects/p1/src/lib.rs", + "src_path": "/path/to/project/example_project/projects/p1/src/lib.rs", "edition": "2021", "doc": true, "doctest": true, @@ -26,7 +40,7 @@ } ], "features": {}, - "manifest_path": "/path/to/project/projects/p1/Cargo.toml", + "manifest_path": "/path/to/project/example_project/projects/p1/Cargo.toml", "metadata": null, "publish": null, "authors": [], @@ -44,7 +58,7 @@ { "name": "p2", "version": "0.1.0", - "id": "p2 0.1.0 (path+file:///path/to/project/projects/p2)", + "id": "p2 0.1.0 (path+file:///path/to/project/example_project/projects/p2)", "license": null, "license_file": null, "description": null, @@ -61,7 +75,7 @@ "features": [], "target": null, "registry": null, - "path": "/path/to/project/projects/p1" + "path": "/path/to/project/example_project/projects/p1" } ], "targets": [ @@ -73,7 +87,7 @@ "lib" ], "name": "p2", - "src_path": "/path/to/project/projects/p2/src/lib.rs", + "src_path": "/path/to/project/example_project/projects/p2/src/lib.rs", "edition": "2021", "doc": true, "doctest": true, @@ -81,7 +95,7 @@ } ], "features": {}, - "manifest_path": "/path/to/project/projects/p2/Cargo.toml", + "manifest_path": "/path/to/project/example_project/projects/p2/Cargo.toml", "metadata": null, "publish": null, "authors": [], @@ -98,28 +112,28 @@ } ], "workspace_members": [ - "p2 0.1.0 (path+file:///path/to/project/projects/p2)" + "p2 0.1.0 (path+file:///path/to/project/example_project/projects/p2)" ], "workspace_default_members": [ - "p2 0.1.0 (path+file:///path/to/project/projects/p2)" + "p2 0.1.0 (path+file:///path/to/project/example_project/projects/p2)" ], "resolve": { "nodes": [ { - "id": "p1 0.1.0 (path+file:///path/to/project/projects/p1)", + "id": "p1 0.1.0 (path+file:///path/to/project/example_project/projects/p1)", "dependencies": [], "deps": [], "features": [] }, { - "id": "p2 0.1.0 (path+file:///path/to/project/projects/p2)", + "id": "p2 0.1.0 (path+file:///path/to/project/example_project/projects/p2)", "dependencies": [ - "p1 0.1.0 (path+file:///path/to/project/projects/p1)" + "p1 0.1.0 (path+file:///path/to/project/example_project/projects/p1)" ], "deps": [ { "name": "p1", - "pkg": "p1 0.1.0 (path+file:///path/to/project/projects/p1)", + "pkg": "p1 0.1.0 (path+file:///path/to/project/example_project/projects/p1)", "dep_kinds": [ { "kind": null, @@ -131,10 +145,10 @@ "features": [] } ], - "root": "p2 0.1.0 (path+file:///path/to/project/projects/p2)" + "root": "p2 0.1.0 (path+file:///path/to/project/example_project/projects/p2)" }, - "target_directory": "/path/to/project/projects/p2/target", + "target_directory": "/path/to/project/example_project/projects/p2/target", "version": 1, - "workspace_root": "/path/to/project/projects/p2", + "workspace_root": "/path/to/project/example_project/projects/p2", "metadata": null } \ No newline at end of file