]> git.decadent.org.uk Git - dak.git/blob - jenna
Fix database name to be a config option. Fix debian/rules typo. [Ryan Murray]
[dak.git] / jenna
1 #!/usr/bin/env python
2
3 # Generate file list which is then fed to apt-ftparchive to generate Packages and Sources files
4 # Copyright (C) 2000, 2001  James Troup <james@nocrew.org>
5 # $Id: jenna,v 1.7 2001-03-20 00:28:11 troup Exp $
6
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21 #######################################################################################
22
23 # BTAF: "GOD *DAMMIT*!!  What the FUCK happened to my free will??"
24 #
25 # -- http://www.angryflower.com/timelo.gif
26
27 #######################################################################################
28
29 import pg, string, os, sys
30 import apt_pkg
31 import db_access, utils, claire
32
33 projectB = None
34 Cnf = None
35
36 def generate_src_list(suite, component, output, dislocated_files):
37     sources = {}
38
39     suite_id = db_access.get_suite_id(suite);
40     
41     if component == "-":
42         q = projectB.query("SELECT s.source, s.version, l.path, f.filename, s.id, f.id FROM source s, src_associations sa, location l, files f WHERE sa.source = s.id AND sa.suite = '%d' AND l.id = f.location AND s.file = f.id ORDER BY s.source, s.version"
43                            % (suite_id));
44     else:
45         q = projectB.query("SELECT s.source, s.version, l.path, f.filename, s.id, f.id FROM source s, src_associations sa, location l, component c, files f WHERE lower(c.name) = '%s' AND (c.id = l.component OR l.component = NULL) AND sa.source = s.id AND sa.suite = '%d' AND l.id = f.location AND s.file = f.id ORDER BY s.source, s.version"
46                            % (component, suite_id));
47     entries = q.getresult();
48     for entry in entries:
49         source = entry[0]
50         version = entry[1]
51         filename = entry[2]+entry[3];
52         id = entry[4]
53         add_new = 0
54         file_id = entry[5];
55         if dislocated_files.has_key(file_id):
56             filename = dislocated_files[file_id];
57         if os.path.exists(filename):
58             if sources.has_key(source):
59                 if apt_pkg.VersionCompare(sources[source]["version"], version) == -1:
60                     if not Cnf.Find("Suite::%s::Untouchable" % (suite)):
61                         print "deleting %s (%s) in favour of newer version %s..." % (source, sources[source]["version"], version)
62                         projectB.query("DELETE FROM src_associations WHERE source = %s AND suite = %d" % (sources[source]["id"], suite_id))
63                     else:
64                         if Cnf.Find("Jenna::Options::Verbose"):
65                             print "[untouchable] would delete %s (%s) in favour of newer version %s..." % (source, sources[source]["version"], version)
66                     sources[source] = { "id": id, "version": version, "filename": filename }
67                 else:
68                     if not Cnf.Find("Suite::%s::Untouchable" % (suite)):
69                         print "deleting %s (%s) in favour of newer version %s..." % (source, version, sources[source]["version"])
70                         projectB.query("DELETE FROM src_associations WHERE source = %s AND suite = %d" % (id, suite_id))
71                     else:
72                         if Cnf.Find("Jenna::Options::Verbose"):
73                             print "[untouchable] would delete %s (%s) in favour of newer version %s..." % (source, version, sources[source]["version"])
74             else:
75                 sources[source] = { "id": id, "version": version, "filename": filename }
76         else:
77             if not Cnf.Find("Suite::%s::Untouchable" % (suite)):
78                 sys.stderr.write("WARNING: deleting %s because it doesn't exist.\n" % (filename));
79                 projectB.query("DELETE FROM src_associations WHERE source = %s AND suite = %d" % (id, suite_id))
80
81     # Write the list of files out
82     source_keys = sources.keys();
83     source_keys.sort();
84     for source in source_keys:
85         output.write(sources[source]["filename"]+'\n')
86     
87 def generate_bin_list(suite, component, architecture, output, type, dislocated_files):
88     packages = {}
89
90     suite_id = db_access.get_suite_id(suite);
91     
92     if component == "-":
93         q = projectB.query("SELECT b.package, b.version, l.path, f.filename, b.id, f.id FROM architecture a, binaries b, bin_associations ba, location l, files f WHERE ( a.arch_string = '%s' OR a.arch_string = 'all' ) AND a.id = b.architecture AND ba.bin = b.id AND ba.suite = '%d' AND l.id = f.location AND b.file = f.id AND b.type = '%s' ORDER BY b.package, b.version, a.arch_string" % (architecture, suite_id, type));
94     else:
95         q = projectB.query("SELECT b.package, b.version, l.path, f.filename, b.id, f.id FROM architecture a, binaries b, bin_associations ba, location l, component c, files f WHERE lower(c.name) = '%s' AND (c.id = l.component OR l.component = NULL) AND (a.arch_string = '%s' OR a.arch_string = 'all') AND a.id = b.architecture AND ba.bin = b.id AND ba.suite = '%d' AND l.id = f.location AND b.file = f.id AND b.type = '%s' ORDER BY b.package, b.version, a.arch_string" % (component, architecture, suite_id, type));
96     entries = q.getresult();
97     for entry in entries:
98         package = entry[0]
99         version = entry[1]
100         filename = entry[2]+entry[3];
101         id = entry[4]
102         add_new = 0
103         file_id = entry[5];
104         if dislocated_files.has_key(file_id):
105             filename = dislocated_files[file_id];
106         
107         if os.path.exists(filename):
108             if packages.has_key(package):
109                 if apt_pkg.VersionCompare(packages[package]["version"], version) == -1:
110                     if not Cnf.Find("Suite::%s::Untouchable" % (suite)):
111                         print "deleting %s (%s) in favour of newer version %s..." % (package, packages[package]["version"], version)
112                         projectB.query("DELETE FROM bin_associations WHERE bin = %s AND suite = %d" % (packages[package]["id"], suite_id))
113                     else:
114                         if Cnf.Find("Jenna::Options::Verbose"):
115                             print "[untouchable] would delete %s (%s) in favour of newer version %s..." % (package, packages[package]["version"], version)
116                     packages[package] = { "id": id, "version": version, "filename": filename }
117                 else:
118                     if not Cnf.Find("Suite::%s::Untouchable" % (suite)):
119                         print "deleting %s (%s) in favour of newer version %s..." % (package, version, packages[package]["version"])
120                         projectB.query("DELETE FROM bin_associations WHERE bin = %s AND suite = %d" % (id, suite_id))
121                     else:
122                         if Cnf.Find("Jenna::Options::Verbose"):
123                             print "[untochable] would delete %s (%s) in favour of newer version %s..." % (package, version, packages[package]["version"])
124             else:
125                 packages[package] = { "id": id, "version": version, "filename": filename }
126         else:
127             if not Cnf.Find("Suite::%s::Untouchable" % (suite)):
128                 sys.stderr.write("WARNING: deleting %s because it doesn't exist.\n" % (filename));
129                 projectB.query("DELETE FROM bin_associations WHERE bin = %s AND suite = %d" % (id, suite_id))
130
131     # Write the list of files out
132     package_keys = packages.keys();
133     package_keys.sort();
134     for package in package_keys:
135         output.write(packages[package]["filename"]+'\n')
136     
137     
138
139 def main():
140     global Cnf, projectB;
141     dislocated_files = {};
142     
143     apt_pkg.init();
144     
145     Cnf = apt_pkg.newConfiguration();
146     apt_pkg.ReadConfigFileISC(Cnf,utils.which_conf_file());
147
148     Arguments = [('a',"architecture","Jenna::Options::Architecture", "HasArg"),
149                  ('c',"component","Jenna::Options::Component", "HasArg"),
150                  ('d',"debug","Jenna::Options::Debug", "IntVal"),
151                  ('h',"help","Jenna::Options::Help"),
152                  ('s',"suite", "Jenna::Options::Suite", "HasArg"),
153                  ('v',"verbose","Jenna::Options::Verbose"),
154                  ('V',"version","Jenna::Options::Version")];
155
156     apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv);
157
158     projectB = pg.connect(Cnf["DB::Name"], Cnf["DB::Host"], int(Cnf["DB::Port"]));
159     db_access.init(Cnf, projectB);
160
161     if Cnf["Jenna::Options::Suite"] == "":
162         Cnf["Jenna::Options::Suite"] = string.join(Cnf.SubTree("Suite").List());
163     for suite in string.split(Cnf["Jenna::Options::Suite"]):
164         suite = string.lower(suite);
165         if suite == 'stable':
166             dislocated_files = claire.find_dislocated_stable(Cnf, projectB);
167         components = Cnf["Jenna::Options::Component"];
168         if not Cnf.has_key("Suite::%s::Components" % (suite)):
169             components = "-";
170         if components == "":
171             components = string.join(Cnf.SubTree("Suite::%s::Components" % (suite)).List());
172         for component in string.split(components):
173             component = string.lower(component)
174             architectures = Cnf["Jenna::Options::Architecture"];
175             if architectures == "":
176                 architectures = string.join(Cnf.SubTree("Suite::%s::Architectures" % (suite)).List());
177             for architecture in string.split(architectures):
178                 architecture = string.lower(architecture)
179                 if architecture == "all":
180                     continue
181                 if architecture == "source":
182                     print "Processing dists/%s/%s/%s..." % (suite, component, architecture);
183                     output = utils.open_file("%s/%s_%s_%s.list" % (Cnf["Dir::ListsDir"], suite, component, architecture), "w")
184                     generate_src_list(suite, component, output, dislocated_files);
185                     output.close();
186                 else:
187                     print "Processing dists/%s/%s/binary-%s..." % (suite, component, architecture);
188                     output = utils.open_file("%s/%s_%s_binary-%s.list" % (Cnf["Dir::ListsDir"], suite, component, architecture), "w");
189                     generate_bin_list(suite, component, architecture, output, "deb", dislocated_files);
190                     output.close();
191                     if component == "main" and (suite == "unstable" or suite == "testing"): # FIXME: must be a cleaner way to say debian-installer is main only?
192                         print "Processing dists/%s/%s/debian-installer/binary-%s..." % (suite,component, architecture);
193                         output = utils.open_file("%s/%s_%s_debian-installer_binary-%s.list" % (Cnf["Dir::ListsDir"], suite, component, architecture), "w");
194                         generate_bin_list(suite, component, architecture, output, "udeb", dislocated_files);
195                         output.close();
196
197 if __name__ == '__main__':
198     main()
199