Skip to content

Commit 9bfe650

Browse files
committed
fix: replace custom version comparison with ALPM Library
- requires libalpm from pacman package
1 parent c9c499f commit 9bfe650

File tree

4 files changed

+47
-33
lines changed

4 files changed

+47
-33
lines changed

Cargo.lock

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ path = "src/main.rs"
1616
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1717

1818
[dependencies]
19+
alpm = "4.0"
1920
lazy_static = "1.4"
2021
lenient_semver = "0.4.2"
2122
ureq = { version = "2.10", features = ["json"] }

src/lib.rs

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,15 @@
11
pub mod version_utils {
2+
use alpm::vercmp;
23
use lenient_semver;
4+
use std::cmp::Ordering;
35

4-
// Helper function to compare versions properly
6+
// Helper function to compare versions using ALPM's vercmp for production consistency
57
pub fn is_version_newer(aur_version: &str, local_version: &str) -> bool {
6-
// Handle git packages with revision numbers (e.g., "r89.fe26a90-1" or "-r89.fe26a90-1")
7-
let extract_git_revision = |version: &str| -> Option<u32> {
8-
if let Some(r_pos) = version.find('r') {
9-
let after_r = &version[r_pos + 1..];
10-
if let Some(dot_pos) = after_r.find('.') {
11-
if let Ok(rev) = after_r[..dot_pos].parse() {
12-
return Some(rev);
13-
}
14-
}
15-
}
16-
None
17-
};
18-
19-
// If both versions have git revision numbers, compare them
20-
if let (Some(aur_rev), Some(local_rev)) = (
21-
extract_git_revision(aur_version),
22-
extract_git_revision(local_version),
23-
) {
24-
return aur_rev > local_rev;
25-
}
26-
27-
// Fall back to semantic version comparison
28-
match (
29-
lenient_semver::parse(aur_version),
30-
lenient_semver::parse(local_version),
31-
) {
32-
(Ok(aur_semver), Ok(local_semver)) => aur_semver > local_semver,
33-
// If semantic parsing fails, fall back to string comparison
34-
// but only show as update if strings are different (conservative approach)
35-
_ => aur_version != local_version && aur_version > local_version,
8+
// Use ALPM's vercmp which follows Arch Linux's official version comparison algorithm
9+
// vercmp returns Ordering::Greater if aur_version is newer than local_version
10+
match vercmp(aur_version, local_version) {
11+
Ordering::Greater => true,
12+
_ => false,
3613
}
3714
}
3815

tests/unit_tests.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@ fn test_version_comparison_git_revisions() {
1414
assert!(is_version_newer("r100.abc123-1", "r99.def456-1"));
1515
assert!(!is_version_newer("r99.abc123-1", "r100.def456-1"));
1616
assert!(!is_version_newer("r100.abc123-1", "r100.def456-1"));
17+
assert!(is_version_newer(
18+
"0.48.0.r62.gd775686-1",
19+
"0.47.0.r63.ccdddddd-2"
20+
));
1721
}
1822

1923
#[test]
2024
fn test_version_comparison_mixed() {
2125
assert!(is_version_newer("1.2.1-r50.abc123", "1.2.0"));
22-
assert!(!is_version_newer("2.0.0", "r100.abc123-1")); // semantic vs git revision - should be false
23-
assert!(is_version_newer("r101.abc123-1", "1.2.0")); // git revision vs semantic - string comparison
26+
assert!(is_version_newer("2.0.0", "r100.abc123-1")); // ALPM: semantic version is newer than git revision
27+
assert!(!is_version_newer("r101.abc123-1", "1.2.0")); // ALPM: git revision is older than semantic version
2428
}
2529

2630
#[test]

0 commit comments

Comments
 (0)