#!/s/mozilla-build/python25/python """ Reads CVS log in the following format from stdin and prints an abridged version of it to stdout: Checking in accessible/src/base/nsAccessibilityAtomList.h; /cvsroot/mozilla/accessible/src/base/nsAccessibilityAtomList.h,v <-- nsAccessibilityAtomList.h new revision: 1.53; previous revision: 1.52 done becomes mozilla/accessible/src/base/nsAccessibilityAtomList.h 1.53 """ import sys import re __author__ = "Nickolay Ponomarev " __version__ = "$Revision: 0.1 $" __date__ = "$Date: 2007/02/18 22:21:04 $" __copyright__ = "Copyright (c) 2007 Nickolay Ponomarev" __license__ = "Python" class CVSLogProcessor: _checkingInRe = re.compile(r"^Checking in.*;$") _RCSFileRe = re.compile(r"^RCS file: .*,v$") _RemovingRe = re.compile(r"^Removing .*;$") _cvsPathRe = re.compile(r"^/cvsroot/(?P.*?),v <-- .*$") _revisionRe = re.compile(r"^(new|initial) revision: (?P([0-9.]+)|(delete))") _doneRe = re.compile(r"^done$") def __init__(self): pass def _processSingleChunk(self, lines): try: line = lines.next().strip() except StopIteration: line = "" if line == "": return None isCheckingIn = self._checkingInRe.match(line) isRemoving = self._RemovingRe.match(line); isRCSFile = self._RCSFileRe.match(line) assert isCheckingIn or isRCSFile or isRemoving, \ "Each chunk of the log must begin with a 'Checking in .... ;'\n" + \ "'Removing ...;', or a 'RCS file: ....,v' line, got '%s'." % (line) if isCheckingIn or isRemoving: line = lines.next() matches = self._cvsPathRe.match(line) assert matches is not None, "Unexpected cvspath line: '%s'" % (line) cvspath = matches.group("cvspath") line = lines.next() matches = self._revisionRe.match(line) assert matches is not None, "Unexpected revision line: '%s'" % (line) revision = matches.group("revision") line = lines.next() assert self._doneRe.match(line) return (cvspath, revision) else: line = lines.next() assert self._doneRe.match(line) return () def shortenCVSLog(self, lines): parsedLog = [] parsedChunk = () while parsedChunk is not None: if len(parsedChunk) > 0: parsedLog.append(parsedChunk) parsedChunk = self._processSingleChunk(lines) return parsedLog class AbridgedLogFormatter: def prettyPrintParsedLog(self, parsedLog): # calculate the maximum length of the file path to pad the rest with whitespace maxLength = reduce(lambda accum, value: max(accum, len(value[0])), log, 0) # generate the formatted list formattedLog = [chunk[0].ljust(maxLength) + " " + chunk[1] for chunk in log] return formattedLog def printParsedLog(self, parsedLog): print "\n".join(self.prettyPrintParsedLog(log)) def readStdOut(): while True: yield sys.stdin.readline() if __name__ == "__main__": log = CVSLogProcessor().shortenCVSLog(readStdOut()) AbridgedLogFormatter().printParsedLog(log)