3 # Generate file list which is then fed to apt-ftparchive to generate Packages and Sources files
4 # Copyright (C) 2000 James Troup <james@nocrew.org>
5 # $Id: jenna,v 1.2 2000-12-05 04:27:48 troup Exp $
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.
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.
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
21 #######################################################################################
23 # BTAF: "GOD *DAMMIT*!! What the FUCK happened to my free will??"
25 # -- http://www.angryflower.com/timelo.gif
27 #######################################################################################
29 import pg, string, os, sys
31 import db_access, utils, claire
36 def generate_src_list(suite, component, output, dislocated_files):
39 suite_id = db_access.get_suite_id(suite);
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"
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"
46 % (component, suite_id));
47 entries = q.getresult();
51 filename = entry[2]+entry[3];
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))
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 }
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))
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"])
75 sources[source] = { "id": id, "version": version, "filename": filename }
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))
81 # Write the list of files out
82 source_keys = sources.keys();
84 for source in source_keys:
85 output.write(sources[source]["filename"]+'\n')
87 def generate_bin_list(suite, component, architecture, output, type, dislocated_files):
90 suite_id = db_access.get_suite_id(suite);
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'" % (architecture, suite_id, type));
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'" % (component, architecture, suite_id, type));
96 entries = q.getresult();
100 filename = entry[2]+entry[3];
104 if dislocated_files.has_key(file_id):
105 filename = dislocated_files[file_id];
107 # Hack to handle screwed up sid distro [FIXME: this may have issues, remove ASAP]
108 if not os.path.exists(filename):
109 sid_filename = string.replace(filename, "/woody/", "/potato/");
110 if os.path.exists(sid_filename):
111 filename = sid_filename;
113 if os.path.exists(filename):
114 if packages.has_key(package):
115 if apt_pkg.VersionCompare(packages[package]["version"], version) == -1:
116 if not Cnf.Find("Suite::%s::Untouchable" % (suite)):
117 print "deleting %s (%s) in favour of newer version %s..." % (package, packages[package]["version"], version)
118 projectB.query("DELETE FROM bin_associations WHERE bin = %s AND suite = %d" % (packages[package]["id"], suite_id))
120 if Cnf.Find("Jenna::Options::Verbose"):
121 print "[untouchable] would delete %s (%s) in favour of newer version %s..." % (package, packages[package]["version"], version)
122 packages[package] = { "id": id, "version": version, "filename": filename }
124 if not Cnf.Find("Suite::%s::Untouchable" % (suite)):
125 print "deleting %s (%s) in favour of newer version %s..." % (package, version, packages[package]["version"])
126 projectB.query("DELETE FROM bin_associations WHERE bin = %s AND suite = %d" % (id, suite_id))
128 if Cnf.Find("Jenna::Options::Verbose"):
129 print "[untochable] would delete %s (%s) in favour of newer version %s..." % (package, version, packages[package]["version"])
131 packages[package] = { "id": id, "version": version, "filename": filename }
133 if not Cnf.Find("Suite::%s::Untouchable" % (suite)):
134 sys.stderr.write("WARNING: deleting %s because it doesn't exist.\n" % (filename));
135 projectB.query("DELETE FROM bin_associations WHERE bin = %s AND suite = %d" % (id, suite_id))
137 # Write the list of files out
138 package_keys = packages.keys();
140 for package in package_keys:
141 output.write(packages[package]["filename"]+'\n')
146 global Cnf, projectB;
147 dislocated_files = {};
149 projectB = pg.connect('projectb', 'localhost');
153 Cnf = apt_pkg.newConfiguration();
154 apt_pkg.ReadConfigFileISC(Cnf,utils.which_conf_file());
156 Arguments = [('a',"architecture","Jenna::Options::Architecture", "HasArg"),
157 ('c',"component","Jenna::Options::Component", "HasArg"),
158 ('d',"debug","Jenna::Options::Debug", "IntVal"),
159 ('h',"help","Jenna::Options::Help"),
160 ('s',"suite", "Jenna::Options::Suite", "HasArg"),
161 ('v',"verbose","Jenna::Options::Verbose"),
162 ('V',"version","Jenna::Options::Version")];
164 apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv);
166 db_access.init(Cnf, projectB);
168 if Cnf["Jenna::Options::Suite"] == "":
169 Cnf["Jenna::Options::Suite"] = string.join(Cnf.SubTree("Suite").List());
170 for suite in string.split(Cnf["Jenna::Options::Suite"]):
171 suite = string.lower(suite);
172 if suite == 'stable':
173 dislocated_files = claire.find_dislocated_stable(Cnf, projectB);
174 components = Cnf["Jenna::Options::Component"];
175 if not Cnf.has_key("Suite::%s::Components" % (suite)):
178 components = string.join(Cnf.SubTree("Suite::%s::Components" % (suite)).List());
179 for component in string.split(components):
180 component = string.lower(component)
181 architectures = Cnf["Jenna::Options::Architecture"];
182 if architectures == "":
183 architectures = string.join(Cnf.SubTree("Suite::%s::Architectures" % (suite)).List());
184 for architecture in string.split(architectures):
185 architecture = string.lower(architecture)
186 if architecture == "all":
188 if architecture == "source":
189 print "Processing dists/%s/%s/%s..." % (suite, component, architecture);
190 output = utils.open_file("%s/%s_%s_%s.list" % (Cnf["Dir::ListsDir"], suite, component, architecture), "w")
191 generate_src_list(suite, component, output, dislocated_files);
194 print "Processing dists/%s/%s/binary-%s..." % (suite, component, architecture);
195 output = utils.open_file("%s/%s_%s_binary-%s.list" % (Cnf["Dir::ListsDir"], suite, component, architecture), "w");
196 generate_bin_list(suite, component, architecture, output, "deb", dislocated_files);
198 if component == "main": # FIXME: must be a cleaner way to say debian-installer is main only?
199 print "Processing dists/%s/%s/debian-installer/binary-%s..." % (suite,component, architecture);
200 output = utils.open_file("%s/%s_%s_debian-installer_binary-%s.list" % (Cnf["Dir::ListsDir"], suite, component, architecture), "w");
201 generate_bin_list(suite, component, architecture, output, "udeb", dislocated_files);
204 if __name__ == '__main__':