aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart-sat-resolver/src/policy.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mozart-sat-resolver/src/policy.rs')
-rw-r--r--crates/mozart-sat-resolver/src/policy.rs46
1 files changed, 45 insertions, 1 deletions
diff --git a/crates/mozart-sat-resolver/src/policy.rs b/crates/mozart-sat-resolver/src/policy.rs
index aa63be7..a66719f 100644
--- a/crates/mozart-sat-resolver/src/policy.rs
+++ b/crates/mozart-sat-resolver/src/policy.rs
@@ -64,8 +64,20 @@ impl DefaultPolicy {
let pkg_a = pool.literal_to_package(a);
let pkg_b = pool.literal_to_package(b);
- // If same name, prefer higher version (or lower if prefer_lowest)
+ // If same name, apply Composer's policy ordering. Mirrors
+ // `DefaultPolicy::versionCompare`: when `prefer_stable` is on and
+ // the two candidates have different stabilities, the more-stable
+ // one wins outright — `prefer_lowest` only kicks in within the same
+ // stability tier. Otherwise sort by version (asc for prefer_lowest,
+ // desc otherwise).
if pkg_a.name == pkg_b.name {
+ if self.prefer_stable {
+ let stab_a = stability_priority(&pkg_a.version);
+ let stab_b = stability_priority(&pkg_b.version);
+ if stab_a != stab_b {
+ return stab_a.cmp(&stab_b);
+ }
+ }
let cmp = self.compare_versions(&pkg_a.version, &pkg_b.version);
return if self.prefer_lowest {
cmp
@@ -111,6 +123,37 @@ impl Default for DefaultPolicy {
}
}
+/// Map a normalized version string to Composer's stability priority
+/// (`BasePackage::STABILITIES`). Lower = more stable. Stable=0, RC=5, beta=10,
+/// alpha=15, dev=20. Mirrors `DefaultPolicy::versionCompare`'s comparison
+/// when `prefer_stable` is set.
+fn stability_priority(version: &str) -> u8 {
+ let Ok(v) = mozart_semver::Version::parse(version) else {
+ return 0;
+ };
+ if v.is_dev_branch {
+ return 20;
+ }
+ match v.pre_release.as_deref() {
+ None => 0,
+ Some(pre) => {
+ let lower = pre.to_lowercase();
+ if lower.starts_with("dev") {
+ 20
+ } else if lower.starts_with("alpha") || lower == "a" {
+ 15
+ } else if lower.starts_with("beta") || lower == "b" {
+ 10
+ } else if lower.starts_with("rc") {
+ 5
+ } else {
+ // patch/pl/p / unknown → stable
+ 0
+ }
+ }
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -126,6 +169,7 @@ mod tests {
provides: vec![],
conflicts: vec![],
is_fixed: false,
+ is_alias_of: None,
}
}