Package dak :: Module make_maintainers
[hide private]
[frames] | no frames]

Source Code for Module dak.make_maintainers

  1  #! /usr/bin/env python3 
  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  # This program is free software; you can redistribute it and/or modify 
 13  # it under the terms of the GNU General Public License as published by 
 14  # the Free Software Foundation; either version 2 of the License, or 
 15  # (at your option) any later version. 
 16   
 17  # This program is distributed in the hope that it will be useful, 
 18  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 19  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 20  # GNU General Public License for more details. 
 21   
 22  # You should have received a copy of the GNU General Public License 
 23  # along with this program; if not, write to the Free Software 
 24  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 25   
 26  ################################################################################ 
 27   
 28  # ``As opposed to "Linux sucks. Respect my academic authoritah, damn 
 29  #   you!" or whatever all this hot air amounts to.'' 
 30  #                             -- ajt@ in _that_ thread on debian-devel@ 
 31   
 32  ################################################################################ 
 33   
 34  import sys 
 35   
 36  import apt_pkg 
 37  from sqlalchemy.sql import text 
 38   
 39  from daklib import daklog 
 40  from daklib.config import Config 
 41  from daklib.dbconn import Archive, DBConn 
 42  from daklib.regexes import re_comments 
 43   
 44  ################################################################################ 
 45   
 46   
47 -def usage(exit_code=0):
48 print( 49 """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 ) 58 sys.exit(exit_code)
59 60 61 ################################################################################ 62 63
64 -def format(package, person):
65 """Return a string nicely formatted for writing to the output file.""" 66 return "%-20s %s\n" % (package, person)
67 68 69 ################################################################################ 70 71
72 -def main():
73 cnf = Config() 74 75 Arguments = [ 76 ("h", "help", "Make-Maintainers::Options::Help"), 77 ("a", "archive", "Make-Maintainers::Options::Archive", "HasArg"), 78 ("s", "source", "Make-Maintainers::Options::Source"), 79 ("p", "print", "Make-Maintainers::Options::Print"), 80 ] 81 for i in ["Help", "Source", "Print"]: 82 key = "Make-Maintainers::Options::%s" % i 83 if key not in cnf: 84 cnf[key] = "" 85 86 extra_files = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) 87 Options = cnf.subtree("Make-Maintainers::Options") 88 89 if Options["Help"] or not Options.get("Archive"): 90 usage() 91 92 Logger = daklog.Logger("make-maintainers") 93 session = DBConn().session() 94 95 archive = session.query(Archive).filter_by(archive_name=Options["Archive"]).one() 96 97 # dictionary packages to maintainer names 98 maintainers = dict() 99 # dictionary packages to list of uploader names 100 uploaders = dict() 101 102 query = session.execute( 103 text( 104 """ 105 SELECT 106 bs.package, 107 bs.name AS maintainer, 108 array_agg(mu.name) OVER ( 109 PARTITION BY bs.source, bs.id 110 ORDER BY mu.name 111 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING 112 ) AS uploaders 113 FROM ( 114 SELECT DISTINCT ON (package) 115 * 116 FROM ( 117 SELECT 118 s.id AS source, 119 0 AS id, 120 s.source AS package, 121 s.version, 122 m.name 123 FROM 124 source AS s INNER JOIN 125 maintainer AS m ON s.maintainer = m.id INNER JOIN 126 src_associations AS sa ON s.id = sa.source INNER JOIN 127 suite on sa.suite = suite.id 128 WHERE 129 suite.archive_id = :archive_id 130 UNION SELECT 131 b.source, 132 b.id, 133 b.package, 134 b.version, 135 m.name 136 FROM 137 binaries AS b INNER JOIN 138 maintainer AS m ON b.maintainer = m.id INNER JOIN 139 bin_associations AS ba ON b.id = ba.bin INNER JOIN 140 suite on ba.suite = suite.id 141 WHERE 142 NOT :source_only AND 143 suite.archive_id = :archive_id 144 ) AS bs 145 ORDER BY package, version desc 146 ) AS bs LEFT OUTER JOIN 147 -- find all uploaders for a given source 148 src_uploaders AS su ON bs.source = su.source LEFT OUTER JOIN 149 maintainer AS mu ON su.maintainer = mu.id 150 """ 151 ).params( 152 archive_id=archive.archive_id, 153 source_only="True" if Options["Source"] else "False", 154 ) 155 ) 156 157 Logger.log(["database"]) 158 for entry in query: 159 maintainers[entry["package"]] = entry["maintainer"] 160 if all(x is None for x in entry["uploaders"]): 161 uploaders[entry["package"]] = [""] 162 else: 163 uploaders[entry["package"]] = entry["uploaders"] 164 165 Logger.log(["files"]) 166 # Process any additional Maintainer files (e.g. from pseudo 167 # packages) 168 for filename in extra_files: 169 with open(filename) as extrafile: 170 for line in extrafile.readlines(): 171 line = re_comments.sub("", line).strip() 172 if line == "": 173 continue 174 (package, maintainer) = line.split(None, 1) 175 maintainers[package] = maintainer 176 uploaders[package] = [maintainer] 177 178 if Options["Print"]: 179 for package in sorted(maintainers): 180 print(format(package, maintainers[package]), end="") 181 else: 182 with open("Maintainers", "w") as maintainer_file, open( 183 "Uploaders", "w" 184 ) as uploader_file: 185 for package in sorted(uploaders): 186 maintainer_file.write(format(package, maintainers[package])) 187 for uploader in uploaders[package]: 188 uploader_file.write(format(package, uploader)) 189 190 Logger.close()
191 192 193 ############################################################################### 194 195 196 if __name__ == "__main__": 197 main() 198