fix(resolver): 🐛 correctly insert packages from lockfile

This commit is contained in:
daimond113 2024-03-28 13:28:28 +01:00
parent 7f6d33814b
commit fe5630af57
No known key found for this signature in database
GPG key ID: 3A8ECE51328B513C

View file

@ -225,25 +225,29 @@ impl Manifest {
let current_dependencies = self.dependencies(); let current_dependencies = self.dependencies();
let current_specifiers = current_dependencies let current_specifiers = current_dependencies
.values() .clone()
.map(|(specifier, _)| specifier) .into_iter()
.collect::<HashSet<_>>(); .map(|(desired_name, (specifier, _))| (specifier, desired_name))
.collect::<HashMap<_, _>>();
// populate the new lockfile with all root dependencies (and their dependencies) from the old lockfile // populate the new lockfile with all root dependencies (and their dependencies) from the old lockfile
for (name, versions) in &old_root.children { for (name, versions) in &old_root.children {
for (version, resolved_package) in versions { for (version, resolved_package) in versions {
let specifier = old_root.root_specifier(resolved_package); let Some((old_specifier, desired_name)) = old_root
.root_specifier(resolved_package)
if !specifier .and_then(|(old_specifier, _)| {
.is_some_and(|(specifier, _)| current_specifiers.contains(specifier)) current_specifiers
{ .get(old_specifier)
.map(|desired_name| (old_specifier, desired_name))
})
else {
continue; continue;
} };
root.specifiers root.specifiers.entry(name.clone()).or_default().insert(
.entry(name.clone()) version.clone(),
.or_default() (old_specifier.clone(), desired_name.clone()),
.insert(version.clone(), specifier.unwrap().clone()); );
let mut queue = VecDeque::from([(resolved_package, 0usize)]); let mut queue = VecDeque::from([(resolved_package, 0usize)]);
@ -254,28 +258,32 @@ impl Manifest {
); );
root.children root.children
.entry(name.clone()) .entry(resolved_package.pkg_ref.name())
.or_default() .or_default()
.insert(version.clone(), resolved_package.clone()); .insert(
resolved_package.pkg_ref.version().clone(),
resolved_package.clone(),
);
for (dep_name, (dep_version, _)) in &resolved_package.dependencies { for (dep_name, (dep_version, _)) in &resolved_package.dependencies {
if root if root
.children .children
.get(dep_name) .get(dep_name)
.and_then(|v| v.get(dep_version)) .and_then(|v| v.get(dep_version))
.is_none() .is_some()
{ {
let dep = old_root continue;
}
let Some(dep) = old_root
.children .children
.get(dep_name) .get(dep_name)
.and_then(|v| v.get(dep_version)); .and_then(|v| v.get(dep_version))
else {
return Err(ResolveError::OutOfDateLockfile);
};
match dep { queue.push_back((dep, depth + 1));
Some(dep) => queue.push_back((dep, depth + 1)),
// the lockfile is out of date
None => return Err(ResolveError::OutOfDateLockfile),
}
}
} }
} }
} }