diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-02 11:19:09 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-02 11:19:09 +0900 |
| commit | b216124157b69edc7330291214a6043c555f0ade (patch) | |
| tree | 13794ed3f158af0b01fc438548723e533eda4300 | |
| parent | 2ff728fe6796506be0e6b640ccb85ed3e1ce2b56 (diff) | |
| download | php-mozart-b216124157b69edc7330291214a6043c555f0ade.tar.gz php-mozart-b216124157b69edc7330291214a6043c555f0ade.tar.zst php-mozart-b216124157b69edc7330291214a6043c555f0ade.zip | |
feat(resolver): honor --ignore-platform-reqs and wildcard patterns
The pool builder and rule-set generator only consulted an exact-match
HashSet, so `--ignore-platform-reqs` (no value) and `--ignore-platform-req=ext-foo-*`
fell through to the SAT layer and produced "no matching package found"
for transitive platform deps. Track the bool flag separately and run
each platform name through `mozart_core::matches_wildcard` against the
configured patterns.
Unblocks four installer fixtures:
install-{ignore-platform-package-requirement-wildcard,ignore-platform-package-requirements}
update-{ignore-platform-package-requirement-wildcard,ignore-platform-package-requirements}.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| -rw-r--r-- | crates/mozart-registry/src/resolver.rs | 9 | ||||
| -rw-r--r-- | crates/mozart-sat-resolver/src/pool_builder.rs | 24 | ||||
| -rw-r--r-- | crates/mozart-sat-resolver/src/rule_set_generator.rs | 28 | ||||
| -rw-r--r-- | crates/mozart/tests/installer.rs | 20 |
4 files changed, 55 insertions, 26 deletions
diff --git a/crates/mozart-registry/src/resolver.rs b/crates/mozart-registry/src/resolver.rs index 7aab6b2..710a9c4 100644 --- a/crates/mozart-registry/src/resolver.rs +++ b/crates/mozart-registry/src/resolver.rs @@ -231,7 +231,9 @@ fn should_skip_platform_dep( if ignore_platform_reqs { return true; } - ignore_platform_req_list.iter().any(|p| p == dep_name) + ignore_platform_req_list + .iter() + .any(|p| mozart_core::matches_wildcard(dep_name, p)) } // ───────────────────────────────────────────────────────────────────────────── @@ -412,13 +414,11 @@ pub async fn resolve(request: &ResolveRequest) -> Result<Vec<ResolvedPackage>, R // Set up ignore list for platform requirements let mut ignore_set: HashSet<String> = HashSet::new(); - if request.ignore_platform_reqs { - // We'll skip platform deps in the loop below - } for name in &request.ignore_platform_req_list { ignore_set.insert(name.clone()); } builder.set_ignore_platform_reqs(ignore_set.clone()); + builder.set_ignore_all_platform_reqs(request.ignore_platform_reqs); // Add platform packages as fixed entries let platform_config = request.platform.to_versions(); @@ -560,6 +560,7 @@ pub async fn resolve(request: &ResolveRequest) -> Result<Vec<ResolvedPackage>, R // Generate rules let mut generator = RuleSetGenerator::new(&mut pool); generator.set_ignore_platform_reqs(ignore_set); + generator.set_ignore_all_platform_reqs(request.ignore_platform_reqs); let rules = generator.generate(&root_requires, &fixed_ids); // Create policy and solve diff --git a/crates/mozart-sat-resolver/src/pool_builder.rs b/crates/mozart-sat-resolver/src/pool_builder.rs index a642fc3..544cac3 100644 --- a/crates/mozart-sat-resolver/src/pool_builder.rs +++ b/crates/mozart-sat-resolver/src/pool_builder.rs @@ -15,8 +15,11 @@ pub struct PoolBuilder { pending_names: VecDeque<String>, /// Package names that have already been explored (returned by next_pending). explored_names: HashSet<String>, - /// Platform packages to ignore. + /// Specific platform packages to ignore (from `--ignore-platform-req=name`). ignore_platform_reqs: HashSet<String>, + /// When true, ignore every platform package (php, ext-*, lib-*, composer-*). + /// Mirrors `--ignore-platform-reqs` (no value). + ignore_all_platform_reqs: bool, } impl PoolBuilder { @@ -27,6 +30,7 @@ impl PoolBuilder { pending_names: VecDeque::new(), explored_names: HashSet::new(), ignore_platform_reqs: HashSet::new(), + ignore_all_platform_reqs: false, } } @@ -35,6 +39,22 @@ impl PoolBuilder { self.ignore_platform_reqs = names; } + /// When set, every platform package is skipped during exploration. + pub fn set_ignore_all_platform_reqs(&mut self, ignore_all: bool) { + self.ignore_all_platform_reqs = ignore_all; + } + + fn is_ignored_platform_dep(&self, name: &str) -> bool { + if self + .ignore_platform_reqs + .iter() + .any(|p| mozart_core::matches_wildcard(name, p)) + { + return true; + } + self.ignore_all_platform_reqs && mozart_core::platform::is_platform_package(name) + } + /// Add a package version to the builder. Returns true if it's new. pub fn add_package(&mut self, input: PoolPackageInput) -> bool { let key = format!("{}@{}", input.name, input.version); @@ -45,7 +65,7 @@ impl PoolBuilder { // Queue dependency names for exploration for link in &input.requires { - if !self.ignore_platform_reqs.contains(&link.target) { + if !self.is_ignored_platform_dep(&link.target) { self.pending_names.push_back(link.target.clone()); } } diff --git a/crates/mozart-sat-resolver/src/rule_set_generator.rs b/crates/mozart-sat-resolver/src/rule_set_generator.rs index 39d28fd..bc56dff 100644 --- a/crates/mozart-sat-resolver/src/rule_set_generator.rs +++ b/crates/mozart-sat-resolver/src/rule_set_generator.rs @@ -13,8 +13,11 @@ pub struct RuleSetGenerator<'a> { added_map: HashSet<PackageId>, /// Package names → list of package IDs with that name (non-alias). added_packages_by_name: HashMap<String, Vec<PackageId>>, - /// Platform packages to ignore. + /// Specific platform packages to ignore (from `--ignore-platform-req=name`). ignore_platform_reqs: HashSet<String>, + /// When true, every platform package is treated as ignored. + /// Mirrors `--ignore-platform-reqs` (no value). + ignore_all_platform_reqs: bool, } impl<'a> RuleSetGenerator<'a> { @@ -25,6 +28,7 @@ impl<'a> RuleSetGenerator<'a> { added_map: HashSet::new(), added_packages_by_name: HashMap::new(), ignore_platform_reqs: HashSet::new(), + ignore_all_platform_reqs: false, } } @@ -33,6 +37,22 @@ impl<'a> RuleSetGenerator<'a> { self.ignore_platform_reqs = names; } + /// When set, every platform package is treated as ignored. + pub fn set_ignore_all_platform_reqs(&mut self, ignore_all: bool) { + self.ignore_all_platform_reqs = ignore_all; + } + + fn is_ignored_platform_dep(&self, name: &str) -> bool { + if self + .ignore_platform_reqs + .iter() + .any(|p| mozart_core::matches_wildcard(name, p)) + { + return true; + } + self.ignore_all_platform_reqs && mozart_core::platform::is_platform_package(name) + } + /// Generate rules for a set of requirements and fixed packages. /// /// Port of Composer's RuleSetGenerator::getRulesFor. @@ -60,7 +80,7 @@ impl<'a> RuleSetGenerator<'a> { // Process root requirements for (name, constraint) in requires { - if self.ignore_platform_reqs.contains(name.as_str()) { + if self.is_ignored_platform_dep(name.as_str()) { continue; } @@ -116,7 +136,7 @@ impl<'a> RuleSetGenerator<'a> { // Process each requirement for link in requires { - if self.ignore_platform_reqs.contains(&link.target) { + if self.is_ignored_platform_dep(&link.target) { continue; } @@ -168,7 +188,7 @@ impl<'a> RuleSetGenerator<'a> { let conflicts = pkg.conflicts.clone(); for link in conflicts { - if self.ignore_platform_reqs.contains(&link.target) { + if self.is_ignored_platform_dep(&link.target) { continue; } diff --git a/crates/mozart/tests/installer.rs b/crates/mozart/tests/installer.rs index fc13392..3c47750 100644 --- a/crates/mozart/tests/installer.rs +++ b/crates/mozart/tests/installer.rs @@ -190,14 +190,8 @@ installer_fixture!(install_funding_notice); installer_fixture!(install_funding_notice_env); installer_fixture!(install_funding_notice_not_displayed_env); installer_fixture!(install_ignore_platform_package_requirement_list); -installer_fixture!( - install_ignore_platform_package_requirement_wildcard, - ignore = "mozart binary cannot yet run this fixture" -); -installer_fixture!( - install_ignore_platform_package_requirements, - ignore = "mozart binary cannot yet run this fixture" -); +installer_fixture!(install_ignore_platform_package_requirement_wildcard); +installer_fixture!(install_ignore_platform_package_requirements); installer_fixture!( install_missing_alias_from_lock, ignore = "mozart binary cannot yet run this fixture" @@ -461,14 +455,8 @@ installer_fixture!( ); installer_fixture!(update_ignore_platform_package_requirement_list); installer_fixture!(update_ignore_platform_package_requirement_list_upper_bounds); -installer_fixture!( - update_ignore_platform_package_requirement_wildcard, - ignore = "mozart binary cannot yet run this fixture" -); -installer_fixture!( - update_ignore_platform_package_requirements, - ignore = "mozart binary cannot yet run this fixture" -); +installer_fixture!(update_ignore_platform_package_requirement_wildcard); +installer_fixture!(update_ignore_platform_package_requirements); installer_fixture!(update_installed_alias); installer_fixture!(update_installed_alias_dry_run); installer_fixture!(update_installed_reference); |
