diff options
Diffstat (limited to 'crates/mozart-sat-resolver/src/pool.rs')
| -rw-r--r-- | crates/mozart-sat-resolver/src/pool.rs | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/crates/mozart-sat-resolver/src/pool.rs b/crates/mozart-sat-resolver/src/pool.rs index 652fc60..0312c24 100644 --- a/crates/mozart-sat-resolver/src/pool.rs +++ b/crates/mozart-sat-resolver/src/pool.rs @@ -53,6 +53,13 @@ pub struct PoolPackage { pub conflicts: Vec<PoolLink>, /// Whether this is a fixed/locked package. pub is_fixed: bool, + /// If `Some`, this package is an `AliasPackage` whose target is the + /// other pool entry with the given ID. Composer creates these for + /// `extra.branch-alias` entries (dev branch → numeric alias). When set, + /// the rule generator emits `PackageAlias`/`PackageInverseAlias` rules + /// instead of regular requires; same-name conflict rules also skip + /// alias packages. + pub is_alias_of: Option<PackageId>, } impl PoolPackage { @@ -99,6 +106,12 @@ pub struct PoolPackageInput { pub provides: Vec<PoolLink>, pub conflicts: Vec<PoolLink>, pub is_fixed: bool, + /// When `Some`, the value is the **normalized** version of another input + /// in this build batch with the same `name`; the pool will resolve it to + /// that input's [`PackageId`] in [`PoolPackage::is_alias_of`]. Used by + /// the registry layer to materialize Composer's `AliasPackage` for + /// `extra.branch-alias` entries. + pub is_alias_of: Option<String>, } /// The package pool: contains all candidate packages for dependency resolution. @@ -119,11 +132,17 @@ pub struct Pool { impl Pool { /// Create a new pool from a list of package inputs. pub fn new(inputs: Vec<PoolPackageInput>, unacceptable_fixed_ids: Vec<PackageId>) -> Self { - let mut packages = Vec::with_capacity(inputs.len()); + let mut packages: Vec<PoolPackage> = Vec::with_capacity(inputs.len()); let mut package_by_name: HashMap<String, Vec<PackageId>> = HashMap::new(); + // Collect alias links (alias_idx, target_name, target_normalized) for + // a second pass once every input has a stable ID. + let mut pending_aliases: Vec<(usize, String, String)> = Vec::new(); for (idx, input) in inputs.into_iter().enumerate() { let id = (idx as PackageId) + 1; + if let Some(target) = input.is_alias_of.clone() { + pending_aliases.push((idx, input.name.clone(), target)); + } let pkg = PoolPackage { id, name: input.name, @@ -134,6 +153,7 @@ impl Pool { provides: input.provides, conflicts: input.conflicts, is_fixed: input.is_fixed, + is_alias_of: None, }; // Index by all names this package provides @@ -147,6 +167,25 @@ impl Pool { packages.push(pkg); } + // Resolve alias targets: for each alias input, find the matching + // (name, normalized version) entry and store its ID. Mirrors the + // post-construction wiring Composer does in + // `RepositorySet::createAliasPackage` / `addPackage`. + for (alias_idx, name, target_normalized) in pending_aliases { + if let Some(ids) = package_by_name.get(&name) { + let target_id = ids.iter().copied().find(|&id| { + let candidate = &packages[(id - 1) as usize]; + !candidate.name.is_empty() + && candidate.name == name + && candidate.version == target_normalized + && candidate.is_alias_of.is_none() + }); + if let Some(tid) = target_id { + packages[alias_idx].is_alias_of = Some(tid); + } + } + } + Pool { packages, package_by_name, @@ -317,6 +356,7 @@ mod tests { provides: vec![], conflicts: vec![], is_fixed: false, + is_alias_of: None, } } |
