#!/usr/bin/python VC_Author = "$Author$" VC_Revision = "$Rev$" VC_Date = "$Date$" VC_Where = "$URL$" import xml.dom.minidom from xml.dom.minidom import parse as xmlparse from xml.dom import Node as DomNode import sys import re import os.path def getText(node): rc = "" for node in node.childNodes: if node.nodeType == node.TEXT_NODE: rc = rc + node.data return rc def filterpath(path, filter): path.pylog_path = getText(path) # print "%s = %s" % (pathtext, filter) return os.path.commonprefix((filter, path.pylog_path)) == filter def compressNode(node): removelist = [] lastnode = None for cnode in node.childNodes: if lastnode and (lastnode.nodeType == DomNode.TEXT_NODE) and \ (cnode.nodeType == DomNode.TEXT_NODE): # print repr(cnode.nodeValue) sval = cnode.nodeValue if sval: sval = sval.strip() if (not sval) or (len(sval) <= 0): # print "Removing: %s %s" % (sval, cnode) removelist.append(cnode) lastnode = cnode for cnode in removelist: node.removeChild(cnode) cnode.unlink() def trimlog(log, base): for logentry in log.getElementsByTagName('logentry'): paths = logentry.getElementsByTagName('paths')[0] pathlist = paths.getElementsByTagName('path') pathlist = filter(lambda x, f=base: not filterpath(x, f), pathlist) for path in pathlist: paths.removeChild(path) path.unlink() path = None compressNode(paths) pathlist = paths.getElementsByTagName('path') if len(pathlist) <= 0: log.removeChild(logentry) logentry.unlink() logentry = None compressNode(log) def chooseoutput_l(logentry, pathlist, base, changelogs): compref = os.path.commonprefix prefix = compref(map(lambda x: x.pylog_path, pathlist)) curroot = None curlen = 0 for cl in changelogs: if len(cl[1]) > curlen: if compref((cl[1], prefix)) == cl[1]: curroot = cl curlen = len(cl[1]) cllist = [] for cl in changelogs: if compref((cl[1], curroot[1])) == curroot[1]: clpl = tuple(filter(lambda x, p=cl[1], c=compref: c((x.pylog_path, p)) == p, pathlist)) if len(clpl) > 0: cl[2].append((logentry.cloneNode(1), clpl)) def chooseoutput(log, base, changelogs): for logentry in log.getElementsByTagName('logentry'): paths = logentry.getElementsByTagName('paths')[0] pathlist = paths.getElementsByTagName('path') chooseoutput_l(logentry, pathlist, base, changelogs) def writeChangelog(cl): Document = xml.dom.minidom.Document Element = xml.dom.minidom.Element (clloc, abs_clloc, entries) = cl clxml = Document() clxml.createProcessingInstruction('xml', 'version="1.0" encoding="utf-8"') log = Element('log') for entry in entries: # entry[0].writexml(sys.stdout, '', '', '') paths = entry[0].getElementsByTagName('paths')[0] npaths = Element('paths') npathsl = [] for path in entry[1]: npathsl.append(path.cloneNode(1)) npathsl.sort(lambda x,y: cmp(getText(x), getText(y))) for path in npathsl: npaths.appendChild(path) entry[0].replaceChild(npaths, paths) log.appendChild(entry[0]) clxml.appendChild(log) clout = file(os.path.join(clloc, 'svn-ChangeLog.xml'), 'w') clxml.writexml(clout, '', '', '') writeTextChangelog(log, file(os.path.join(clloc, 'svn-ChangeLog.txt'), 'w')) datere = re.compile('^\s*([0-9]+-[0-9]+-[0-9]+)T([0-9]+:[0-9]+:[0-9]+)\.[0-9]+Z\s*$') def writeTextChangelog(domlog, outfile): entries = domlog.getElementsByTagName('logentry') for logentry in entries: revision = logentry.getAttribute('revision') author = getText(logentry.getElementsByTagName('author')[0]) timestamp = logentry.getElementsByTagName('date')[0] (date, time) = datere.match(getText(timestamp)).groups() msg = getText(logentry.getElementsByTagName('msg')[0]) pathlist = [] for path in logentry.getElementsByTagName('paths')[0].getElementsByTagName('path'): if not path.hasAttribute('copyfrom-path'): pathlist.append(' %s %s' % (path.getAttribute('action'), getText(path))) else: pathlist.append(' %s %s (from %s:%s)' % \ (path.getAttribute('action'), getText(path), path.getAttribute('copyfrom-path'), path.getAttribute('copyfrom-rev'))) pathlist = '\n'.join(pathlist) logstr = '------------------------------------------------------------------------\nrev %s: \t%s | %s %s\nChanged paths:\n%s\n\n%s\n' % \ (revision, author, date, time, pathlist, msg) outfile.write(logstr) d = xmlparse(sys.stdin) log = d.documentElement pfilter = sys.argv[1] base = os.path.normpath(sys.argv[1]) changelogs = tuple(map(lambda x, b=base: [os.path.normpath(x), os.path.normpath(os.path.join(b, x)), []], sys.argv[2:])) trimlog(log, base) chooseoutput(log, base, changelogs) for cl in changelogs: writeChangelog(cl) #d.writexml(sys.stdout, '', '', '')