Make abidiff --harmless show harmless changes in unions
[platform/upstream/libabigail.git] / gen-changelog.py
1 #!/usr/bin/env python
2 # -*- mode: python -*-
3 #
4 # This python program has been copied from
5 # https://github.com/GNOME/gnet/blob/master/gen-changelog.py
6 #
7 # It has been authored by Edward Hervey, of GStreamer fame.  I have
8 # asked his permission to copy it and re-use it here, as part of the
9 # Libabigail project.  He granted me the permission to distribute the
10 # program under the terms of the GNU Lesser Public License as
11 # published by the Free Software Foundaion; either version 2, or (at
12 # your option) any later version.
13 #
14 # Thus, this program is free software; you can redistribute it and/or
15 # modify it under the terms of the GNU Lesser General Public License
16 # as published by the Free Software Foundation; either version 2, or
17 # (at your option) any later version.
18 #
19 # This program is distributed in the hope that it will be useful, but
20 # WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22 # General Lesser Public License for more details.
23 #
24 # You should have received a copy of the GNU Lesser General Public
25 # License along with this program; see the file COPYING-LGPLV2.  If
26 # not, see <http://www.gnu.org/licenses/>.
27
28 import sys
29 import subprocess
30 import re
31
32 # Makes a GNU-Style ChangeLog from a git repository
33 # Handles git-svn repositories also
34
35 # Arguments : same as for git log
36 release_refs={}
37
38 def process_commit(lines, files):
39     # DATE NAME
40     # BLANK LINE
41     # Subject
42     # BLANK LINE
43     # ...
44     # FILES
45     fileincommit = False
46     lines = [x.strip() for x in lines if x.strip() and not x.startswith('git-svn-id')]
47     files = [x.strip() for x in files if x.strip()]
48     for l in lines:
49         if l.startswith('* '):
50             fileincommit = True
51             break
52
53     top_line = lines[0]
54     subject_line_index = 0 if lines[1].startswith('*') else 1;
55     first_cl_body_line_index = 0;
56
57     for i in range(1, len(lines)):
58         if lines[i].startswith('*'):
59             first_cl_body_line_index = i
60             break;
61
62     # Clean up top line of ChangeLog entry:
63     fields = top_line.split(' ')
64
65     # 1. remove the time and timezone stuff in "2008-05-13 07:10:28 +0000  name"
66     if fields[2].startswith('+') or fields[2].startswith('-'):
67       del fields[2]
68     if fields[1][2] == ':' and fields[1][5] == ':':
69       del fields[1]
70
71     # 2. munge at least my @src.gnome.org e-mail address...
72     if fields[-1] == '<tpm@src.gnome.org>':
73       fields[-1] = '<tim@centricular.net>'
74
75     top_line = ' '.join(fields)
76     print top_line.strip()
77     print
78
79     if subject_line_index > 0:
80         print '\t', lines[subject_line_index]
81
82     if not fileincommit:
83         for f in files:
84             print '\t* %s:' % f
85         print
86
87     if first_cl_body_line_index > 0:
88         for l in lines[first_cl_body_line_index:]:
89             if l.startswith('Signed-off-by:'):
90                 continue
91             print '\t', l
92         print
93
94 def output_commits():
95     cmd = ['git', 'log', '--pretty=format:--START-COMMIT--%H%n%ai  %an <%ae>%n%n%s%n%b%n--END-COMMIT--',
96            '--date=short', '--name-only']
97
98     start_tag = find_start_tag()
99
100     if start_tag is None:
101         cmd.extend(sys.argv[1:])
102     else:
103         cmd.extend(["%s..HEAD" % (start_tag)])
104
105     p = subprocess.Popen(args=cmd, shell=False, stdout=subprocess.PIPE)
106     buf = []
107     files = []
108     filemode = False
109     for lin in p.stdout.readlines():
110         if lin.startswith("--START-COMMIT--"):
111             if buf != []:
112                 process_commit(buf, files)
113             hash = lin[16:].strip()
114             try:
115                 rel = release_refs[hash]
116                 print "=== release %d.%d.%d ===\n" % (int(rel[0]), int(rel[1]), int(rel[2]))
117             except:
118                 pass
119             buf = []
120             files = []
121             filemode = False
122         elif lin.startswith("--END-COMMIT--"):
123             filemode = True
124         elif filemode == True:
125             files.append(lin)
126         else:
127             buf.append(lin)
128     if buf != []:
129         process_commit(buf, files)
130
131 def get_rel_tags():
132     # Populate the release_refs dict with the tags for previous releases
133     reltagre = re.compile("^([a-z0-9]{40}) refs\/tags\/GNET-([0-9]+)[-_.]([0-9]+)[-_.]([0-9]+)")
134
135     cmd = ['git', 'show-ref', '--tags', '--dereference']
136     p = subprocess.Popen(args=cmd, shell=False, stdout=subprocess.PIPE)
137     for lin in p.stdout.readlines():
138        match = reltagre.search (lin)
139        if match:
140            (sha, maj, min, nano) = match.groups()
141            release_refs[sha] = (maj, min, nano)
142
143 def find_start_tag():
144     starttagre = re.compile("^([a-z0-9]{40}) refs\/tags\/CHANGELOG_START")
145     cmd = ['git', 'show-ref', '--tags']
146     p = subprocess.Popen(args=cmd, shell=False, stdout=subprocess.PIPE)
147     for lin in p.stdout.readlines():
148        match = starttagre.search (lin)
149        if match:
150            return match.group(1)
151     return None
152
153 if __name__ == "__main__":
154     get_rel_tags()
155     output_commits()