summaryrefslogtreecommitdiff
path: root/version.py
diff options
context:
space:
mode:
Diffstat (limited to 'version.py')
-rw-r--r--version.py75
1 files changed, 75 insertions, 0 deletions
diff --git a/version.py b/version.py
new file mode 100644
index 0000000..1de0442
--- /dev/null
+++ b/version.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+#
+# Copyright © 2018-2020 Adélie Linux team. All rights reserved.
+# NCSA license.
+#
+import ctypes
+import enum
+import functools
+
+class APK_VER(enum.IntFlag):
+ UNKNOWN = 0
+ EQUAL = 1
+ LESS = 2
+ GREATER = 4
+ FUZZY = 8
+
+APK_OPS = {
+ ">=": APK_VER.GREATER | APK_VER.EQUAL,
+ "<=": APK_VER.LESS | APK_VER.EQUAL,
+ ">~": APK_VER.GREATER | APK_VER.EQUAL,
+ "<~": APK_VER.LESS | APK_VER.EQUAL,
+ ">": APK_VER.GREATER,
+ "<": APK_VER.LESS,
+ "=": APK_VER.EQUAL,
+ "~": APK_VER.EQUAL,
+}
+
+class _apk_blob_t(ctypes.Structure):
+ _fields_ = [
+ ("len", ctypes.c_long),
+ ("ptr", ctypes.c_char_p),
+ ]
+
+ def __init__(self, s):
+ s = s.encode("utf-8")
+ self.len = len(s)
+ self.ptr = ctypes.c_char_p(s)
+
+def vercmp(a, b, fuzzy=False):
+ a = _apk_blob_t(a)
+ b = _apk_blob_t(b)
+ fuzzy = 1 if fuzzy else 0
+ return APK_VER(_LIBAPK.apk_version_compare_blob_fuzzy(a, b, fuzzy))
+
+@functools.cmp_to_key
+def verkey(a, b):
+ r = vercmp(a, b)
+
+ if r == APK_VER.LESS:
+ return -1
+ if r == APK_VER.EQUAL:
+ return 0
+ if r == APK_VER.GREATER:
+ return 1
+
+ return None
+
+def ver_is(a, op, b):
+ if op not in APK_OPS:
+ raise ValueError("Invalid op " + repr(op))
+
+ fuzzy = "~" in op
+ return vercmp(a, b, fuzzy) & APK_OPS[op]
+
+def is_older(old, new):
+ return vercmp(old, new) == APK_VER.LESS
+
+def is_same(old, new):
+ return vercmp(old, new) == APK_VER.EQUAL
+
+_LIBAPK = ctypes.CDLL("libapk.so")
+_LIBAPK.apk_version_compare_blob_fuzzy.argtypes = [
+ _apk_blob_t, _apk_blob_t, ctypes.c_int,
+]
+_LIBAPK.apk_version_compare_blob_fuzzy.restype = ctypes.c_int