#!/usr/bin/env python # vim: set ai et sw=4 ts=4 sts=4: """Script to remove retired devs from metadata.xml.""" import os import sys import difflib import StringIO try: import cElementTree as etree except ImportError: try: from elementtree import ElementTree as etree except ImportError: print 'This script needs either celementtree (preferred, faster) or' print 'elementtree installed.' sys.exit(1) def getretired(userinfo_path): """ Get a list of retired devs from userinfo.xml """ retired = [] userinfo = etree.parse(userinfo_path) for entry in userinfo.findall('user'): status = entry.find('status') if status is not None: if status.text == 'Retired' or status.text == 'retired': devname = entry.get('username') retired.append(devname) return retired def herds(userinfo_path, herds_path): """ Show retired developers and which herds they are in """ try: retired = getretired(userinfo_path) except: print >>sys.stderr, "Couldn't parse userinfo.xml" sys.exit(1) try: herds = etree.parse(herds_path) except: print >>sys.stderr, "Couldn't parse herds.xml" sys.exit(1) for herd in herds.findall('herd'): herdname = herd.find('name').text for entry in herd.findall('maintainer'): email = entry.find('email') username = email.text.replace('@gentoo.org','') if username in retired: print herdname + ':\t' + username return 0 def project(userinfo_path, path): """ Remove retired developers from project pages userinfo is path to proj/en/devrel/roll-call/userinfo.xml files is a list of project xmls """ try: retired = getretired(userinfo_path) except: print >>sys.stderr, "Couldn't parse userinfo.xml" sys.exit(1) for root, dirs, files in os.walk(path): for file in files: if file.endswith('.xml'): fpath = root + '/' + file try: project = etree.parse(fpath) except SyntaxError: #print "Skipping %s, probably not a project xml" % file continue for entry in project.findall('dev'): if entry.text in retired: print fpath + ':\t' + entry.text def metadata(devname, path): """ output a diff between current metadata.xml and metadata.xml with the retired dev removed. """ email = '%s@gentoo.org' % devname if not os.path.isdir(path): print >>sys.stderr, '%r is not a directory' % path sys.exit(1) # Make sure path has a / at the end if not path.endswith('/'): path+='/' for root, dirs, files in os.walk(path): if 'metadata.xml' not in files: continue metadata_path = os.path.join(root, 'metadata.xml') try: metadata = etree.parse(metadata_path) except: print >>sys.stderr, "Couldn't parse %s .. skipping" % root[len(path) + 1:] continue changed = False noherd = False # Check if package has no-herd herd = metadata.find('herd') if herd is None: noherd = True elif herd.text is None: print >>sys.stderr, "Bogus herd entry in %s" % root[len(path):] noherd = True elif herd.text.strip() == 'no-herd': noherd = True for entry in metadata.findall('maintainer'): for mailentry in entry.findall('email'): if mailentry.text.strip() == email: if noherd: # remove name for name in entry.findall('name'): entry.remove(name) mailentry.text = 'maintainer-needed@gentoo.org' else: metadata.getroot().remove(entry) changed = True if changed: # we don't want the full path in the diff if not root.startswith(path): print 'wtf (not %r.startswith(%r/))' % (root, path) return 1 shortpath = root[len(path):] newfile = StringIO.StringIO() # etree does not write the header and DOCTYPE newfile.write('\n') newfile.write( '\n') metadata.write(newfile) # etree omits the final newline, add that to make the diff nicer newfile.write('\n') newfile.seek(0) # (skips the and DOCTYPE lines, hopefully) for line in difflib.unified_diff( open(metadata_path).readlines(), list(newfile), '%s.orig' % shortpath, shortpath): print line, print return 0 def usage(): print 'Usage: %s subcommand opts' % sys.argv[0] print 'Subcommands:' print '--herds /path/to/userinfo.xml /path/to/herds.xml : check herds.xml for retired developers' print '--metadata devname /path/to/tree :' print '\toutputs a diff between the current metadata.xml and' print '\tmetadata.xml with the retired dev removed.' print '--project /path/to/userinfo.xml /path/to/proj :' print '\tcheck the project pages for retired developers' sys.exit(1) def main(args): subcommands = ( '--herds', '--metadata', '--project' ) if len(args) == 1: usage() if args[1] not in subcommands: print args[1] usage() elif args[1] == '--herds': if not len(args) == 4: usage() herds(args[2],args[3]) elif args[1] == '--metadata': if not len(args) == 4: usage() metadata(args[2], args[3]) elif args[1] == '--project': if not len(args) == 4: usage() project(args[2], args[3]) return 0 if __name__ == '__main__': sys.exit(main(sys.argv))