From 4afbb96b1ef62469845e00ddaecb521fc5f0cbdb Mon Sep 17 00:00:00 2001 From: Anders Blomdell <anders.blomdell@control.lth.se> Date: Mon, 30 Jan 2017 20:41:38 +0100 Subject: [PATCH] Added group merging for comps.xml (needed for CentOS at least) --- src/mio.py | 111 +++++++++++++++++++++++++----------------- src/mio/repository.py | 8 +-- src/mio/transform.py | 9 ++++ 3 files changed, 79 insertions(+), 49 deletions(-) diff --git a/src/mio.py b/src/mio.py index dfa02c1..cc2503d 100755 --- a/src/mio.py +++ b/src/mio.py @@ -24,9 +24,11 @@ def parse_with_path(path, filename, repository): f = mio.filecache.loadfile(path, filename) tree = mio.parser.parse(f.filename, url=f.key) + join = None if tree._tag == "comps": # Transform comps to canonical form tree = mio.transform.from_fedora(tree) + join = mio.transform.join elif tree._tag == "hostinfo": # Transform hostinfo to canonical form tree = mio.transform.from_hostinfo(tree) @@ -34,7 +36,7 @@ def parse_with_path(path, filename, repository): # Transform mio tree to canonical form tree = mio.transform.from_mio(tree) - repository.add(tree._group_) + repository.add(tree._group_, join=join) def parse(filename, repository): path = list(options.path) @@ -48,58 +50,74 @@ def parse(filename, repository): pass raise Exception("Could not parse %s" % filename) -def find_and_parse(target, builder, url=None): - path = list(options.path) - if url: - for p in url.path: - path.insert(0, os.path.dirname(p)) +class FindAndParse: - for p in path: - if target.startswith("/"): - m = re.match("^/([^/]*)", target) - filename = "%s.mio" % (m.group(1)) - pass - elif target.startswith("@"): - filename = "base/comps.xml" + def __init__(self): + self.tried = set() + + def parse_with_path(self, path, filename, builder, target): + if not (path,filename) in self.tried: try: - # Try to locate group file via repomd.xml - f = mio.filecache.loadfile(p, '/repodata/repomd.xml') - tree = mio.parser.parse(f.filename) - for l in tree._data_._location_: - if l.type[1] == 'group': - filename = l.href[0] - break - pass - pass + parse_with_path(path, filename, builder) + self.tried.add((path,filename)) + return True except IOError, e: - continue - pass - else: - filename = "hostinfo.xml" + self.tried.add((path,filename)) + pass + except ValueError, e: + pass + except DuplicateGroupException, e: + print e + traceback.print_exc() + print "Failed to locate: %s" % target + sys.exit(1) + pass pass - try: - parse_with_path(p, filename, builder) + return False + + + def __call__(self, target, builder, url=None): + path = list(options.path) + if url: + for p in url.path: + path.insert(0, os.path.dirname(p)) + + OK = False + for p in path: + if target.startswith("/"): + m = re.match("^/([^/]*)", target) + OK |= self.parse_with_path(p, "%s.mio" % (m.group(1)), builder, target) + pass + elif target.startswith("@"): + filename = "base/comps.xml" + try: + # Try to locate group file via repomd.xml + f = mio.filecache.loadfile(p, '/repodata/repomd.xml') + tree = mio.parser.parse(f.filename) + for l in tree._data_._location_: + if l.type[1] == 'group': + OK |= self.parse_with_path(p, l.href[0], builder, target) + break + pass + pass + except IOError, e: + continue + pass + else: + OK |= self.parse_with_path(p, "hostinfo.xml", builder, target) + pass + + if OK: return - except IOError, e: - pass - except ValueError, e: + if options.noyum and target.startswith('@'): + # Synthetic target + tmp1 = mio.parser.Node("mio", 0) + tmp2 = mio.parser.Node("group", 0, { "name": target }) + tmp1._add(tmp2) + builder.add(tmp1._group_) pass - except DuplicateGroupException, e: - print e - traceback.print_exc() + else: print "Failed to locate: %s" % target - sys.exit(1) - pass - pass - if options.noyum and target.startswith('@'): - # Synthetic target - tmp1 = mio.parser.Node("mio", 0) - tmp2 = mio.parser.Node("group", 0, { "name": target }) - tmp1._add(tmp2) - builder.add(tmp1._group_) - pass - else: - print "Failed to locate: %s" % target if __name__ == '__main__': optParser = argparse.ArgumentParser(usage="%(prog)s [options]") @@ -168,6 +186,7 @@ if __name__ == '__main__': mio.log.set_verbosity(NORMAL + options.verbose - options.quiet) + find_and_parse = FindAndParse() rules = mio.repository.Repository(find_and_parse) rpm_result = None diff --git a/src/mio/repository.py b/src/mio/repository.py index 34d6eb1..9339ea2 100755 --- a/src/mio/repository.py +++ b/src/mio/repository.py @@ -12,13 +12,15 @@ class Repository: self.group = {} self.filter = filter - - def add(self, group): + def add(self, group, join=None): for g in group: name = g.name[0] if self.group.has_key(name): og = self.group[name] - raise DuplicateGroupException(g, og) + if join: + g = join(og, g) + else: + raise DuplicateGroupException(g, og) self.group[name] = g def get(self, target): diff --git a/src/mio/transform.py b/src/mio/transform.py index a7846d2..03aba20 100755 --- a/src/mio/transform.py +++ b/src/mio/transform.py @@ -2,6 +2,15 @@ import mio.parser import copy import itertools +def join(a, b): + result = mio.parser.Node("group", a._line, a._attribute) + for c in a._child(): + result._add(copy.deepcopy(c)) + for c in b._child(): + result._add(copy.deepcopy(c)) + result._parent = a._parent + return result + def from_fedora(tree): result = mio.parser.Node("mio", tree._line) result._url = tree._url -- GitLab