From: Chulwoo Shin Date: Mon, 27 Feb 2017 14:19:29 +0000 (+0900) Subject: [TIC-CORE] Support analysis of unified repositories X-Git-Tag: v20170316~2^2~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;ds=sidebyside;h=refs%2Fchanges%2F64%2F116564%2F1;p=archive%2F20170607%2Ftools%2Ftic-core.git [TIC-CORE] Support analysis of unified repositories - support analysis of unified repositories - support dependency tag for recommends/suggest Change-Id: I9b74ec52b9118f0853c9dbd626d821ca34f724d6 Signed-off-by: Chulwoo Shin --- diff --git a/tic/command.py b/tic/command.py index ea0e4e6..89df3fb 100644 --- a/tic/command.py +++ b/tic/command.py @@ -68,7 +68,7 @@ def analyze(repo_list, recipe_list=None): start_time = current_milli_time() # Parse the xml files for the analysis of package (.rpm) - repo_parser = RepodataParser(repoinfo) + repo_parser = RepodataParser('armv7l', repoinfo) pkg_group = repo_parser.parse() logger.info('packages: %d, provides: %d, files: %d', len(pkg_group['pkg_dict']), len(pkg_group['provides']), len(pkg_group['files'])) logger.info('time to parse repodata: %d ms', current_milli_time() - start_time) @@ -95,7 +95,7 @@ def analyze(repo_list, recipe_list=None): return result -def exports(export_type, recipe, packages, outdir): +def exports(export_type, recipe, packages, outdir, filename): logger = logging.getLogger(__name__) #TODO validation should be checked before request @@ -131,6 +131,9 @@ def exports(export_type, recipe, packages, outdir): # check whether the ks exists baseline=recipe['Default'].get('Baseline') ksname= ''.join([config.get('FileName'), '.ks']) + if filename: + ksname= ''.join([config.get('FileName'), '.ks']) + kspath=os.path.join(yaml_info.cachedir, baseline, ksname) if not os.path.exists(kspath): raise TICError('No ks file was created from kickstarter') diff --git a/tic/dependency.py b/tic/dependency.py index 80b9045..09af564 100644 --- a/tic/dependency.py +++ b/tic/dependency.py @@ -19,10 +19,10 @@ # Contributors: # - S-Core Co., Ltd -import rpm import logging from lxml import etree from tic.utils.error import TICError +from tic.utils.rpmmisc import meetRequireVersion, compare_ver def analyze_dependency(pkg_group): @@ -95,37 +95,16 @@ def analyze_dependency(pkg_group): def get_installed_packages(recipe, repoinfo, pkg_group): logger = logging.getLogger(__name__) - def _compare_ver(ver1, ver2): - return rpm.labelCompare((ver1.get('epoch'), ver1.get('ver'), ver1.get('rel')), - (ver2.get('epoch'), ver2.get('ver'), ver2.get('rel'))) - - def _compare_req_cap_ver(req, cap): - epoch = cap.get('epoch') - ver = cap.get('ver') - rel = cap.get('rel') - if not req.get('epoch'): epoch = None - if not req.get('rel'): rel = None - return rpm.labelCompare((req.get('epoch'), req.get('ver'), req.get('rel')), (epoch, ver, rel)) - - def _meetRequireVersion(req_ver, cmp_ver): - cmp_ret = _compare_req_cap_ver(req_ver, cmp_ver) - if cmp_ret == 0 and (req_ver['flags'] == 'EQ' or req_ver['flags'] == 'GE' or req_ver['flags'] == 'LE'): - return True - elif cmp_ret == 1 and (req_ver['flags'] == 'LT' or req_ver['flags'] == 'LE'): - return True - elif cmp_ret == -1 and (req_ver['flags'] == 'GT' or req_ver['flags'] == 'GE'): - return True - return False - def _select_rpm(capability, require): provide_list = [] # 1. Choose the rpm included in version from provides if require.get('ver') is not None: for provide in capability: ver_data = provide['data'] + # If there is no capability version, use version of package if not ver_data.get('ver'): ver_data = pkg_dict.get(provide['name']).get('version') - if _meetRequireVersion(require, ver_data): + if meetRequireVersion(require, ver_data): provide_list.append(provide) else: provide_list = capability @@ -150,7 +129,7 @@ def get_installed_packages(recipe, repoinfo, pkg_group): if not _check_conflicts(pkg_dict.get(provide_list[i]['name'])): if max_ver: cap_info = provide_list[i].get('data') - ret = _compare_ver(max_ver.get('data'), cap_info) + ret = compare_ver(max_ver.get('data'), cap_info) # cap_info is greater than max_ver if ret == -1: max_ver = provide_list[i] @@ -207,7 +186,7 @@ def get_installed_packages(recipe, repoinfo, pkg_group): for pro in pkg_info['provides']: if pro['name'] in conflicts: for con in conflicts[pro['name']]: - if not con['data'].get('ver') or _meetRequireVersion(con['data'], pro): + if not con['data'].get('ver') or meetRequireVersion(con['data'], pro): #package conflict return True @@ -218,12 +197,12 @@ def get_installed_packages(recipe, repoinfo, pkg_group): for pro in provides[con['name']]: pkg = pkg_dict[pro['name']] if selected[pkg['id']] != 0: - if not con.get('ver') or _meetRequireVersion(con, pkg['version']): + if not con.get('ver') or meetRequireVersion(con, pkg['version']): return True elif con['name'] in pkg_dict: pkg = pkg_dict[con['name']] if selected[pkg['id']] != 0: - if not con.get('ver') or _meetRequireVersion(con, pkg['version']): + if not con.get('ver') or meetRequireVersion(con, pkg['version']): return True return False @@ -257,7 +236,7 @@ def get_installed_packages(recipe, repoinfo, pkg_group): _add_conflicts(pkg_info) # Installation dependency analysis of rpm - for dep_tag in ['requires']: # 'recommends' + for dep_tag in ['requires', 'recommends']: if pkg_info.get(dep_tag): for req in pkg_info.get(dep_tag): choose = None @@ -392,24 +371,28 @@ def get_installed_packages(recipe, repoinfo, pkg_group): group_set.update(g.get('Groups')) if g.has_key('ExtraPackages'): pkg_set.update(g.get('ExtraPackages')) - group_dict = dict.fromkeys(group_set) + #group_dict = dict.fromkeys(group_set) # parsing group.xml - try: - tree = etree.parse(repoinfo[0].get('comps')) - root = tree.getroot() - except etree.XMLSyntaxError as e: - raise TICError('primary.xml syntax error. %s', e) - - # Convert groups to packages - for elm in root.findall('group'): - group_name = elm.find('name').text - if group_dict.has_key(group_name): - pkglist = elm.find('packagelist') - plist = [] - for pkgreq in pkglist.findall('packagereq'): - plist.append(pkgreq.text) - pkg_set.update(set(plist)) + if group_set: + for repo in repoinfo: + if repo.get('comps'): + try: + tree = etree.parse(repo.get('comps')) + root = tree.getroot() + except etree.XMLSyntaxError as e: + raise TICError('group.xml syntax error. %s', e) + + # Convert groups to packages + for elm in root.findall('group'): + group_name = elm.find('name').text + if group_name in group_set: + pkglist = elm.find('packagelist') + plist = [] + for pkgreq in pkglist.findall('packagereq'): + plist.append(pkgreq.text) + pkg_set.update(set(plist)) + group_set.discard(group_name); pkg_dict = pkg_group.get('pkg_dict') provides = pkg_group.get('provides') diff --git a/tic/parser/recipe_parser.py b/tic/parser/recipe_parser.py index 971735a..102daee 100644 --- a/tic/parser/recipe_parser.py +++ b/tic/parser/recipe_parser.py @@ -50,47 +50,41 @@ def get_default_recipe(): SaveRepos= False, UserGroups= "audio,video" ), - Emulator64wayland=dict( + Wayland=dict( Part='mobile-mbr', UserGroups='audio,video', - Groups=['Generic Base'], + Groups=[], PostScripts=[], Repos= [], NoChrootScripts=[] ), Configurations=[ dict( - Name='mobile-emulator64-wayland', - Architecture='x86_64', + Name='default', + Architecture='armv7l', Schedule= "*", Active= True, - Platform= 'Emulator64wayland', + Platform= 'Wayland', Part= 'mobile-2parts-emulator', Mic2Options= '-f loop --pack-to=@NAME@.tar.gz', - FileName= 'mobile-emulator64-wayland', - Repos=['mobile-emulator64-wayland', 'base_emulator64'], + FileName= 'default', + Repos=['tizen-standard'], Groups=[], -# Groups=['Mobile Adaptation Emulator'], - ExtraPackages= ['building-block-sub2-metapkg-extsub1-exts1sub1', 'building-block-sub2-metapkg-extsub1-exts1sub1', 'icecream'], + ExtraPackages= [], RemovePackages=[] ) ], Repositories=[ -# dict(Name='mobile-emulator64-wayland', -# Url='http://download.tizen.org/live/devel:/Tizen:/Unified:/unmerged/standard/', -# Options='--ssl_verify=no'), - dict(Name='mobile-emulator64-wayland', - Url='http://download.tizen.org/snapshots/tizen/mobile/latest/repos/emulator64-wayland/packages/', + dict(Name='tizen-unified', + Url='http://download.tizen.org/live/devel:/Tizen:/Unified/standard/', Options='--ssl_verify=no'), - dict(Name='base_emulator64', - Url='http://download.tizen.org/snapshots/tizen/base/latest/repos/emulator64/packages/', + dict(Name='tizen-base', + Url='http://download.tizen.org/snapshots/tizen/base/latest/repos/arm/packages/', Options='--ssl_verify=no') ], Partitions=[ dict(Name='mobile-mbr', - Contents='part / --fstype="ext4" --size=3584 --ondisk=sda --active --label platform --fsoptions=defaults,noatime'), - dict(Name= 'mobile-2parts-emulator', - Contents='part / --size=2000 --ondisk=sda --fstype=ext4 --label=emulator-rootfs\npart /opt/ --size=2000 --ondisk=sda --fstype=ext4 --label=emulator-sysdata') + Contents='part / --fstype="ext4" --size=3584 --ondisk=sda --active --label platform --fsoptions=defaults,noatime') ] ) return recipe diff --git a/tic/parser/repo_parser.py b/tic/parser/repo_parser.py index 2487336..a7f0c5f 100644 --- a/tic/parser/repo_parser.py +++ b/tic/parser/repo_parser.py @@ -21,15 +21,24 @@ from lxml import etree from tic.utils.error import TICError +from tic.utils.rpmmisc import archPolicies, default_arch import logging import re +meta_prefix = 'building-blocks' +meta_prefix_root = 'building-blocks-root-' +meta_prefix_sub1 = 'building-blocks-sub1-' +meta_pattern = re.compile(''.join(['^', meta_prefix, '-(?Proot|sub1|sub2)-(?P.+)']), re.I) +meta_sub1_pattern = re.compile("(?P.+)-(?P.+)") +meta_sub2_pattern = re.compile("(?P.+)-(?P.+)-(?P.+)") + class RepodataParser(object): - def __init__(self, repodata_list): + def __init__(self, arch, repodata_list): + self.arch = arch self.repodata_list = repodata_list - def _xml_parse(self, pkg_group, root, tag_dic): + def _xml_parse(self, pkg_group, pkg_list, tag_dic): def _set_version(element, tag): if 'ver' in tag.attrib: @@ -40,34 +49,26 @@ class RepodataParser(object): element['epoch'] = tag.attrib['epoch'] if 'flags' in tag.attrib: element['flags'] = tag.attrib['flags'] - - logger = logging.getLogger(__name__) - meta_prefix = 'building-block' - meta_prefix_root = 'building-block-root-' - meta_prefix_sub1 = 'building-block-sub1-' - meta_pattern = re.compile(''.join(['^', meta_prefix, '-(?Proot|sub1|sub2)-(?P.+)']), re.I) - meta_sub1_pattern = re.compile("(?P.+)-(?P.+)") - meta_sub2_pattern = re.compile("(?P.+)-(?P.+)-(?P.+)") pkg_dict = pkg_group.get('pkg_dict') provides_dict = pkg_group.get('provides') files_dict = pkg_group.get('files') meta_info = pkg_group.get('meta_info') - pkg_id = len(pkg_dict) - for pkg in root.findall(tag_dic['package']): + for pkg in pkg_list: pkg_name = pkg.findtext(tag_dic['name']) # check whether a package is duplicated. if pkg_name in pkg_dict: - #TODO: Apply to policy of duplication - logger.warning('package(%s) is duplicated. exclude this package', pkg_name) + # TODO: Apply to policy of duplication + # logger.warning('package(%s) is duplicated. exclude this package', pkg_name) continue - + pkg_info = {} pkg_info['id'] = pkg_id pkg_info['name'] = pkg_name + pkg_info['arch'] = pkg.findtext(tag_dic['arch']) pkg_info['selfChecked'] = False # for web-ui tree # Parsing meta-pkg using meta naming rule @@ -89,8 +90,7 @@ class RepodataParser(object): ''.join([meta_prefix_sub1, sub2_match.group('root'),'-', sub2_match.group('sub1')])]) pkg_info['meta'] = 'sub2' - pkg_info['arch'] = pkg.findtext(tag_dic['arch']) - #pkg_info['version'] = pkg.find(tag_dic['version']).attrib['ver'] + ver_tag = pkg.find(tag_dic['version']) pkg_info['version'] = {'epoch':ver_tag.attrib['epoch'], 'ver':ver_tag.attrib['ver'], @@ -213,6 +213,20 @@ class RepodataParser(object): tags['recommends'] = '{%s}recommends' % root.nsmap['rpm'] tags['file'] = '{%s}file' % root.nsmap[None] return tags + + def _filtering_data_based_arch(self, xml_list, tag_dic): + ret_list = [] + for xml_root in xml_list: + pkg_data = {} + for pkg_elm in xml_root.findall(tag_dic['package']): + pkg_arch = pkg_elm.findtext(tag_dic['arch']) + if pkg_arch not in archPolicies[self.arch] and pkg_arch not in default_arch: + continue; + if not pkg_data.get(pkg_arch): + pkg_data[pkg_arch] = [] + pkg_data[pkg_arch].append(pkg_elm) + ret_list.append(pkg_data) + return ret_list def parse(self): if not self.repodata_list: @@ -228,22 +242,30 @@ class RepodataParser(object): tag_dic = self._get_tagname(xml_list[0]) - #TODO: temporary code (should be deleted) - #meta_string='building-block-root-metapkgaarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfSimple DirectMedia LayerThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/building-block-sub1-metapkg-extsub1aarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfsub1-extensionThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/building-block-sub2-metapkg-extsub1-exts1sub1aarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfsub2-extensionThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/building-block-sub2-metapkg-extsub1-exts1sub2aarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfsub2-extensionThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/building-block-sub1-metapkg-extsub2aarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfsub1-extensionThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/building-block-sub2-metapkg-extsub2-exts2sub1aarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfsub2-extensionThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/building-block-sub2-metapkg-extsub2-exts2sub2aarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfsub2-extensionThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/' - meta_string='building-block-root-metapkgaarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfSimple DirectMedia LayerThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/building-block-sub1-metapkg-extsub1aarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfsub1-extensionThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/building-block-sub2-metapkg-extsub1-exts1sub1aarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfsub2-extensionThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/building-block-sub2-metapkg-extsub1-exts1sub2aarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfsub2-extensionThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/building-block-sub1-metapkg-extsub2aarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfsub1-extensionThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/building-block-sub2-metapkg-extsub2-exts2sub1aarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfsub2-extensionThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/building-block-sub2-metapkg-extsub2-exts2sub2aarch646f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfsub2-extensionThis is the Simple DirectMedia Layer, a generic API that provides low level access to audio, keyboard, mouse, and display framebuffer across multiple platforms.http://www.libsdl.org/' - xml_list.append(etree.fromstring(meta_string)) + # TODO: temporary code (should be deleted) + # meta_string='building-blocks-root-chooseonlyone_Kernelarmv7l6f74666eb89e1addc4ce75e25f3e639bbfdd8798fc848a6b7027501070567dcfLinux KernelInclude Linux Kernel in the Platform Imagehttp://tizen.org' + # xml_list.append(etree.fromstring(meta_string)) - #pkg_group = dict(pkg_list=[], pkg2id={}, provides2id={}, file2id={}, meta_info=dict(root=[], sub1=[], sub2=[])) - pkg_group = dict(pkg_dict={}, - provides={}, - files={}, + filter_data = self._filtering_data_based_arch(xml_list, tag_dic) + + pkg_group = dict(pkg_dict={}, + provides={}, + files={}, groups={}, conflicts={}, meta_info=dict(root=[], sub1=[], sub2=[])) # parses the repodata (primary.xml) - for xml_root in xml_list: - self._xml_parse(pkg_group, xml_root, tag_dic) + # for xml_root in xml_list: + # self._xml_parse(pkg_group, xml_root, tag_dic) + for xml_data in filter_data: + for arch in archPolicies[self.arch]: + if arch in xml_data: + self._xml_parse(pkg_group, xml_data[arch], tag_dic) + # noarch, src + for arch in default_arch: + if arch in xml_data: + self._xml_parse(pkg_group, xml_data[arch], tag_dic) # set the requires id #self._prepare_requires_id(pkg_group) diff --git a/tic/parser/view_parser.py b/tic/parser/view_parser.py index 586307d..30cd3aa 100644 --- a/tic/parser/view_parser.py +++ b/tic/parser/view_parser.py @@ -1,30 +1,55 @@ import logging from operator import itemgetter +from tic.utils.rpmmisc import meetRequireVersion def make_view_data(pkg_group): logger = logging.getLogger(__name__) + def _select_provide_rpm(capability, require): + provide_list = [] + if require.get('ver') is not None: + for provide in capability: + ver_data = provide['data'] + if not ver_data.get('ver'): + ver_data = pkg_dict.get(provide['name']).get('version') + if meetRequireVersion(require, ver_data): + provide_list.append(provide) + else: + provide_list = capability + + result = [] + for provide in provide_list: + result.append(pkg_dict[provide['name']]) + + return result + def set_meta_require(meta_info): meta_nodes = meta_info.get('nodes') for child_meta in meta_nodes: refer_count[child_meta['id']] += 1 set_meta_require(child_meta) - req_list = pkg_dict[meta_info['text']].get('requires') - if req_list is not None: - for req in req_list: - if provides.get(req['name']): - provide_info = provides[req['name']][0] - pkg_name = provide_info['name'] - if 'meta' not in pkg_dict[pkg_name]: - child_pkg = pkg_dict[pkg_name] - meta_nodes.append(make_node(child_pkg)) - refer_count[child_pkg['id']] += 1 + pkg_info = pkg_dict[meta_info['text']] + for dep_tag in ['requires', 'recommends']: + if pkg_info.get(dep_tag): + for req in pkg_info.get(dep_tag): + targets = [] + if req['name'] in provides: + targets = _select_provide_rpm(provides[req['name']], req) + elif req['name'] in files: + targets.append(pkg_dict.get(files[req['name']][0])) + elif req['name'] in pkg_dict: + targets.append(pkg_dict.get(req['name'])) else: - # The meta-pkg of the other group are excluded. # the dependent package does not exist. pass + + for pkg in targets: + # The meta-pkg of the other group are excluded. + if not pkg.get('meta'): + refer_count[pkg['id']] += 1 + meta_nodes.append(make_node(pkg)) def make_node(pkg_info): return dict(id=pkg_info['id'], text=pkg_info['name'], nodes=[]) @@ -39,6 +64,7 @@ def make_view_data(pkg_group): pkg_dict = pkg_group['pkg_dict'] provides = pkg_group['provides'] + files = pkg_group['files'] refer_count = [0] * len(pkg_dict) # sort by pkg_name ([0]:name, [1]:root, [2]:sub1) diff --git a/tic/server/tic_server.py b/tic/server/tic_server.py index d0b3a9a..106b26a 100644 --- a/tic/server/tic_server.py +++ b/tic/server/tic_server.py @@ -46,8 +46,8 @@ def exports(): logger = logging.getLogger(__name__) logger.info('%s - %s %s : data=%s' % (request.remote_addr, request.method, request.path, request.data)) exportInfo = json.loads(request.data) - type = request.args.get('format') - output = command.exports(type, exportInfo.get('recipe'), exportInfo.get('packages'), exportInfo.get('output')) + export_type = request.args.get('format') + output = command.exports(export_type, exportInfo.get('recipe'), exportInfo.get('packages'), exportInfo.get('outdir'), exportInfo.get('filename')) resp = makeresponse(output, None) except error.TICError as err: logger.error(err) diff --git a/tic/utils/rpmmisc.py b/tic/utils/rpmmisc.py new file mode 100644 index 0000000..299896b --- /dev/null +++ b/tic/utils/rpmmisc.py @@ -0,0 +1,62 @@ +#!/usr/bin/python +# Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved. +# +# Contact: +# @author Chulwoo Shin +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Contributors: +# - S-Core Co., Ltd + +import rpm + +default_arch = ('noarch', 'src') + +archPolicies = { + "x86_64": ("x86_64", "i686", "i586", "i486", "i386"), + "i686": ("i686", "i586", "i486", "i386"), + "i586": ("i586", "i486", "i386"), + "ia64": ("ia64", "i686", "i586", "i486", "i386"), + "aarch64": ("aarch64"), + "armv7tnhl": ("armv7tnhl", "armv7thl", "armv7nhl", "armv7hl"), + "armv7thl": ("armv7thl", "armv7hl"), + "armv7nhl": ("armv7nhl", "armv7hl"), + "armv7hl": ("armv7hl"), + "armv7l": ("armv7l", "armv6l", "armv5tejl", "armv5tel", "armv5l", "armv4tl", "armv4l", "armv3l"), + "armv6l": ("armv6l", "armv5tejl", "armv5tel", "armv5l", "armv4tl", "armv4l", "armv3l"), + "armv5tejl": ("armv5tejl", "armv5tel", "armv5l", "armv4tl", "armv4l", "armv3l"), + "armv5tel": ("armv5tel", "armv5l", "armv4tl", "armv4l", "armv3l"), + "armv5l": ("armv5l", "armv4tl", "armv4l", "armv3l"), +} + +def compare_ver(ver1, ver2): + return rpm.labelCompare((ver1.get('epoch'), ver1.get('ver'), ver1.get('rel')), (ver2.get('epoch'), ver2.get('ver'), ver2.get('rel'))) + +def compare_req_cap_ver(req, cap): + epoch = cap.get('epoch') + ver = cap.get('ver') + rel = cap.get('rel') + if not req.get('epoch'): epoch = None + if not req.get('rel'): rel = None + return rpm.labelCompare((req.get('epoch'), req.get('ver'), req.get('rel')), (epoch, ver, rel)) + +def meetRequireVersion(req_ver, cmp_ver): + cmp_ret = compare_req_cap_ver(req_ver, cmp_ver) + if cmp_ret == 0 and (req_ver['flags'] == 'EQ' or req_ver['flags'] == 'GE' or req_ver['flags'] == 'LE'): + return True + elif cmp_ret == 1 and (req_ver['flags'] == 'LT' or req_ver['flags'] == 'LE'): + return True + elif cmp_ret == -1 and (req_ver['flags'] == 'GT' or req_ver['flags'] == 'GE'): + return True + return False