diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-10 00:32:08 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-10 00:32:08 +0900 |
| commit | 8cc1ba8a02c0318b65658f1634de378c780392b9 (patch) | |
| tree | fdd5cb61e488018891a486b25991b87c84220bb8 /crates/mozart-registry/src/version.rs | |
| parent | 72b2e877c01e67ba7edd37e34ac2eadb7a1c62c4 (diff) | |
| download | php-mozart-8cc1ba8a02c0318b65658f1634de378c780392b9.tar.gz php-mozart-8cc1ba8a02c0318b65658f1634de378c780392b9.tar.zst php-mozart-8cc1ba8a02c0318b65658f1634de378c780392b9.zip | |
refactor(workspace): consolidate crates into mozart-core
Merged mozart-archiver, mozart-autoload, mozart-registry,
mozart-sat-resolver, and mozart-vcs into mozart-core to align
the source layout with Composer's structure.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart-registry/src/version.rs')
| -rw-r--r-- | crates/mozart-registry/src/version.rs | 269 |
1 files changed, 0 insertions, 269 deletions
diff --git a/crates/mozart-registry/src/version.rs b/crates/mozart-registry/src/version.rs deleted file mode 100644 index 9a7c6e6..0000000 --- a/crates/mozart-registry/src/version.rs +++ /dev/null @@ -1,269 +0,0 @@ -use crate::packagist::PackagistVersion; -use mozart_core::package::Stability; -use std::cmp::Ordering; - -/// Determine the stability of a normalized version string. -pub fn stability_of(version_normalized: &str) -> Stability { - let v = version_normalized.to_lowercase(); - if v.starts_with("dev-") || v.ends_with("-dev") { - return Stability::Dev; - } - // Check for pre-release suffixes: alpha, beta, RC - // Normalized versions use formats like "1.0.0.0-alpha1", "1.0.0.0-beta2", "1.0.0.0-RC1" - if let Some(pos) = v.rfind('-') { - let suffix = &v[pos + 1..]; - if suffix.starts_with("alpha") { - return Stability::Alpha; - } - if suffix.starts_with("beta") { - return Stability::Beta; - } - if suffix.starts_with("rc") || suffix.starts_with("RC") { - return Stability::RC; - } - } - Stability::Stable -} - -/// Compare two normalized version strings (e.g. "1.2.3.0" vs "1.2.4.0"). -/// -/// Each version is split into numeric parts. Non-numeric suffixes (like "-beta1") -/// are handled by treating the base parts as numeric and the suffix separately. -pub fn compare_normalized_versions(a: &str, b: &str) -> Ordering { - let parse = |v: &str| -> (Vec<u64>, Option<String>) { - // Split off any pre-release suffix - let (base, suffix) = if let Some(pos) = v.find('-') { - (&v[..pos], Some(v[pos + 1..].to_string())) - } else { - (v, None) - }; - let parts: Vec<u64> = base.split('.').filter_map(|p| p.parse().ok()).collect(); - (parts, suffix) - }; - - let (a_parts, a_suffix) = parse(a); - let (b_parts, b_suffix) = parse(b); - - // Compare numeric parts - let max_len = a_parts.len().max(b_parts.len()); - for i in 0..max_len { - let a_val = a_parts.get(i).copied().unwrap_or(0); - let b_val = b_parts.get(i).copied().unwrap_or(0); - match a_val.cmp(&b_val) { - Ordering::Equal => continue, - other => return other, - } - } - - // If numeric parts are equal, compare stability - // A stable version (no suffix) is greater than a pre-release - match (&a_suffix, &b_suffix) { - (None, None) => Ordering::Equal, - (None, Some(_)) => Ordering::Greater, // stable > pre-release - (Some(_), None) => Ordering::Less, // pre-release < stable - (Some(a_s), Some(b_s)) => { - let stab_a = stability_of(&format!("0.0.0.0-{a_s}")); - let stab_b = stability_of(&format!("0.0.0.0-{b_s}")); - // Lower stability value = more stable = greater version - match stab_a.cmp(&stab_b) { - Ordering::Equal => a_s.cmp(b_s), - // Stability enum: Stable(0) < RC(5) < Beta(10) < Alpha(15) < Dev(20) - // But more stable = higher version, so we reverse - Ordering::Less => Ordering::Greater, - Ordering::Greater => Ordering::Less, - } - } - } -} - -/// Find the best version candidate given a preferred minimum stability. -/// -/// Returns the highest version whose stability is at least as stable as -/// the preferred stability (i.e., stability value <= preferred value). -pub fn find_best_candidate( - versions: &[PackagistVersion], - preferred_stability: Stability, -) -> Option<&PackagistVersion> { - versions - .iter() - .filter(|v| stability_of(&v.version_normalized) <= preferred_stability) - .max_by(|a, b| compare_normalized_versions(&a.version_normalized, &b.version_normalized)) -} - -/// Generate a recommended version constraint string from a concrete version. -/// -/// Examples: -/// - `"1.2.1"` (stable) → `"^1.2"` -/// - `"0.3.5"` (stable) → `"^0.3"` -/// - `"2.0.0-beta.1"` (beta) → `"^2.0@beta"` -/// - `"dev-master"` (dev) → `"dev-master"` -pub fn find_recommended_require_version( - version: &str, - version_normalized: &str, - stability: Stability, -) -> String { - // dev branches are returned as-is - if stability == Stability::Dev { - return version.to_string(); - } - - // Extract major.minor from the normalized version (e.g. "1.2.3.0" → "1.2") - let base = if let Some(pos) = version_normalized.find('-') { - &version_normalized[..pos] - } else { - version_normalized - }; - - let parts: Vec<&str> = base.split('.').collect(); - let major = parts.first().copied().unwrap_or("0"); - let minor = parts.get(1).copied().unwrap_or("0"); - - let constraint = format!("^{major}.{minor}"); - - match stability { - Stability::Stable => constraint, - Stability::RC => format!("{constraint}@RC"), - Stability::Beta => format!("{constraint}@beta"), - Stability::Alpha => format!("{constraint}@alpha"), - Stability::Dev => format!("{constraint}@dev"), - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_stability_of() { - assert_eq!(stability_of("1.0.0.0"), Stability::Stable); - assert_eq!(stability_of("2.3.1.0"), Stability::Stable); - assert_eq!(stability_of("1.0.0.0-alpha1"), Stability::Alpha); - assert_eq!(stability_of("1.0.0.0-beta2"), Stability::Beta); - assert_eq!(stability_of("1.0.0.0-RC1"), Stability::RC); - assert_eq!(stability_of("dev-master"), Stability::Dev); - assert_eq!(stability_of("dev-feature/foo"), Stability::Dev); - assert_eq!(stability_of("1.0.0.0-dev"), Stability::Dev); - } - - #[test] - fn test_compare_normalized_versions() { - assert_eq!( - compare_normalized_versions("1.0.0.0", "1.0.0.0"), - Ordering::Equal - ); - assert_eq!( - compare_normalized_versions("2.0.0.0", "1.0.0.0"), - Ordering::Greater - ); - assert_eq!( - compare_normalized_versions("1.0.0.0", "2.0.0.0"), - Ordering::Less - ); - assert_eq!( - compare_normalized_versions("1.2.0.0", "1.1.0.0"), - Ordering::Greater - ); - assert_eq!( - compare_normalized_versions("1.0.0.0", "1.0.0.0-beta1"), - Ordering::Greater - ); - assert_eq!( - compare_normalized_versions("1.0.0.0-RC1", "1.0.0.0-beta1"), - Ordering::Greater - ); - } - - fn make_pv(version: &str, version_normalized: &str) -> PackagistVersion { - PackagistVersion { - version: version.to_string(), - version_normalized: version_normalized.to_string(), - require: Default::default(), - replace: Default::default(), - provide: Default::default(), - conflict: Default::default(), - dist: None, - source: None, - require_dev: Default::default(), - suggest: None, - package_type: None, - autoload: None, - autoload_dev: None, - license: None, - description: None, - homepage: None, - keywords: None, - authors: None, - support: None, - funding: None, - time: None, - extra: None, - notification_url: None, - default_branch: false, - abandoned: None, - } - } - - #[test] - fn test_find_best_candidate_stable() { - let versions = vec![ - make_pv("dev-master", "dev-master"), - make_pv("2.0.0-beta.1", "2.0.0.0-beta1"), - make_pv("1.5.0", "1.5.0.0"), - make_pv("1.4.0", "1.4.0.0"), - ]; - - let best = find_best_candidate(&versions, Stability::Stable).unwrap(); - assert_eq!(best.version, "1.5.0"); - } - - #[test] - fn test_find_best_candidate_beta() { - let versions = vec![ - make_pv("dev-master", "dev-master"), - make_pv("2.0.0-beta.1", "2.0.0.0-beta1"), - make_pv("1.5.0", "1.5.0.0"), - ]; - - let best = find_best_candidate(&versions, Stability::Beta).unwrap(); - assert_eq!(best.version, "2.0.0-beta.1"); - } - - #[test] - fn test_find_best_candidate_no_match() { - let versions = vec![make_pv("dev-master", "dev-master")]; - - let best = find_best_candidate(&versions, Stability::Stable); - assert!(best.is_none()); - } - - #[test] - fn test_find_recommended_require_version() { - // Stable - assert_eq!( - find_recommended_require_version("1.2.1", "1.2.1.0", Stability::Stable), - "^1.2" - ); - assert_eq!( - find_recommended_require_version("0.3.5", "0.3.5.0", Stability::Stable), - "^0.3" - ); - - // Beta - assert_eq!( - find_recommended_require_version("2.0.0-beta.1", "2.0.0.0-beta1", Stability::Beta), - "^2.0@beta" - ); - - // RC - assert_eq!( - find_recommended_require_version("3.0.0-RC1", "3.0.0.0-RC1", Stability::RC), - "^3.0@RC" - ); - - // Dev - assert_eq!( - find_recommended_require_version("dev-master", "dev-master", Stability::Dev), - "dev-master" - ); - } -} |
