blob: 86cc3ef1742f1f1d714008afdc732a2565b4fda0 [file] [log] [blame]
Johnny Chene79a8d32011-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
Kate Stoneb9c1b512016-09-06 20:57:50 +000012import fileinput
13import re
14import sys
15import StringIO
Johnny Chene79a8d32011-11-04 01:05:29 +000016
17# Separator string for "svn log -v" output.
18separator = '-' * 72
19
20usage = """Usage: grep-svn-log.py line-pattern
21Example:
22 svn log -v | grep-svn-log.py '^ D.+why_are_you_missing.h'"""
23
Kate Stoneb9c1b512016-09-06 20:57:50 +000024
Johnny Chene79a8d32011-11-04 01:05:29 +000025class Log(StringIO.StringIO):
26 """Simple facade to keep track of the log content."""
Kate Stoneb9c1b512016-09-06 20:57:50 +000027
Johnny Chene79a8d32011-11-04 01:05:29 +000028 def __init__(self):
29 self.reset()
Kate Stoneb9c1b512016-09-06 20:57:50 +000030
Johnny Chene79a8d32011-11-04 01:05:29 +000031 def add_line(self, a_line):
32 """Add a line to the content, if there is a previous line, commit it."""
33 global separator
Kate Stoneb9c1b512016-09-06 20:57:50 +000034 if self.prev_line is not None:
Johnny Chene79a8d32011-11-04 01:05:29 +000035 print >> self, self.prev_line
36 self.prev_line = a_line
37 self.separator_added = (a_line == separator)
Kate Stoneb9c1b512016-09-06 20:57:50 +000038
Johnny Chene79a8d32011-11-04 01:05:29 +000039 def del_line(self):
40 """Forget about the previous line, do not commit it."""
41 self.prev_line = None
Kate Stoneb9c1b512016-09-06 20:57:50 +000042
Johnny Chene79a8d32011-11-04 01:05:29 +000043 def reset(self):
44 """Forget about the previous lines entered."""
45 StringIO.StringIO.__init__(self)
46 self.prev_line = None
Kate Stoneb9c1b512016-09-06 20:57:50 +000047
Johnny Chene79a8d32011-11-04 01:05:29 +000048 def finish(self):
49 """Call this when you're finished with populating content."""
Kate Stoneb9c1b512016-09-06 20:57:50 +000050 if self.prev_line is not None:
Johnny Chene79a8d32011-11-04 01:05:29 +000051 print >> self, self.prev_line
52 self.prev_line = None
53
Kate Stoneb9c1b512016-09-06 20:57:50 +000054
Johnny Chene79a8d32011-11-04 01:05:29 +000055def grep(regexp):
56 # The log content to be written out once a match is found.
57 log = Log()
58
59 LOOKING_FOR_MATCH = 0
60 FOUND_LINE_MATCH = 1
61 state = LOOKING_FOR_MATCH
62
Kate Stoneb9c1b512016-09-06 20:57:50 +000063 while True:
Johnny Chene79a8d32011-11-04 01:05:29 +000064 line = sys.stdin.readline()
65 if not line:
66 return
67 line = line.splitlines()[0]
68 if state == FOUND_LINE_MATCH:
69 # At this state, we keep on accumulating lines until the separator
70 # is encountered. At which point, we can return the log content.
71 if line == separator:
Johnny Chen641e95d2012-03-05 18:25:29 +000072 log.finish()
Johnny Chene79a8d32011-11-04 01:05:29 +000073 print log.getvalue()
74 return
75 log.add_line(line)
76
77 elif state == LOOKING_FOR_MATCH:
78 if line == separator:
79 log.reset()
80 log.add_line(line)
81 # Update next state if necessary.
82 if regexp.search(line):
83 state = FOUND_LINE_MATCH
84
Kate Stoneb9c1b512016-09-06 20:57:50 +000085
Johnny Chene79a8d32011-11-04 01:05:29 +000086def main():
87 if len(sys.argv) != 2:
88 print usage
89 sys.exit(0)
90
91 regexp = re.compile(sys.argv[1])
92 grep(regexp)
Johnny Chen641e95d2012-03-05 18:25:29 +000093 sys.stdin.close()
Johnny Chene79a8d32011-11-04 01:05:29 +000094
95if __name__ == '__main__':
96 main()