Repository: conan-io/conan
Pull request #15653 (2024-02-12 20:36:16)

To check what to do with version build metadata and prereleases
Changelog: Bugfix: Fix version precendence for metadata version ranges
Docs: Omit

I suspect more things are still needed



Patch:
diff --git a/conans/model/version_range.py b/conans/model/version_range.py
index 4360758a1..97778f68c 100644
--- a/conans/model/version_range.py
+++ b/conans/model/version_range.py
@@ -12,7 +12,7 @@ class _Condition:
         self.display_version = version
 
         value = str(version)
-        if (operator == ">=" or operator == "<") and "-" not in value:
+        if (operator == ">=" or operator == "<") and "-" not in value and version.build is None:
             value += "-"
         self.version = Version(value)
 


Test patch:
diff --git a/conans/test/unittests/model/version/test_version_comparison.py b/conans/test/unittests/model/version/test_version_comparison.py
index 27f52f75a..da480377e 100644
--- a/conans/test/unittests/model/version/test_version_comparison.py
+++ b/conans/test/unittests/model/version/test_version_comparison.py
@@ -59,6 +59,13 @@ v = [("1", "2"),
      ("0.0.1-3-1", "0.0.1"),
      ("0.0.1-3-1", "0.0.1-4"),
      ("0.0.1-3", "0.0.1-3-1"),  # 3 is less than 3-1, pure alphanumeric ID "3-1"
+     # build + prerelease
+     ("1.1-pre.1", "1.1+b.1"),
+     ("1.1-pre.1", "1.1-pre.1+b.1"),
+     ("1.1-pre.1+b.1", "1.1-pre.1+b.2"),
+     ("1.1+b.1", "1.2-pre.1+b.2"),
+     ("1.0.0-+2", "1.0.0+2"),  # Note it is not the number, but the prerelease
+     ("1.0.0-+2", "1.0.0+1"),  # Even if the build metadata is lower the first one is pre-release
      # cci. schema used in CCI
      ("cci.20230101", "cci.20240101"),
      ]
diff --git a/conans/test/unittests/model/version/test_version_range.py b/conans/test/unittests/model/version/test_version_range.py
index 3d45847a2..263caf65f 100644
--- a/conans/test/unittests/model/version/test_version_range.py
+++ b/conans/test/unittests/model/version/test_version_range.py
@@ -35,9 +35,19 @@ values = [
                            ["1.0", "1.2", "3.3"],  ["1-pre.1", "1.5-a1", "3.3-a1"]],
     ['^1.1.2',  [[['>=', '1.1.2-'], ['<', '2.0.0-']]], ["1.2.3"],  ["1.2.0-alpha1", "2.0.0-alpha1"]],
     ['~1.1.2',  [[['>=', '1.1.2-'], ['<', '1.2.0-']]], ["1.1.3"],  ["1.1.3-alpha1", "1.2.0-alpha1"]],
-    ['>=2.0-pre.0 <3', [[['>=', '2.0-pre.0'], ['<', '3-']]], ["2.1"], ["2.0-pre.1","2.0-alpha.1"]],
+    ['>=2.0-pre.0 <3', [[['>=', '2.0-pre.0'], ['<', '3-']]], ["2.1"], ["2.0-pre.1", "2.0-alpha.1"]],
+    # Build metadata
+    ['>=1.0.0+2', [[['>=', '1.0.0+2']]], ["1.0.0+2", "1.0.0+3"], ["1.0.0+1"]],
+    ['>=1.0.0', [[['>=', '1.0.0-']]], ["1.0.0+2", "1.0.0+3"], []],
+    # Build metadata and pre-releases
+    ['>=1.0.0-pre.1+2', [[['>=', '1.0.0-pre.1+2']]], ["1.0.0+1", "1.0.0+2"], ["1.0.0-pre.1+3"]], # excluded 1+3 because is a pre-release!
+    ['>=1.0.0-pre.1+2, include_prerelease=True', [[['>=', '1.0.0-pre.1+2']]], ["1.0.0+1", "1.0.0+2", "1.0.0-pre.1+3"], ["1.0.0-pre.1+1"]],
+    ['<1.0.1-pre.1+2', [[['<', '1.0.1-pre.1+2']]], ["1.0.0+1", "1.0.0+2"], ["1.0.0-pre.1+2"]],
+    ['<1.0.1-pre.1+2, include_prerelease=True', [[['<', '1.0.1-pre.1+2']]], ["1.0.0+1", "1.0.0+2", "1.0.1-pre.1+1"], ["1.0.1-pre.1+2"]],
     # Or explicitly
-    ['>=2.0-pre.0, include_prerelease', [[['>=', '2.0-pre.0']]], ["2.1", "2.0-pre.1"], ["1.5"]]
+    ['>=2.0-pre.0, include_prerelease', [[['>=', '2.0-pre.0']]], ["2.1", "2.0-pre.1"], ["1.5"]],
+    # Build metadata
+    ['>=1.0.0+2', [[['>=', '1.0.0+2']]], ["1.0.0+2", "1.0.0+3"], ["1.0.0+1"]],
 ]