summaryrefslogtreecommitdiff
path: root/osc/util/debquery.py
diff options
context:
space:
mode:
authorMichal Čihař <nijel@debian.org>2019-02-17 09:12:42 +0100
committerMichal Čihař <nijel@debian.org>2019-02-17 09:12:42 +0100
commitd0395582092c53d328a3071878a9327894ef1284 (patch)
tree3b3c955a2dbbb59ab22071e3ecaa6722fb45f252 /osc/util/debquery.py
parent3443a428fefbd5715c8cd5f7c967e9d0db51446f (diff)
New upstream version 0.164.2
Diffstat (limited to 'osc/util/debquery.py')
-rw-r--r--osc/util/debquery.py131
1 files changed, 78 insertions, 53 deletions
diff --git a/osc/util/debquery.py b/osc/util/debquery.py
index 4c2e0e5..3d56880 100644
--- a/osc/util/debquery.py
+++ b/osc/util/debquery.py
@@ -5,8 +5,10 @@ from . import ar
import os.path
import re
import tarfile
-import StringIO
+from io import BytesIO
from . import packagequery
+import itertools
+
HAVE_LZMA = True
try:
@@ -14,13 +16,21 @@ try:
except ImportError:
HAVE_LZMA = False
+
+if (not hasattr(itertools, 'zip_longest')
+ and hasattr(itertools, 'izip_longest')):
+ # python2 case
+ itertools.zip_longest = itertools.izip_longest
+
+
class DebError(packagequery.PackageError):
pass
class DebQuery(packagequery.PackageQuery, packagequery.PackageQueryResult):
- default_tags = ('package', 'version', 'release', 'epoch', 'architecture', 'description',
- 'provides', 'depends', 'pre_depends', 'conflicts', 'breaks')
+ default_tags = (b'package', b'version', b'release', b'epoch',
+ b'architecture', b'description', b'provides', b'depends',
+ b'pre_depends', b'conflicts', b'breaks')
def __init__(self, fh):
self.__file = fh
@@ -31,24 +41,24 @@ class DebQuery(packagequery.PackageQuery, packagequery.PackageQueryResult):
def read(self, all_tags=False, self_provides=True, *extra_tags):
arfile = ar.Ar(fh = self.__file)
arfile.read()
- debbin = arfile.get_file('debian-binary')
+ debbin = arfile.get_file(b'debian-binary')
if debbin is None:
raise DebError(self.__path, 'no debian binary')
- if debbin.read() != '2.0\n':
+ if debbin.read() != b'2.0\n':
raise DebError(self.__path, 'invalid debian binary format')
- control = arfile.get_file('control.tar.gz')
+ control = arfile.get_file(b'control.tar.gz')
if control is not None:
# XXX: python2.4 relies on a name
tar = tarfile.open(name='control.tar.gz', fileobj=control)
else:
- control = arfile.get_file('control.tar.xz')
+ control = arfile.get_file(b'control.tar.xz')
if control is None:
raise DebError(self.__path, 'missing control.tar')
if not HAVE_LZMA:
raise DebError(self.__path, 'can\'t open control.tar.xz without python-lzma')
decompressed = lzma.decompress(control.read())
tar = tarfile.open(name="control.tar.xz",
- fileobj=StringIO.StringIO(decompressed))
+ fileobj=BytesIO(decompressed))
try:
name = './control'
# workaround for python2.4's tarfile module
@@ -64,94 +74,98 @@ class DebQuery(packagequery.PackageQuery, packagequery.PackageQueryResult):
def __parse_control(self, control, all_tags=False, self_provides=True, *extra_tags):
data = control.readline().strip()
while data:
- field, val = re.split(':\s*', data.strip(), 1)
+ field, val = re.split(b':\s*', data.strip(), 1)
data = control.readline()
- while data and re.match('\s+', data):
- val += '\n' + data.strip()
+ while data and re.match(b'\s+', data):
+ val += b'\n' + data.strip()
data = control.readline().rstrip()
- field = field.replace('-', '_').lower()
+ field = field.replace(b'-', b'_').lower()
if field in self.default_tags + extra_tags or all_tags:
# a hyphen is not allowed in dict keys
self.fields[field] = val
- versrel = self.fields['version'].rsplit('-', 1)
+ versrel = self.fields[b'version'].rsplit(b'-', 1)
if len(versrel) == 2:
- self.fields['version'] = versrel[0]
- self.fields['release'] = versrel[1]
+ self.fields[b'version'] = versrel[0]
+ self.fields[b'release'] = versrel[1]
else:
- self.fields['release'] = None
- verep = self.fields['version'].split(':', 1)
+ self.fields[b'release'] = None
+ verep = self.fields[b'version'].split(b':', 1)
if len(verep) == 2:
- self.fields['epoch'] = verep[0]
- self.fields['version'] = verep[1]
+ self.fields[b'epoch'] = verep[0]
+ self.fields[b'version'] = verep[1]
else:
- self.fields['epoch'] = '0'
- self.fields['provides'] = [ i.strip() for i in re.split(',\s*', self.fields.get('provides', '')) if i ]
- self.fields['depends'] = [ i.strip() for i in re.split(',\s*', self.fields.get('depends', '')) if i ]
- self.fields['pre_depends'] = [ i.strip() for i in re.split(',\s*', self.fields.get('pre_depends', '')) if i ]
- self.fields['conflicts'] = [ i.strip() for i in re.split(',\s*', self.fields.get('conflicts', '')) if i ]
- self.fields['breaks'] = [ i.strip() for i in re.split(',\s*', self.fields.get('breaks', '')) if i ]
- self.fields['recommends'] = [ i.strip() for i in re.split(',\s*', self.fields.get('recommends', '')) if i ]
- self.fields['suggests'] = [ i.strip() for i in re.split(',\s*', self.fields.get('suggests', '')) if i ]
- self.fields['enhances'] = [ i.strip() for i in re.split(',\s*', self.fields.get('enhances', '')) if i ]
+ self.fields[b'epoch'] = b'0'
+ self.fields[b'provides'] = self._split_field_value(b'provides')
+ self.fields[b'depends'] = self._split_field_value(b'depends')
+ self.fields[b'pre_depends'] = self._split_field_value(b'pre_depends')
+ self.fields[b'conflicts'] = self._split_field_value(b'conflicts')
+ self.fields[b'breaks'] = self._split_field_value(b'breaks')
+ self.fields[b'recommends'] = self._split_field_value(b'recommends')
+ self.fields[b'suggests'] = self._split_field_value(b'suggests')
+ self.fields[b'enhances'] = self._split_field_value(b'enhances')
if self_provides:
# add self provides entry
- self.fields['provides'].append('%s (= %s)' % (self.name(), '-'.join(versrel)))
+ self.fields[b'provides'].append(b'%s (= %s)' % (self.name(), b'-'.join(versrel)))
+
+ def _split_field_value(self, field, delimeter=b',\s*'):
+ return [i.strip()
+ for i in re.split(delimeter, self.fields.get(field, b'')) if i]
def vercmp(self, debq):
- res = cmp(int(self.epoch()), int(debq.epoch()))
+ res = packagequery.cmp(int(self.epoch()), int(debq.epoch()))
if res != 0:
return res
res = DebQuery.debvercmp(self.version(), debq.version())
- if res != None:
+ if res != 0:
return res
res = DebQuery.debvercmp(self.release(), debq.release())
return res
def name(self):
- return self.fields['package']
+ return self.fields[b'package']
def version(self):
- return self.fields['version']
+ return self.fields[b'version']
def release(self):
- return self.fields['release']
+ return self.fields[b'release']
def epoch(self):
- return self.fields['epoch']
+ return self.fields[b'epoch']
def arch(self):
- return self.fields['architecture']
+ return self.fields[b'architecture']
def description(self):
- return self.fields['description']
+ return self.fields[b'description']
def path(self):
return self.__path
def provides(self):
- return self.fields['provides']
+ return self.fields[b'provides']
def requires(self):
- return self.fields['depends'] + self.fields['pre_depends']
+ return self.fields[b'depends'] + self.fields[b'pre_depends']
def conflicts(self):
- return self.fields['conflicts'] + self.fields['breaks']
+ return self.fields[b'conflicts'] + self.fields[b'breaks']
def obsoletes(self):
return []
def recommends(self):
- return self.fields['recommends']
+ return self.fields[b'recommends']
def suggests(self):
- return self.fields['suggests']
+ return self.fields[b'suggests']
def supplements(self):
# a control file has no notion of "supplements"
return []
def enhances(self):
- return self.fields['enhances']
+ return self.fields[b'enhances']
def gettag(self, num):
return self.fields.get(num, None)
@@ -174,20 +188,31 @@ class DebQuery(packagequery.PackageQuery, packagequery.PackageQueryResult):
"""
# 32 is arbitrary - it is needed for the "longer digit string wins" handling
# (found this nice approach in Build/Deb.pm (build package))
- ver1 = re.sub('(\d+)', lambda m: (32 * '0' + m.group(1))[-32:], ver1)
- ver2 = re.sub('(\d+)', lambda m: (32 * '0' + m.group(1))[-32:], ver2)
- vers = map(lambda x, y: (x or '', y or ''), ver1, ver2)
+ ver1 = re.sub(b'(\d+)', lambda m: (32 * b'0' + m.group(1))[-32:], ver1)
+ ver2 = re.sub(b'(\d+)', lambda m: (32 * b'0' + m.group(1))[-32:], ver2)
+ vers = itertools.zip_longest(ver1, ver2, fillvalue=b'')
for v1, v2 in vers:
if v1 == v2:
continue
+ if not v1:
+ # this makes the corresponding condition in the following
+ # else part superfluous - keep the superfluous condition for
+ # now (just to ease a (hopefully) upcoming refactoring (this
+ # method really deserves a cleanup...))
+ return -1
+ if not v2:
+ # see above
+ return 1
+ v1 = bytes(bytearray([v1]))
+ v2 = bytes(bytearray([v2]))
if (v1.isalpha() and v2.isalpha()) or (v1.isdigit() and v2.isdigit()):
- res = cmp(v1, v2)
+ res = packagequery.cmp(v1, v2)
if res != 0:
return res
else:
- if v1 == '~' or not v1:
+ if v1 == b'~' or not v1:
return -1
- elif v2 == '~' or not v2:
+ elif v2 == b'~' or not v2:
return 1
ord1 = ord(v1)
if not (v1.isalpha() or v1.isdigit()):
@@ -204,9 +229,9 @@ class DebQuery(packagequery.PackageQuery, packagequery.PackageQueryResult):
@staticmethod
def filename(name, epoch, version, release, arch):
if release:
- return '%s_%s-%s_%s.deb' % (name, version, release, arch)
+ return b'%s_%s-%s_%s.deb' % (name, version, release, arch)
else:
- return '%s_%s_%s.deb' % (name, version, arch)
+ return b'%s_%s_%s.deb' % (name, version, arch)
if __name__ == '__main__':
import sys
@@ -218,6 +243,6 @@ if __name__ == '__main__':
print(debq.name(), debq.version(), debq.release(), debq.arch())
print(debq.description())
print('##########')
- print('\n'.join(debq.provides()))
+ print(b'\n'.join(debq.provides()))
print('##########')
- print('\n'.join(debq.requires()))
+ print(b'\n'.join(debq.requires()))