blob: ebbfe33f0520405e48ce168fc1d45ce6c351d456 [file] [log] [blame]
Johnny Chen10dd7a42011-11-04 01:05:29 +00001#!/usr/bin/env python
2
3"""
4Greps and returns the first svn log entry containing a line matching the regular
5expression pattern passed as the only arg.
6
7Example:
8
9svn log -v | grep-svn-log.py '^ D.+why_are_you_missing.h$'
10"""
11
12import fileinput, re, sys, StringIO
13
14# Separator string for "svn log -v" output.
15separator = '-' * 72
16
17usage = """Usage: grep-svn-log.py line-pattern
18Example:
19 svn log -v | grep-svn-log.py '^ D.+why_are_you_missing.h'"""
20
21class 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
45def 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:
Johnny Chenaa142bc2012-03-05 18:25:29 +000062 log.finish()
Johnny Chen10dd7a42011-11-04 01:05:29 +000063 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
75def 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)
Johnny Chenaa142bc2012-03-05 18:25:29 +000082 sys.stdin.close()
Johnny Chen10dd7a42011-11-04 01:05:29 +000083
84if __name__ == '__main__':
85 main()