diff --git a/src/mio.py b/src/mio.py index dfa02c160e799553fdc0f5ea922f1a7e0c28a15d..cc2503dc13079e8bf038ef2b5be14c757c34ea25 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 34d6eb15731d6c3266f10a925a888c6124caf7fc..9339ea23f528b16c74e4a7a8135f4a519fad2861 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 a7846d2340068f2e3a2dd05fba09c16f4cd14c7a..03aba20b67654ef6b4d3c89d7bd481e3881835b6 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