From ab2772b8c85139df7d5e625ac5262d385e5ab4c0 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 3 May 2026 12:25:45 +0900 Subject: fix(resolver): seed root package into pool as fixed entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Composer's RootPackageRepository puts a clone of the root package into the pool as a fixed entry — its `require` / `require-dev` cleared, but its name, version, provides, and replaces preserved. That way a transitive `require` pointing back at the root resolves through the pool the same way any other reference would, and legal circular dependencies (root requires A, A requires root) work. Mozart had no such seed: the rule generator only knew about the root through the explicit root-require / root-provide / root-replace tables, so a transitive consumer requiring the root by name failed with no provider. Plumb root_version through ResolveRequest (RawPackageData gains a matching `Option` field), build a fixed PoolPackageInput for the root with provides/replaces lifted from request.root_provide / root_replace, and skip the root by name when collecting the resolver's output so it doesn't leak into the lock file. Falls back to `1.0.0+no-version-set` (Composer's RootPackage::DEFAULT_PRETTY_VERSION) when the root composer.json omits `version`. Unblocks circular_dependency2, conflict_against_replaced_package_problem, and provider_conflicts installer fixtures. Co-Authored-By: Claude Opus 4.7 (1M context) --- crates/mozart/src/commands/create_project.rs | 1 + crates/mozart/src/commands/remove.rs | 4 ++++ crates/mozart/src/commands/require.rs | 3 +++ crates/mozart/src/commands/update.rs | 2 ++ 4 files changed, 10 insertions(+) (limited to 'crates/mozart/src/commands') diff --git a/crates/mozart/src/commands/create_project.rs b/crates/mozart/src/commands/create_project.rs index 139550a..eceafd0 100644 --- a/crates/mozart/src/commands/create_project.rs +++ b/crates/mozart/src/commands/create_project.rs @@ -409,6 +409,7 @@ pub async fn execute( let request = ResolveRequest { root_name: raw.name.clone(), + root_version: raw.version.clone(), require, require_dev, include_dev: dev_mode, diff --git a/crates/mozart/src/commands/remove.rs b/crates/mozart/src/commands/remove.rs index df8bf2b..f11e9c3 100644 --- a/crates/mozart/src/commands/remove.rs +++ b/crates/mozart/src/commands/remove.rs @@ -243,6 +243,7 @@ pub async fn execute( let request = ResolveRequest { root_name: raw.name.clone(), + root_version: raw.version.clone(), require, require_dev, include_dev: dev_mode, @@ -513,6 +514,7 @@ async fn remove_unused( let request = ResolveRequest { root_name: raw.name.clone(), + root_version: raw.version.clone(), require, require_dev, include_dev: dev_mode, @@ -866,6 +868,7 @@ mod tests { // Simulate initial install let request = ResolveRequest { root_name: String::new(), + root_version: None, require: vec![("psr/log".to_string(), "^3.0".to_string())], require_dev: vec![], include_dev: false, @@ -919,6 +922,7 @@ mod tests { // Re-resolve with empty require let request2 = ResolveRequest { root_name: String::new(), + root_version: None, require: vec![], require_dev: vec![], include_dev: false, diff --git a/crates/mozart/src/commands/require.rs b/crates/mozart/src/commands/require.rs index 69d7ea2..cac0dad 100644 --- a/crates/mozart/src/commands/require.rs +++ b/crates/mozart/src/commands/require.rs @@ -631,6 +631,7 @@ pub async fn execute( let request = ResolveRequest { root_name: raw.name.clone(), + root_version: raw.version.clone(), require, require_dev, include_dev: dev_mode, @@ -1031,6 +1032,7 @@ mod tests { let request = ResolveRequest { root_name: String::new(), + root_version: None, require: vec![("psr/log".to_string(), "^3.0".to_string())], require_dev: vec![], include_dev: false, @@ -1101,6 +1103,7 @@ mod tests { let request = ResolveRequest { root_name: String::new(), + root_version: None, require: vec![("psr/log".to_string(), "^3.0".to_string())], require_dev: vec![], include_dev: false, diff --git a/crates/mozart/src/commands/update.rs b/crates/mozart/src/commands/update.rs index 0c25a9e..db9d616 100644 --- a/crates/mozart/src/commands/update.rs +++ b/crates/mozart/src/commands/update.rs @@ -883,6 +883,7 @@ pub async fn run( let request = ResolveRequest { root_name: composer_json.name.clone(), + root_version: composer_json.version.clone(), require, require_dev, include_dev: dev_mode, @@ -1993,6 +1994,7 @@ mod tests { let request = ResolveRequest { root_name: String::new(), + root_version: None, require: vec![("monolog/monolog".to_string(), "^3.0".to_string())], require_dev: vec![], include_dev: false, -- cgit v1.3.1