mirror of
https://github.com/openSUSE/osc.git
synced 2024-11-14 00:06:15 +01:00
- util/rpmquery.py: implemented RPM's version comparison algorithm as described in rpmio/rpmvercmp.c
- util/packagequery.py: added vercmp(pkgq) method - util/debquery.py: currently vercmp(degq) is only a dummy method. The real implementation will follow soon.
This commit is contained in:
parent
cc6d7413fb
commit
8c14808dd1
@ -52,6 +52,10 @@ class DebQuery(packagequery.PackageQuery):
|
||||
# add self provides entry
|
||||
self.fields['provides'].append('%s = %s' % (self.name(), '-'.join(versrel)))
|
||||
|
||||
def vercmp(self, debq):
|
||||
# XXX: just a dummy - the implementation will follow soon
|
||||
return 0
|
||||
|
||||
def name(self):
|
||||
return self.fields['package']
|
||||
|
||||
|
@ -33,6 +33,9 @@ class PackageQuery:
|
||||
def getTag(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def vercmp(self, pkgq):
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def query(filename):
|
||||
f = open(filename, 'rb')
|
||||
|
@ -1,4 +1,5 @@
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
import packagequery
|
||||
|
||||
@ -157,6 +158,16 @@ class RpmQuery(packagequery.PackageQuery):
|
||||
res.append(name)
|
||||
return res
|
||||
|
||||
def vercmp(self, rpmq):
|
||||
res = RpmQuery.rpmvercmp(str(self.epoch()), str(rpmq.epoch()))
|
||||
if res != 0:
|
||||
return res
|
||||
res = RpmQuery.rpmvercmp(self.version(), rpmq.version())
|
||||
if res != 0:
|
||||
return res
|
||||
res = RpmQuery.rpmvercmp(self.release(), rpmq.release())
|
||||
return res
|
||||
|
||||
# XXX: create dict for the tag => number mapping?!
|
||||
def name(self):
|
||||
return self.header.getTag(1000).data
|
||||
@ -167,6 +178,12 @@ class RpmQuery(packagequery.PackageQuery):
|
||||
def release(self):
|
||||
return self.header.getTag(1002).data
|
||||
|
||||
def epoch(self):
|
||||
epoch = self.header.getTag(1003)
|
||||
if epoch is None:
|
||||
return 0
|
||||
return epoch.data[0]
|
||||
|
||||
def arch(self):
|
||||
return self.header.getTag(1022).data
|
||||
|
||||
@ -199,6 +216,53 @@ class RpmQuery(packagequery.PackageQuery):
|
||||
f.close()
|
||||
return rpmq
|
||||
|
||||
@staticmethod
|
||||
def rpmvercmp(ver1, ver2):
|
||||
"""
|
||||
implementation of RPM's version comparison algorithm
|
||||
(as described in rpmio/rpmvercmp.c)
|
||||
"""
|
||||
if ver1 == ver2:
|
||||
return 0
|
||||
res = 0
|
||||
while res == 0:
|
||||
# remove all leading non alphanumeric chars
|
||||
ver1 = re.sub('^[^a-zA-z0-9]*', '', ver1)
|
||||
ver2 = re.sub('^[^a-zA-z0-9]*', '', ver2)
|
||||
if not (len(ver1) and len(ver2)):
|
||||
break
|
||||
# check if we have a digits segment
|
||||
mo1 = re.match('(\d+)', ver1)
|
||||
mo2 = re.match('(\d+)', ver2)
|
||||
numeric = True
|
||||
if mo1 is None:
|
||||
mo1 = re.match('([a-zA-Z]+)', ver1)
|
||||
mo2 = re.match('([a-zA-Z]+)', ver2)
|
||||
numeric = False
|
||||
# check for different types: alpha and numeric
|
||||
if mo2 is None:
|
||||
if numeric:
|
||||
return 1
|
||||
return -1
|
||||
seg1 = mo1.group(0)
|
||||
ver1 = ver1[mo1.end(0):]
|
||||
seg2 = mo2.group(1)
|
||||
ver2 = ver2[mo2.end(1):]
|
||||
if numeric:
|
||||
# remove leading zeros
|
||||
seg1 = re.sub('^0+', '', seg1)
|
||||
seg2 = re.sub('^0+', '', seg2)
|
||||
# longer digit segment wins - if both have the same length
|
||||
# a simple ascii compare decides
|
||||
res = len(seg1) - len(seg2) or cmp(seg1, seg2)
|
||||
else:
|
||||
res = cmp(seg1, seg2)
|
||||
if res > 0:
|
||||
return 1
|
||||
elif res < 0:
|
||||
return -1
|
||||
return cmp(ver1, ver2)
|
||||
|
||||
def unpack_string(data):
|
||||
"""unpack a '\\0' terminated string from data"""
|
||||
val = ''
|
||||
|
Loading…
Reference in New Issue
Block a user