aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart/src/commands/install.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mozart/src/commands/install.rs')
-rw-r--r--crates/mozart/src/commands/install.rs9
1 files changed, 8 insertions, 1 deletions
diff --git a/crates/mozart/src/commands/install.rs b/crates/mozart/src/commands/install.rs
index 58a01b4..017c08e 100644
--- a/crates/mozart/src/commands/install.rs
+++ b/crates/mozart/src/commands/install.rs
@@ -206,12 +206,19 @@ pub fn compute_operations<'a>(
ops.push((pkg, action));
}
- // Compute removals: packages in installed but not in locked
+ // Compute removals: packages in installed but not in locked. Iterate
+ // installed.json in reverse, mirroring Composer's
+ // `Transaction::calculateOperations`, which seeds `removeMap` from
+ // `presentPackages` in order and then `array_unshift`s each entry onto
+ // `operations` — flipping the iteration order. Without the flip, two
+ // co-orphaned packages emit removals in the wrong order vs Composer's
+ // trace.
let locked_names: IndexSet<String> = locked.iter().map(|p| p.name.to_lowercase()).collect();
let removals: Vec<String> = installed
.packages
.iter()
+ .rev()
.filter(|p| !locked_names.contains(&p.name.to_lowercase()))
.map(|p| p.name.clone())
.collect();