diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-03 22:26:55 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-03 22:26:55 +0900 |
| commit | 2a680f571eae31737525ef96105e929ae420b061 (patch) | |
| tree | 6297d7b76753de69e9934550a739c39459d8a681 /crates/mozart-registry/src/resolver.rs | |
| parent | 55e6f5367bf86d1dc6e99b7492d86c5208dd1f1c (diff) | |
| download | php-mozart-2a680f571eae31737525ef96105e929ae420b061.tar.gz php-mozart-2a680f571eae31737525ef96105e929ae420b061.tar.zst php-mozart-2a680f571eae31737525ef96105e929ae420b061.zip | |
fix(resolver): strip inline #ref and gate alias trace on alias stability
Two related parity gaps surfaced by the `alias-with-reference` fixture:
1. A root require like `dev-main#abcd as 1.0.0` left the SAT-side
constraint as `dev-main#abcd`, which no candidate matched, so
resolution failed before the alias could be materialized. Mirror
Composer's `extractAliases` regex (which captures only the
constraint up to `#`) and `RootPackageLoader::extractReferences`
(which records the hash separately): drop the trailing `#hex` from
the resolver-side constraint and from the alias's left-hand side.
Lockfile generation already pulls the reference back out of the
raw require map for the post-resolve override.
2. `MarkAliasInstalled`'s trace line gated the reference suffix on
the *target* package's stability, so a stable alias like `1.0.0`
pointing at a dev-branch target rendered as `1.0.0 abcd`. Mirror
`AliasPackage::getFullPrettyVersion`: the alias decides on its own
whether to append the suffix based on its own normalized version,
so a stable alias skips the suffix even when the target is dev.
Diffstat (limited to 'crates/mozart-registry/src/resolver.rs')
| -rw-r--r-- | crates/mozart-registry/src/resolver.rs | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/crates/mozart-registry/src/resolver.rs b/crates/mozart-registry/src/resolver.rs index 67650e6..9fb5cec 100644 --- a/crates/mozart-registry/src/resolver.rs +++ b/crates/mozart-registry/src/resolver.rs @@ -288,7 +288,11 @@ struct RootAlias { /// the cleaned constraint plus the `(left, right)` pieces when an alias is /// present. Mirrors Composer's `VersionParser::parseConstraint` `as`-strip: /// the constraint passed to the resolver is the LEFT side, and a separate -/// alias entry is recorded for the RIGHT side. +/// alias entry is recorded for the RIGHT side. A trailing `#hex` reference +/// (`dev-main#abcd`) is also stripped — Composer's `extractAliases` regex +/// `([^,\s#|]+)(?:#[^ ]+)?` excludes it from the captured constraint, and +/// `RootPackageLoader::extractReferences` records the hash separately for +/// the post-resolve `setSourceDistReferences` pass. fn strip_root_alias_clause(constraint: &str) -> (String, Option<(String, String)>) { let trimmed = constraint.trim(); if let Some(idx) = trimmed.find(" as ") { @@ -299,13 +303,28 @@ fn strip_root_alias_clause(constraint: &str) -> (String, Option<(String, String) && !before.contains([' ', '\t', ',', '|']) && !after.contains([' ', '\t', ',', '|']) { - return ( - before.to_string(), - Some((before.to_string(), after.to_string())), - ); + let cleaned = strip_inline_reference(before); + return (cleaned.clone(), Some((cleaned, after.to_string()))); } } - (trimmed.to_string(), None) + (strip_inline_reference(trimmed), None) +} + +/// Drop a trailing `#hex` reference from a single-atom `dev-*` / `*-dev` +/// constraint, matching Composer's `'{^[^,\s@]+?#([a-f0-9]+)$}'` guard. +/// Lockfile generation records the reference separately via +/// `extract_root_references` and applies it after resolution, so the SAT +/// constraint itself only needs the bare branch name. +fn strip_inline_reference(s: &str) -> String { + if let Some((head, hash)) = s.rsplit_once('#') + && !hash.is_empty() + && hash.chars().all(|c| c.is_ascii_hexdigit()) + && !head.contains([' ', '\t', ',', '@']) + && (head.to_lowercase().starts_with("dev-") || head.to_lowercase().ends_with("-dev")) + { + return head.to_string(); + } + s.to_string() } // ───────────────────────────────────────────────────────────────────────────── |
