From c53dfc52f6449c8d5ca0b160a2a25f99790711f2 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 3 May 2026 12:36:34 +0900 Subject: fix(resolver): carry root composer.json conflicts onto the in-pool root entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The root pool entry now seeded from composer.json carried provides and replaces but no conflicts, so a root-level conflict like \`{"some/dep": ">=1.3"}\` was silently dropped. Composer keeps these on the RootPackage (which lives in the pool via RootPackageRepository), and the SAT generator turns them into rules that forbid any candidate matching the constraint — including a branch alias that would resolve to a matching version. Without that, Mozart cheerfully installs both the required dev branch and its conflicting alias. Plumb composer.json's \`conflict\` map through ResolveRequest as root_conflict and project it onto the root pool entry as PoolLink conflicts; all callers updated. Unblocks conflict_on_root_with_alias_prevents_update_if_not_required and conflict_with_alias_prevents_update installer fixtures. Co-Authored-By: Claude Opus 4.7 (1M context) --- crates/mozart/src/commands/update.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'crates/mozart/src/commands/update.rs') diff --git a/crates/mozart/src/commands/update.rs b/crates/mozart/src/commands/update.rs index db9d616..130d7e3 100644 --- a/crates/mozart/src/commands/update.rs +++ b/crates/mozart/src/commands/update.rs @@ -907,6 +907,11 @@ pub async fn run( .iter() .map(|(k, v)| (k.clone(), v.clone())) .collect(), + root_conflict: composer_json + .conflict + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(), }; // Step 6: Print header and run resolver @@ -2017,6 +2022,7 @@ mod tests { raw_repositories: vec![], root_provide: IndexMap::new(), root_replace: IndexMap::new(), + root_conflict: IndexMap::new(), }; let resolved = resolve(&request).await.expect("Resolution should succeed"); -- cgit v1.3.1