This patch changes repoman to use the libxml2 python bindings to verify metadata.xml instead of calling xmllint. --- repoman 2005-03-20 01:29:53.000000000 +0100 +++ repoman.new 2005-03-20 02:25:38.000000000 +0100 @@ -155,7 +155,6 @@ qacats.append(x+".missing") qawarnings.append(x+".missing") - def err(txt): print exename+": "+txt sys.exit(1) @@ -172,6 +171,31 @@ repoman_settings = portage.config(clone=portage.settings) +class repoman_metadata_verifier: + def __init__(self, dtd): + import libxml2 + self._errors = [] + self._errstr = "" + libxml2.registerErrorHandler(self.error_handler, None) + self._validator = libxml2.newValidCtxt() + self._parser = libxml2.newParserCtxt() + self._parsed_dtd = libxml2.parseDTD(None, dtd) + + def error_handler(self, ctxt, string): + self._errstr += string + if self._errstr[-1] == "\n": + self._errors.append(self._errstr.rstrip()) + self._errstr = "" + + def verify_file(self, file, verbose=True): + self._errors = [] + try: + xml = self._parser.ctxtReadFile(file, None, 0) + result = xml.validateDtd(self._validator, self._parsed_dtd) + except: + result = None + return (result, self._errors) + def valid_ebuild_name(name): """(name) --- Checks to ensure that the package name meets portage specs. Return 1 if valid, 0 if not.""" @@ -575,13 +599,11 @@ for x in qacats: stats[x]=0 fails[x]=[] -xmllint_capable = False -if getstatusoutput('which xmllint')[0] != 0: - print red("!!! xmllint not found. Can't check metadata.xml.\n") - if "--xmlparse" in myoptions or repolevel==3: - print red("!!!")+" sorry, xmllint is needed. failing\n" - sys.exit(1) -else: +libxml2_capable = False + +try: + import libxml2 + #hardcoded paths/urls suck. :-/ must_fetch=1 backup_exists=0 @@ -630,9 +652,13 @@ os.rename(portage.CACHE_PATH+'/metadata.dtd.backup',portage.CACHE_PATH+'/metadata.dtd') print red("!!!")+" fetching new metadata.dtd failed, aborting" sys.exit(1) - #this can be problematic if xmllint changes their output - xmllint_capable=True - + metadata_verifier = repoman_metadata_verifier(portage.CACHE_PATH+'/metadata.dtd') + libxml2_capable=True +except ImportError, e: + print red("!!! libxml2 python bindings not found. Can't check metadata.xml.\n") + if "--xmlparse" in myoptions or repolevel==3: + print red("!!!")+" sorry, libxml2 python bindings are needed. failing\n" + sys.exit(1) arch_caches={} for x in scanlist: @@ -798,11 +824,12 @@ #metadata.xml parse check else: #Only carry out if in package directory or check forced - if xmllint_capable: - st=getstatusoutput("xmllint --noout --valid --dtdvalid %s/metadata.dtd %s/metadata.xml" % (portage.CACHE_PATH, checkdir)) - if st[0] != 0: - for z in st[1].split("\n"): - print red("!!! ")+z + if libxml2_capable: + result, errors = metadata_verifier.verify_file(checkdir+"/metadata.xml") + + if not result: + for line in errors: + print red("!!! ")+x+"/metadata.xml: "+line stats["metadata.bad"]+=1 fails["metadata.bad"].append(x+"/metadata.xml")