]> git.donarmstrong.com Git - lilypond.git/blob - buildscripts/git-update-changelog.py
*** empty log message ***
[lilypond.git] / buildscripts / git-update-changelog.py
1 #!/usr/bin/python
2
3 import time
4 import os
5 import re
6 import optparse
7
8 def read_pipe (x):
9     print 'pipe', x
10     return os.popen (x).read ()
11
12 class Commit:
13     def __init__ (self, dict):
14         for v in ('message',
15                   'date',
16                   'author',
17                   'committish'):
18             self.__dict__[v] = dict[v]
19
20         # Sat Oct 28 18:52:30 2006 +0200
21         
22         self.date = ' '.join  (self.date.split (' ')[:-1])
23         self.date = time.strptime (self.date, '%a %b %d %H:%M:%S %Y')
24
25         m = re.search ('(.*)<(.*)>', self.author)
26         self.email = m.group (2)
27         self.name = m.group (1)
28
29     def touched_files (self):
30
31         files = []
32         def note_file (x):
33             files.append (x.group (1))
34             return ''
35             
36         diff = read_pipe ('git show %s' % self.committish)
37         re.sub ('\n--- a/([^\n]+)\n',
38                 note_file, diff)
39         re.sub('\n--- /dev/null\n\\+\\+\\+ b/([^\n]+)',
40                note_file, diff)
41
42         return files
43
44 def parse_commit_log (log):
45     print log
46     
47     committish = re.search ('^([^\n]+)', log).group (1)
48     author = re.search ('\nAuthor:\s+([^\n]+)', log).group (1)
49     date_match = re.search ('\nDate:\s+([^\n]+)', log)
50     date = date_match.group (1)
51     log = log[date_match.end (1):]
52
53     message = re.sub ("\n *", '', log)
54     message = message.strip ()
55
56     c = Commit (locals ())
57     return c
58
59 def parse_add_changes (from_commit):
60     
61     log = read_pipe ('git log %(from_commit)s..' % locals ())
62
63     log = log[len ('commit '):]
64     log = log.strip ()
65
66     if not log:
67         return []
68         
69     commits = map (parse_commit_log, re.split ('\ncommit ', log))
70     
71     return commits
72
73
74 def header (commit):
75     return '%d-%02d-%02d  %s  <%s>\n' % (commit.date[:3] + (commit.name, commit.email))
76
77 def changelog_body (commit):
78
79     s = ''
80     s += "\ngit commit %s\n" % commit.committish    
81     s += ''.join ('\n* %s: ' % f for f in commit.touched_files())
82     s += '\n' + commit.message
83     
84     s = s.replace ('\n', '\n\t')
85     s += '\n'
86     return s
87         
88 def find_last_checked_in_commit (log):
89     m = re.match ('^(\\d+-\\d+-\\d+)[^\n]+\n*\tgit commit ([a-f0-9]+)', log)
90     
91     if m:
92         return (m.group (1), m.group (2))
93
94     return None
95
96
97
98
99 def main ():
100     p = optparse.OptionParser ("usage git-update-changelog.py --options")
101     p.add_option ("--start",
102                   action='store',
103                   default='',
104                   dest="start",
105                   help="start of log messages to merge.")
106
107     (options, args) = p.parse_args ()
108     
109     log = open ('ChangeLog').read ()
110
111     if not options.start:
112         (time, id) = find_last_checked_in_commit (log)
113         options.start = id
114
115         print 'processing commits from ', id, options.start
116
117     commits = parse_add_changes (options.start)
118     if not commits:
119         return
120     
121     new_log = ''
122     last_commit = None
123
124     first = header (commits[0]) + '\n'
125     if first == log[:len (first)]:
126         log = log[len (first):]
127     
128     for c in commits:
129         if c.touched_files () == ['ChangeLog']:
130             continue
131         
132         if (last_commit
133             and c.author != last_commit.author
134             and c.date[:3] != last_commit.date[:3]):
135
136             new_log += header (last_commit)
137
138         new_log += changelog_body (c)  
139         last_commit = c
140         
141     new_log = header (last_commit) + new_log + '\n'
142
143     log = new_log + log
144     try:
145         os.unlink ('ChangeLog~')
146     except IOError:
147         pass
148     
149     os.rename ('ChangeLog', 'ChangeLog~')
150     open ('ChangeLog', 'w').write (log)
151     
152 main ()
153     
154     
155