1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-02-27 04:32:18 +01:00

support archlinux builds

This commit is contained in:
Michael Schroeder 2012-04-03 15:59:42 +02:00
parent c744710145
commit 8df38af7e3
5 changed files with 181 additions and 6 deletions

View File

@ -14,7 +14,7 @@ from tempfile import NamedTemporaryFile, mkdtemp
from osc.fetch import *
from osc.core import get_buildinfo, store_read_apiurl, store_read_project, store_read_package, meta_exists, quote_plus, get_buildconfig, is_package_dir
from osc.core import get_binarylist, get_binary_file
from osc.util import rpmquery, debquery
from osc.util import rpmquery, debquery, archquery
import osc.conf
import oscerr
import subprocess
@ -105,6 +105,8 @@ class Buildinfo:
self.pacsuffix = 'rpm'
if self.buildtype == 'dsc':
self.pacsuffix = 'deb'
if self.buildtype == 'arch':
self.pacsuffix = 'arch'
self.buildarch = root.find('arch').text
if root.find('hostarch') != None:
@ -199,6 +201,8 @@ class Pac:
if pacsuffix == 'deb':
filename = debquery.DebQuery.filename(self.mp['name'], self.mp['version'], self.mp['release'], self.mp['arch'])
elif pacsuffix == 'arch':
filename = archquery.ArchQuery.filename(self.mp['name'], self.mp['version'], self.mp['release'], self.mp['arch'])
else:
filename = rpmquery.RpmQuery.filename(self.mp['name'], self.mp['version'], self.mp['release'], self.mp['arch'])
@ -380,7 +384,9 @@ def main(apiurl, opts, argv):
build_descr = os.path.abspath(build_descr)
build_type = os.path.splitext(build_descr)[1][1:]
if build_type not in ['spec', 'dsc', 'kiwi']:
if os.path.basename(build_descr) == 'PKGBUILD':
build_type = 'arch'
if build_type not in ['spec', 'dsc', 'kiwi', 'arch']:
raise oscerr.WrongArgs(
'Unknown build type: \'%s\'. Build description should end in .spec, .dsc or .kiwi.' \
% build_type)

View File

@ -4862,7 +4862,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
arg_arch = arg_repository = arg_descr = None
if len(args) < 3:
for arg in args:
if arg.endswith('.spec') or arg.endswith('.dsc') or arg.endswith('.kiwi'):
if arg.endswith('.spec') or arg.endswith('.dsc') or arg.endswith('.kiwi') or os.path.basename(arg) == 'PKGBUILD':
arg_descr = arg
else:
if (arg in osc.build.can_also_build.get(osc.build.hostarch, [])

View File

@ -12,6 +12,7 @@ from util import packagequery, cpio
import conf
import oscerr
import tempfile
import re
try:
from meter import TextMeter
except:
@ -112,7 +113,8 @@ class Fetcher:
archive.copyin_file(hdr.filename)
raise oscerr.APIError('CPIO archive is incomplete (see .errors file)')
if package == '_repository':
pac = pkgs[hdr.filename.rsplit('.', 1)[0]]
n = re.sub(r'\.pkg\.tar\..z$', '.arch', hdr.filename)
pac = pkgs[n.rsplit('.', 1)[0]]
else:
# this is a kiwi product
pac = pkgs[hdr.filename]

164
osc/util/archquery.py Normal file
View File

@ -0,0 +1,164 @@
import os.path
import re
import tarfile
import packagequery
import subprocess
class ArchError(packagequery.PackageError):
pass
class ArchQuery(packagequery.PackageQuery):
def __init__(self, fh):
self.__file = fh
self.__path = os.path.abspath(fh.name)
self.fields = {}
#self.magic = None
#self.pkgsuffix = 'pkg.tar.gz'
self.pkgsuffix = 'arch'
def read(self, *extra_tags):
f = open(self.__path, 'rb')
#self.magic = f.read(5)
#if self.magic == '\375\067zXZ':
# self.pkgsuffix = 'pkg.tar.xz'
fn = open('/dev/null', 'wb')
pipe = subprocess.Popen(['tar', '-O', '-xf', self.__path, '.PKGINFO'], stdout=subprocess.PIPE, stderr=fn).stdout;
for line in pipe.readlines():
line = line.rstrip().split(' = ', 2)
if len(line) == 2:
if not line[0] in self.fields:
self.fields[line[0]] = []
self.fields[line[0]].append(line[1])
def vercmp(self, archq):
res = cmp(int(self.epoch()), int(archq.epoch()))
if res != 0:
return res
res = ArchQuery.rpmvercmp(self.version(), archq.version())
if res != None:
return res
res = ArchQuery.rpmvercmp(self.release(), archq.release())
return res
def name(self):
return self.fields['pkgname'][0] if 'pkgname' in self.fields else None
def version(self):
pkgver = self.fields['pkgver'][0] if 'pkgver' in self.fields else None
if pkgver != None:
pkgver = re.sub(r'[0-9]+:', '', pkgver, 1)
pkgver = re.sub(r'-[^-]*$', '', pkgver)
return pkgver
def release(self):
pkgver = self.fields['pkgver'][0] if 'pkgver' in self.fields else None
if pkgver != None:
m = re.search(r'-([^-])*$', pkgver)
if m:
return m.group(1)
return None
def epoch(self):
pkgver = self.fields['pkgver'][0] if 'pkgver' in self.fields else None
if pkgver != None:
m = re.match(r'([0-9])+:', pkgver)
if m:
return m.group(1)
return None
def arch(self):
return self.fields['arch'][0] if 'arch' in self.fields else None
def description(self):
return self.fields['pkgdesc'][0] if 'pkgdesc' in self.fields else None
def path(self):
return self.__path
def provides(self):
return self.fields['provides'] if 'provides' in self.fields else []
def requires(self):
return self.fields['depend'] if 'depend' in self.fields else []
def canonname(self):
pkgver = self.fields['pkgver'][0] if 'pkgver' in self.fields else None
return self.name() + '-' + pkgver + '-' + self.arch() + '.' + self.pkgsuffix
@staticmethod
def query(filename, all_tags = False, *extra_tags):
f = open(filename, 'rb')
archq = ArchQuery(f)
archq.read(all_tags, *extra_tags)
f.close()
return archq
@staticmethod
def rpmvercmp(ver1, ver2):
"""
implementation of RPM's version comparison algorithm
(as described in lib/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)
@staticmethod
def filename(name, version, release, arch):
if release:
return '%s-%s-%s-%s.arch' % (name, version, release, arch)
else:
return '%s-%s-%s.arch' % (name, version, arch)
if __name__ == '__main__':
import sys
try:
archq = ArchQuery.query(sys.argv[1])
except ArchError, e:
print e.msg
sys.exit(2)
print archq.name(), archq.version(), archq.release(), archq.arch()
print archq.canonname()
print archq.description()
print '##########'
print '\n'.join(archq.provides())
print '##########'
print '\n'.join(archq.requires())

View File

@ -99,8 +99,11 @@ class PackageQuery:
pkgquery = debquery.DebQuery(f)
extra_tags = extra_debtags
elif magic[:5] == '<?xml':
f.close()
return None
f.close()
return None
elif magic[:5] == '\375\067zXZ' or magic[:2] == '\037\213':
import archquery
pkgquery = archquery.ArchQuery(f)
else:
raise PackageError(filename, 'unsupported package type. magic: \'%s\'' % magic)
pkgquery.read(all_tags, *extra_tags)