1 #!/usr/bin/env python 2 3 """ 4 Greps and returns the first svn log entry containing a line matching the regular 5 expression pattern passed as the only arg. 6 7 Example: 8 9 svn log -v | grep-svn-log.py '^ D.+why_are_you_missing.h$' 10 """ 11 12 import fileinput, re, sys, StringIO 13 14 # Separator string for "svn log -v" output. 15 separator = '-' * 72 16 17 usage = """Usage: grep-svn-log.py line-pattern 18 Example: 19 svn log -v | grep-svn-log.py '^ D.+why_are_you_missing.h'""" 20 21 class Log(StringIO.StringIO): 22 """Simple facade to keep track of the log content.""" 23 def __init__(self): 24 self.reset() 25 def add_line(self, a_line): 26 """Add a line to the content, if there is a previous line, commit it.""" 27 global separator 28 if self.prev_line != None: 29 print >> self, self.prev_line 30 self.prev_line = a_line 31 self.separator_added = (a_line == separator) 32 def del_line(self): 33 """Forget about the previous line, do not commit it.""" 34 self.prev_line = None 35 def reset(self): 36 """Forget about the previous lines entered.""" 37 StringIO.StringIO.__init__(self) 38 self.prev_line = None 39 def finish(self): 40 """Call this when you're finished with populating content.""" 41 if self.prev_line != None: 42 print >> self, self.prev_line 43 self.prev_line = None 44 45 def grep(regexp): 46 # The log content to be written out once a match is found. 47 log = Log() 48 49 LOOKING_FOR_MATCH = 0 50 FOUND_LINE_MATCH = 1 51 state = LOOKING_FOR_MATCH 52 53 while 1: 54 line = sys.stdin.readline() 55 if not line: 56 return 57 line = line.splitlines()[0] 58 if state == FOUND_LINE_MATCH: 59 # At this state, we keep on accumulating lines until the separator 60 # is encountered. At which point, we can return the log content. 61 if line == separator: 62 log.finish() 63 print log.getvalue() 64 return 65 log.add_line(line) 66 67 elif state == LOOKING_FOR_MATCH: 68 if line == separator: 69 log.reset() 70 log.add_line(line) 71 # Update next state if necessary. 72 if regexp.search(line): 73 state = FOUND_LINE_MATCH 74 75 def main(): 76 if len(sys.argv) != 2: 77 print usage 78 sys.exit(0) 79 80 regexp = re.compile(sys.argv[1]) 81 grep(regexp) 82 sys.stdin.close() 83 84 if __name__ == '__main__': 85 main() 86