aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart-sat-resolver/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-02 22:46:44 +0900
committernsfisis <nsfisis@gmail.com>2026-05-02 22:46:44 +0900
commit3c61a7e1e557e3b90128d2ec29227f166b17c05b (patch)
treee68f5a03ac3ca5ba3a1ab29de755b18e0f3228e5 /crates/mozart-sat-resolver/src
parent8da98493daf5013585e07ec98ca6960a42924edf (diff)
downloadphp-mozart-3c61a7e1e557e3b90128d2ec29227f166b17c05b.tar.gz
php-mozart-3c61a7e1e557e3b90128d2ec29227f166b17c05b.tar.zst
php-mozart-3c61a7e1e557e3b90128d2ec29227f166b17c05b.zip
feat(resolver): support inline #ref pin and default-branch alias
Adds the missing pieces for installer fixtures that pin a dev package via `dev-foo#hex` or rely on Composer's `default-branch: true` synthetic `9999999-dev` alias. Mirrors Composer at four layers: 1. `mozart_semver::parse_single` strips `dev-...#hex` / `....x-dev#hex` suffixes from constraints (Composer's `parseConstraint` regex). 2. `PackagistVersion` carries `default_branch`. When set on a `dev-` package with no numeric prefix, `packagist_to_pool_inputs` emits the synthetic `9999999-dev` alias — but skips it when an explicit `extra.branch-alias` already covers the version (matches `ArrayLoader::getBranchAlias`). 3. `RuleSetGenerator::generate` picks up `addRulesForRootAliases`: any pool alias whose target was added gets its own alias↔target rules so the SAT solver pulls them in together. 4. `lockfile::generate_lock_file` extracts root `#hex` overrides from `require`/`require-dev` and rewrites source/dist references (and github/gitlab/bitbucket archive URLs) on the matched package, the `setSourceDistReferences` ladder Composer runs in `PoolBuilder`. Resolver also infers `Stability::Dev` from a `dev-foo` style single-atom constraint when no explicit `@flag` is given, mirroring the second loop of `RootPackageLoader::extractStabilityFlags` so the package isn't filtered out under default `stable` minimum-stability. Newly green: install_branch_alias_composer_repo, install_reference, conflict_with_alias_prevents_update_if_not_required, unbounded_conflict_matches_default_branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart-sat-resolver/src')
-rw-r--r--crates/mozart-sat-resolver/src/rule_set_generator.rs18
1 files changed, 18 insertions, 0 deletions
diff --git a/crates/mozart-sat-resolver/src/rule_set_generator.rs b/crates/mozart-sat-resolver/src/rule_set_generator.rs
index b5dfcdb..92b9f77 100644
--- a/crates/mozart-sat-resolver/src/rule_set_generator.rs
+++ b/crates/mozart-sat-resolver/src/rule_set_generator.rs
@@ -105,6 +105,24 @@ impl<'a> RuleSetGenerator<'a> {
}
}
+ // Mirror Composer's `RuleSetGenerator::addRulesForRootAliases`:
+ // ensure every alias whose target was already added gets its own
+ // alias↔target rules, even when the alias itself didn't appear in
+ // any root require's `whatProvides` (e.g. the synthetic
+ // `9999999-dev` alias from a `default-branch: true` package, which
+ // only matches a literal `9999999-dev` constraint).
+ let alias_pairs: Vec<(PackageId, PackageId)> = self
+ .pool
+ .packages()
+ .iter()
+ .filter_map(|p| p.is_alias_of.map(|t| (p.id, t)))
+ .collect();
+ for (alias_id, target_id) in alias_pairs {
+ if self.added_map.contains(&target_id) && !self.added_map.contains(&alias_id) {
+ self.add_rules_for_package(alias_id);
+ }
+ }
+
// Add conflict rules
self.add_conflict_rules();