Generate a ChangeLog before make dist
[claws.git] / tools / gitlog2changelog.py
1 #!/usr/bin/python
2 # Copyright 2008 Marcus D. Hanwell <marcus@cryos.org>
3 # Distributed under the terms of the GNU General Public License v2 or later
4
5 import string, re, os, sys
6
7 curRev = ""
8 prevVer = ""
9
10 if len(sys.argv) == 3:
11     curRev = sys.argv[2]
12     prevVer = sys.argv[1]
13 else:
14     curRevCmd = os.popen("git describe")
15     curRev = curRevCmd.read()
16     curRev = curRev[0:len(curRev)-1]
17     curRevCmd.close()
18     if len(sys.argv) == 2:
19         prevVer = sys.argv[1]
20     else:
21         prevVer = re.split('-', curRev, 1)[0]
22
23 # Execute git log with the desired command line options.
24 fin = os.popen('git log ' + prevVer + '..' + curRev +' --summary --stat --no-merges --date=short', 'r')
25 # Create a ChangeLog file in the current directory.
26 fout = sys.stdout
27
28 # Set up the loop variables in order to locate the blocks we want
29 authorFound = False
30 dateFound = False
31 messageFound = False
32 filesFound = False
33 message = ""
34 commit = ""
35 messageNL = False
36 files = ""
37 prevAuthorLine = ""
38
39 # The main part of the loop
40 for line in fin:
41     # The commit line marks the start of a new commit object.
42     if re.match('^commit', line) >= 0:
43         # Start all over again...
44         authorFound = False
45         dateFound = False
46         messageFound = False
47         messageNL = False
48         message = ""
49         filesFound = False
50         files = ""
51         commitCmd = os.popen("git describe "+re.split(' ', line, 1)[1])
52         commit = commitCmd.read()
53         commitCmd.close()
54         commit = commit[0:len(commit)-1]
55         continue
56     # Match the author line and extract the part we want
57     elif re.match('^Author:', line) >=0:
58         authorList = re.split(': ', line, 1)
59         author = re.split('<', authorList[1], 1)[0]
60         author = "[" + author[0:len(author)-1]+"]"
61         authorFound = True
62     # Match the date line
63     elif re.match('^Date:', line) >= 0:
64         dateList = re.split(':   ', line, 1)
65         date = dateList[1]
66         date = date[0:len(date)-1]
67         dateFound = True
68     # The svn-id lines are ignored
69     elif re.match('    git-svn-id:', line) >= 0:
70         continue
71     # The sign off line is ignored too
72     elif re.search('Signed-off-by', line) >= 0:
73         continue
74     # Extract the actual commit message for this commit
75     elif authorFound & dateFound & messageFound == False:
76         # Find the commit message if we can
77         if len(line) == 1:
78             if messageNL:
79                 messageFound = True
80             else:
81                 messageNL = True
82         elif len(line) == 4:
83             messageFound = True
84         else:
85             if len(message) == 0:
86                 message = message + line.strip()
87             else:
88                 message = message + " " + line.strip()
89     # If this line is hit all of the files have been stored for this commit
90     elif re.search('files changed', line) >= 0:
91         filesFound = True
92         continue
93     # Collect the files for this commit. FIXME: Still need to add +/- to files
94     elif authorFound & dateFound & messageFound:
95         fileList = re.split(' \| ', line, 2)
96         if len(fileList) > 1:
97             if len(files) > 0:
98                 files = files + "\n\t* " + fileList[0].strip()
99             else:
100                 files = "\t* " + fileList[0].strip()
101     # All of the parts of the commit have been found - write out the entry
102     if authorFound & dateFound & messageFound & filesFound:
103         # First the author line, only outputted if it is the first for that
104         # author on this day
105         authorLine = date + "  " + author
106         if len(prevAuthorLine) != 0:
107             fout.write("\n");
108         fout.write(authorLine + " " + commit + "\n\n")
109
110         # Assemble the actual commit message line(s) and limit the line length
111         # to 80 characters.
112         commitLine = message
113         i = 0
114         commit = ""
115         while i < len(commitLine):
116             if len(commitLine) < i + 70:
117                 commit = commit + "\n\t\t" + commitLine[i:len(commitLine)]
118                 break
119             index = commitLine.rfind(' ', i, i+70)
120             if index > i:
121                 commit = commit + "\n\t\t" + commitLine[i:index]
122                 i = index+1
123             else:
124                 commit = commit + "\n\t\t" + commitLine[i:70]
125                 i = i+71
126
127         # Write out the commit line
128         fout.write(files + "\t\t" + commit + "\n")
129
130         #Now reset all the variables ready for a new commit block.
131         authorFound = False
132         dateFound = False
133         messageFound = False
134         messageNL = False
135         message = ""
136         filesFound = False
137         files = ""
138         prevAuthorLine = authorLine
139
140 # Close the input and output lines now that we are finished.
141 fin.close()
142 fout.close()