Prechádzať zdrojové kódy

fix: version ordering ignores components beyond the shorter version

greater_than/less_than compared only the shared prefix, so 0.1.1 vs 0.1
read as equal and usm update reported 'All installed packages are up to
date' against listings carrying newer versions. Missing components now
count as zero: trailing zeros stay equal (0.1 == 0.1.0) while extra
non-zero components order (0.1.1 > 0.1). Ten ordering regression tests.
clanker 1 mesiac pred
rodič
commit
b57c701b54
2 zmenil súbory, kde vykonal 51 pridanie a 6 odobranie
  1. 37 6
      src/lib/Version.vala
  2. 14 0
      src/tests/TestMain.vala

+ 37 - 6
src/lib/Version.vala

@@ -81,12 +81,28 @@ namespace Usm {
         }
 
         public bool greater_than(Version other) {
-            var parts = int.min(other.version_nums.length, version_nums.length);
+            var mine = version_nums ?? new int[0];
+            var theirs = other.version_nums ?? new int[0];
+            var parts = int.min(theirs.length, mine.length);
             for(int i = 0; i < parts; i++) {
-                if(version_nums[i] > other.version_nums[i]) {
+                if(mine[i] > theirs[i]) {
+                    return true;
+                }
+                if(mine[i] < theirs[i]) {
+                    return false;
+                }
+            }
+            // Components only one side has count as zero, so trailing zeros
+            // stay equal (0.1 == 0.1.0) but extra non-zero components make
+            // the longer version newer (0.1.1 > 0.1)
+            var longest = int.max(theirs.length, mine.length);
+            for(int i = parts; i < longest; i++) {
+                var mine_component = i < mine.length ? mine[i] : 0;
+                var theirs_component = i < theirs.length ? theirs[i] : 0;
+                if(mine_component > theirs_component) {
                     return true;
                 }
-                if(version_nums[i] < other.version_nums[i]) {
+                if(mine_component < theirs_component) {
                     return false;
                 }
             }
@@ -104,12 +120,27 @@ namespace Usm {
         }
 
         public bool less_than(Version other) {
-            var parts = int.min(other.version_nums.length, version_nums.length);
+            var mine = version_nums ?? new int[0];
+            var theirs = other.version_nums ?? new int[0];
+            var parts = int.min(theirs.length, mine.length);
             for(int i = 0; i < parts; i++) {
-                if(version_nums[i] < other.version_nums[i]) {
+                if(mine[i] < theirs[i]) {
+                    return true;
+                }
+                if(mine[i] > theirs[i]) {
+                    return false;
+                }
+            }
+            // Components only one side has count as zero, mirroring
+            // {@link greater_than}
+            var longest = int.max(theirs.length, mine.length);
+            for(int i = parts; i < longest; i++) {
+                var mine_component = i < mine.length ? mine[i] : 0;
+                var theirs_component = i < theirs.length ? theirs[i] : 0;
+                if(mine_component < theirs_component) {
                     return true;
                 }
-                if(version_nums[i] > other.version_nums[i]) {
+                if(mine_component > theirs_component) {
                     return false;
                 }
             }

+ 14 - 0
src/tests/TestMain.vala

@@ -466,6 +466,19 @@ namespace Usm.Tests {
         check(rejected.count() == 0, @"malformed constraints are rejected ($(rejected.to_string(s => s, ", ")))");
     }
 
+    void test_version_ordering() throws Error {
+        check(version("0.1.1").greater_than(version("0.1")), "extra non-zero component is newer (0.1.1 > 0.1)");
+        check(version("0.1").less_than(version("0.1.1")), "fewer components is older (0.1 < 0.1.1)");
+        check(version("0.1.0").compare(version("0.1")) == 0, "trailing zero components stay equal (0.1 == 0.1.0)");
+        check(!version("0.1").greater_than(version("0.1.0")), "trailing zero components do not order (0.1 !> 0.1.0)");
+        check(version("1.0.0.1").greater_than(version("1.0")), "extra component wins at any depth");
+        check(version("0.2").greater_than(version("0.1.1")), "shared-prefix difference dominates component count");
+        check(version("0.1+1").greater_than(version("0.1")), "release suffix still beats release-less");
+        check(version("0.1.1+1").greater_than(version("0.1.1")), "release breaks numeric ties");
+        check(version("0.1.1").greater_than(version("0.1+5")), "non-zero component beats any release of the shorter version");
+        check(version("0.1").compare(version("0.1")) == 0, "identical versions compare equal");
+    }
+
     void test_resource_ref_operator_parsing() throws Error {
         var constrained = new Usm.ResourceRef("lib:libcmark.so.0>=0.30.0");
         check(constrained.base_name == "libcmark.so.0", "base name drops the constraint");
@@ -2418,6 +2431,7 @@ echo "Installing libmeson-pkg.so to /usr/lib"
 
         try {
             test_version_constraint_semantics();
+            test_version_ordering();
             test_resource_ref_operator_parsing();
             test_depends_operator_type_rules();
             test_provides_declaration_rules();