blob: a29df3fc108096da54d2c3fef14dc7f9b2a5ca38 [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:
62 print log.getvalue()
63 return
64 log.add_line(line)
65
66 elif state == LOOKING_FOR_MATCH:
67 if line == separator:
68 log.reset()
69 log.add_line(line)
70 # Update next state if necessary.
71 if regexp.search(line):
72 state = FOUND_LINE_MATCH
73
74def main():
75 if len(sys.argv) != 2:
76 print usage
77 sys.exit(0)
78
79 regexp = re.compile(sys.argv[1])
80 grep(regexp)
81
82if __name__ == '__main__':
83 main()