1
2
3 """
4 Generate Maintainers file used by e.g. the Debian Bug Tracking System
5 @contact: Debian FTP Master <ftpmaster@debian.org>
6 @copyright: 2000, 2001, 2002, 2003, 2004, 2006 James Troup <james@nocrew.org>
7 @copyright: 2011 Torsten Werner <twerner@debian.org>
8 @license: GNU General Public License version 2 or later
9
10 """
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 from daklib import daklog
35 from daklib import utils
36 from daklib.config import Config
37 from daklib.dbconn import *
38 from daklib.regexes import re_comments
39
40 import apt_pkg
41 import sys
42
43 from sqlalchemy.sql import text
44
45
46
47
49 print("""Usage: dak make-maintainers [OPTION] -a ARCHIVE EXTRA_FILE[...]
50 Generate an index of packages <=> Maintainers / Uploaders.
51
52 -a, --archive=ARCHIVE archive to take packages from
53 -s, --source output source packages only
54 -p, --print print package list to stdout instead of writing it to files
55 -h, --help show this help and exit
56 """)
57 sys.exit(exit_code)
58
59
60
61
65
66
67
68
70 cnf = Config()
71
72 Arguments = [('h', "help", "Make-Maintainers::Options::Help"),
73 ('a', "archive", "Make-Maintainers::Options::Archive", 'HasArg'),
74 ('s', "source", "Make-Maintainers::Options::Source"),
75 ('p', "print", "Make-Maintainers::Options::Print")]
76 for i in ["Help", "Source", "Print"]:
77 key = "Make-Maintainers::Options::%s" % i
78 if key not in cnf:
79 cnf[key] = ""
80
81 extra_files = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv)
82 Options = cnf.subtree("Make-Maintainers::Options")
83
84 if Options["Help"] or not Options.get('Archive'):
85 usage()
86
87 Logger = daklog.Logger('make-maintainers')
88 session = DBConn().session()
89
90 archive = session.query(Archive).filter_by(archive_name=Options['Archive']).one()
91
92
93 maintainers = dict()
94
95 uploaders = dict()
96
97 query = session.execute(text('''
98 SELECT
99 bs.package,
100 bs.name AS maintainer,
101 array_agg(mu.name) OVER (
102 PARTITION BY bs.source, bs.id
103 ORDER BY mu.name
104 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
105 ) AS uploaders
106 FROM (
107 SELECT DISTINCT ON (package)
108 *
109 FROM (
110 SELECT
111 s.id AS source,
112 0 AS id,
113 s.source AS package,
114 s.version,
115 m.name
116 FROM
117 source AS s INNER JOIN
118 maintainer AS m ON s.maintainer = m.id INNER JOIN
119 src_associations AS sa ON s.id = sa.source INNER JOIN
120 suite on sa.suite = suite.id
121 WHERE
122 suite.archive_id = :archive_id
123 UNION SELECT
124 b.source,
125 b.id,
126 b.package,
127 b.version,
128 m.name
129 FROM
130 binaries AS b INNER JOIN
131 maintainer AS m ON b.maintainer = m.id INNER JOIN
132 bin_associations AS ba ON b.id = ba.bin INNER JOIN
133 suite on ba.suite = suite.id
134 WHERE
135 NOT :source_only AND
136 suite.archive_id = :archive_id
137 ) AS bs
138 ORDER BY package, version desc
139 ) AS bs LEFT OUTER JOIN
140 -- find all uploaders for a given source
141 src_uploaders AS su ON bs.source = su.source LEFT OUTER JOIN
142 maintainer AS mu ON su.maintainer = mu.id
143 ''').params(
144 archive_id=archive.archive_id,
145 source_only="True" if Options["Source"] else "False"
146 ))
147
148 Logger.log(['database'])
149 for entry in query:
150 maintainers[entry['package']] = entry['maintainer']
151 if all(x is None for x in entry['uploaders']):
152 uploaders[entry['package']] = ['']
153 else:
154 uploaders[entry['package']] = entry['uploaders']
155
156 Logger.log(['files'])
157
158
159 for filename in extra_files:
160 with open(filename) as extrafile:
161 for line in extrafile.readlines():
162 line = re_comments.sub('', line).strip()
163 if line == "":
164 continue
165 (package, maintainer) = line.split(None, 1)
166 maintainers[package] = maintainer
167 uploaders[package] = [maintainer]
168
169 if Options["Print"]:
170 for package in sorted(maintainers):
171 print(format(package, maintainers[package]), end='')
172 else:
173 with open('Maintainers', 'w') as maintainer_file, open('Uploaders', 'w') as uploader_file:
174 for package in sorted(uploaders):
175 maintainer_file.write(format(package, maintainers[package]))
176 for uploader in uploaders[package]:
177 uploader_file.write(format(package, uploader))
178
179 Logger.close()
180
181
182
183
184 if __name__ == '__main__':
185 main()
186