From b60cf8d9cb6776e5df85f080b5bb3fba252e154c Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 2 May 2026 22:59:23 +0900 Subject: fix(resolver): honor root self-provide/replace as require fulfilment Port Composer's RuleSetGenerator::createRequireRule self-fulfilling branch: when the root composer.json's `provide` or `replace` covers a name it also requires (with intersecting constraints), skip emitting an install-one-of rule for that root require. Composer relies on the root package being a fixed entry in the pool so whatProvides() includes it; Mozart does not yet add the root to the pool, so the same decision is made via explicit `root_provide` / `root_replace` tables threaded through ResolveRequest. Without this, an inline repo package whose name matches the root's provide was being force-installed. Fixes installer fixtures `provider_satisfies_its_own_requirement` and `replacer_satisfies_its_own_requirement`. --- crates/mozart/src/commands/remove.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'crates/mozart/src/commands/remove.rs') diff --git a/crates/mozart/src/commands/remove.rs b/crates/mozart/src/commands/remove.rs index 58917e9..20cb6a2 100644 --- a/crates/mozart/src/commands/remove.rs +++ b/crates/mozart/src/commands/remove.rs @@ -258,6 +258,16 @@ pub async fn execute( ), temporary_constraints: HashMap::new(), raw_repositories: raw.repositories.clone(), + root_provide: raw + .provide + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(), + root_replace: raw + .replace + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(), }; // Print header messages @@ -518,6 +528,16 @@ async fn remove_unused( ), temporary_constraints: HashMap::new(), raw_repositories: raw.repositories.clone(), + root_provide: raw + .provide + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(), + root_replace: raw + .replace + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(), }; console.info("Resolving dependencies to detect unused packages..."); @@ -866,6 +886,8 @@ mod tests { ), temporary_constraints: HashMap::new(), raw_repositories: vec![], + root_provide: HashMap::new(), + root_replace: HashMap::new(), }; let resolved = resolve(&request) .await @@ -917,6 +939,8 @@ mod tests { ), temporary_constraints: HashMap::new(), raw_repositories: vec![], + root_provide: HashMap::new(), + root_replace: HashMap::new(), }; let resolved2 = resolve(&request2) .await -- cgit v1.3.1