]> git.decadent.org.uk Git - dak.git/blob - dak/make_changelog.py
Merge remote branch 'drkranz/master' into merge
[dak.git] / dak / make_changelog.py
1 #!/usr/bin/env python
2
3 """
4 Generate changelog entry between two suites
5
6 @contact: Debian FTP Master <ftpmaster@debian.org>
7 @copyright: 2010 Luca Falavigna <dktrkranz@debian.org>
8 @license: GNU General Public License version 2 or later
9 """
10
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2 of the License, or
14 # (at your option) any later version.
15
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 # GNU General Public License for more details.
20
21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, write to the Free Software
23 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
25 ################################################################################
26
27 # <bdefreese> !dinstall
28 # <dak> bdefreese: I guess the next dinstall will be in 0hr 1min 35sec
29 # <bdefreese> Wow I have great timing
30 # <DktrKranz> dating with dinstall, part II
31 # <bdefreese> heh
32 # <Ganneff> dating with that monster? do you have good combat armor?
33 # <bdefreese> +5 Plate :)
34 # <Ganneff> not a good one then
35 # <Ganneff> so you wont even manage to bypass the lesser monster in front, unchecked
36 # <DktrKranz> asbesto belt
37 # <Ganneff> helps only a step
38 # <DktrKranz> the Ultimate Weapon: cron_turned_off
39 # <bdefreese> heh
40 # <Ganneff> thats debadmin limited
41 # <Ganneff> no option for you
42 # <DktrKranz> bdefreese: it seems ftp-masters want dinstall to sexual harass us, are you good in running?
43 # <Ganneff> you can run but you can not hide
44 # <bdefreese> No, I'm old and fat :)
45 # <Ganneff> you can roll but you can not hide
46 # <Ganneff> :)
47 # <bdefreese> haha
48 # <DktrKranz> damn dinstall, you racist bastard
49
50 ################################################################################
51
52 import sys
53 import apt_pkg
54 from daklib.dbconn import *
55 from daklib import utils
56
57 ################################################################################
58
59 def usage (exit_code=0):
60     print """Generate changelog between two suites
61
62        Usage:
63        make-changelog -s <suite> -b <base_suite> [OPTION]...
64        make-changelog -T
65
66 Options:
67
68   -h, --help                show this help and exit
69   -s, --suite               suite providing packages to compare
70   -b, --base-suite          suite to be taken as reference for comparison
71   -n, --binnmu              display binNMUs uploads instead of source ones
72   -T, --testing             display changes entering testing"""
73
74     sys.exit(exit_code)
75
76 def get_source_uploads(suite, base_suite, session):
77     """
78     Returns changelogs for source uploads where version is newer than base.
79     """
80
81     query = """WITH base AS (
82                  SELECT source, max(version) AS version
83                  FROM source_suite
84                  WHERE suite_name = :base_suite
85                  GROUP BY source
86                  UNION (SELECT source, CAST(0 AS debversion) AS version
87                  FROM source_suite
88                  WHERE suite_name = :suite
89                  EXCEPT SELECT source, CAST(0 AS debversion) AS version
90                  FROM source_suite
91                  WHERE suite_name = :base_suite
92                  ORDER BY source)),
93                cur_suite AS (
94                  SELECT source, max(version) AS version
95                  FROM source_suite
96                  WHERE suite_name = :suite
97                  GROUP BY source)
98                SELECT DISTINCT c.source, c.version, c.changelog
99                FROM changelogs c
100                JOIN base b ON b.source = c.source
101                JOIN cur_suite cs ON cs.source = c.source
102                WHERE c.version > b.version
103                AND c.version <= cs.version
104                AND c.architecture LIKE '%source%'
105                ORDER BY c.source, c.version DESC"""
106
107     return session.execute(query, {'suite': suite, 'base_suite': base_suite})
108
109 def get_binary_uploads(suite, base_suite, session):
110     """
111     Returns changelogs for binary uploads where version is newer than base.
112     """
113
114     query = """WITH base as (
115                  SELECT s.source, max(b.version) AS version, a.arch_string
116                  FROM source s
117                  JOIN binaries b ON b.source = s.id
118                  JOIN bin_associations ba ON ba.bin = b.id
119                  JOIN architecture a ON a.id = b.architecture
120                  WHERE ba.suite = (
121                    SELECT id
122                    FROM suite
123                    WHERE suite_name = :base_suite)
124                  GROUP BY s.source, a.arch_string),
125                cur_suite as (
126                  SELECT s.source, max(b.version) AS version, a.arch_string
127                  FROM source s
128                  JOIN binaries b ON b.source = s.id
129                  JOIN bin_associations ba ON ba.bin = b.id
130                  JOIN architecture a ON a.id = b.architecture
131                  WHERE ba.suite = (
132                    SELECT id
133                    FROM suite
134                    WHERE suite_name = :suite)
135                  GROUP BY s.source, a.arch_string)
136                SELECT DISTINCT c.source, c.version, c.architecture, c.changelog
137                FROM changelogs c
138                JOIN base b on b.source = c.source
139                JOIN cur_suite cs ON cs.source = c.source
140                WHERE c.version > b.version
141                AND c.version <= cs.version
142                AND c.architecture = b.arch_string
143                AND c.architecture = cs.arch_string
144                ORDER BY c.source, c.version DESC, c.architecture"""
145
146     return session.execute(query, {'suite': suite, 'base_suite': base_suite})
147
148 def testing_summary(summary, session):
149     """
150     Returns changes introduced in packages entering testing.
151     """
152
153     query =  'SELECT source, changelog FROM changelogs WHERE'
154     fd = open(summary, 'r')
155     for package in fd.read().splitlines():
156         package = package.split()
157         if package[1] != package[2]:
158             if package[1] == '(not_in_testing)':
159                 package[1] = 0
160             query += " source = '%s' AND version > '%s' AND version <= '%s'" \
161                      % (package[0], package[1], package[2])
162             query += " AND architecture LIKE '%source%' OR"
163     fd.close()
164     query += ' False ORDER BY source, version DESC;'
165
166     return session.execute(query)
167
168 def display_changes(uploads, index):
169     prev_upload = None
170     for upload in uploads:
171         if prev_upload and prev_upload != upload[0]:
172             print
173         print upload[index]
174         prev_upload = upload[0]
175
176 def main():
177     Cnf = utils.get_conf()
178     Arguments = [('h','help','Make-Changelog::Options::Help'),
179                  ('s','suite','Make-Changelog::Options::Suite','HasArg'),
180                  ('b','base-suite','Make-Changelog::Options::Base-Suite','HasArg'),
181                  ('n','binnmu','Make-Changelog::Options::binNMU'),
182                  ('T', 'testing','Make-Changelog::Options::Testing')]
183
184     for i in ['help', 'suite', 'base-suite', 'binnmu', 'testing']:
185         if not Cnf.has_key('Make-Changelog::Options::%s' % (i)):
186             Cnf['Make-Changelog::Options::%s' % (i)] = ''
187
188     apt_pkg.ParseCommandLine(Cnf, Arguments, sys.argv)
189     Options = Cnf.SubTree('Make-Changelog::Options')
190     suite = Cnf['Make-Changelog::Options::Suite']
191     base_suite = Cnf['Make-Changelog::Options::Base-Suite']
192     binnmu = Cnf['Make-Changelog::Options::binNMU']
193     testing = Cnf['Make-Changelog::Options::Testing']
194
195     if Options['help'] or not (suite and base_suite) and not testing:
196         usage()
197
198     for s in suite, base_suite:
199         if not testing and not get_suite(s):
200             utils.fubar('Invalid suite "%s"' % s)
201
202     session = DBConn().session()
203
204     if testing:
205         display_changes(testing_summary(Cnf['Changelogs::Testing'], session), 1)
206     elif binnmu:
207         display_changes(get_binary_uploads(suite, base_suite, session), 3)
208     else:
209         display_changes(get_source_uploads(suite, base_suite, session), 2)
210
211     session.commit()
212
213 if __name__ == '__main__':
214     main()