]> git.decadent.org.uk Git - dak.git/blob - dak/symlink_dists.py
Stop using silly names, and migrate to a saner directory structure.
[dak.git] / dak / symlink_dists.py
1 #!/usr/bin/env python
2
3 # 'Fix' stable to make debian-cd and dpkg -BORGiE users happy
4 # Copyright (C) 2000, 2001, 2002, 2003  James Troup <james@nocrew.org>
5 # $Id: claire.py,v 1.19 2003-09-07 13:52: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 #  _   _ ____
24 # | \ | | __ )_
25 # |  \| |  _ (_)
26 # | |\  | |_) |   This has been obsoleted since the release of woody.
27 # |_| \_|____(_)
28 #
29
30 ################################################################################
31
32 import os, pg, re, sys;
33 import utils, db_access;
34 import apt_pkg;
35
36 ################################################################################
37
38 re_strip_section_prefix = re.compile(r'.*/');
39
40 Cnf = None;
41 projectB = None;
42
43 ################################################################################
44
45 def usage (exit_code=0):
46     print """Usage: claire [OPTIONS]
47 Create compatibility symlinks from legacy locations to the pool.
48
49   -v, --verbose              explain what is being done
50   -h, --help                 show this help and exit"""
51
52     sys.exit(exit_code)
53
54 ################################################################################
55
56 def fix_component_section (component, section):
57     if component == "":
58         component = utils.extract_component_from_section(section)[1];
59
60     # FIXME: ugly hacks to work around override brain damage
61     section = re_strip_section_prefix.sub('', section);
62     section = section.lower().replace('non-us', '');
63     if section == "main" or section == "contrib" or section == "non-free":
64         section = '';
65     if section != '':
66         section += '/';
67
68     return (component, section);
69
70 ################################################################################
71
72 def find_dislocated_stable(Cnf, projectB):
73     dislocated_files = {}
74
75     codename = Cnf["Suite::Stable::Codename"];
76
77     # Source
78     q = projectB.query("""
79 SELECT DISTINCT ON (f.id) c.name, sec.section, l.path, f.filename, f.id
80     FROM component c, override o, section sec, source s, files f, location l,
81          dsc_files df, suite su, src_associations sa, files f2, location l2
82     WHERE su.suite_name = 'stable' AND sa.suite = su.id AND sa.source = s.id
83       AND f2.id = s.file AND f2.location = l2.id AND df.source = s.id
84       AND f.id = df.file AND f.location = l.id AND o.package = s.source
85       AND sec.id = o.section AND NOT (f.filename ~ '^%s/')
86       AND l.component = c.id AND o.suite = su.id
87 """ % (codename));
88 # Only needed if you have files in legacy-mixed locations
89 #  UNION SELECT DISTINCT ON (f.id) null, sec.section, l.path, f.filename, f.id
90 #      FROM component c, override o, section sec, source s, files f, location l,
91 #           dsc_files df, suite su, src_associations sa, files f2, location l2
92 #      WHERE su.suite_name = 'stable' AND sa.suite = su.id AND sa.source = s.id
93 #        AND f2.id = s.file AND f2.location = l2.id AND df.source = s.id
94 #        AND f.id = df.file AND f.location = l.id AND o.package = s.source
95 #        AND sec.id = o.section AND NOT (f.filename ~ '^%s/') AND o.suite = su.id
96 #        AND NOT EXISTS (SELECT 1 FROM location l WHERE l.component IS NOT NULL AND f.location = l.id);
97     for i in q.getresult():
98         (component, section) = fix_component_section(i[0], i[1]);
99         if Cnf.FindB("Dinstall::LegacyStableHasNoSections"):
100             section="";
101         dest = "%sdists/%s/%s/source/%s%s" % (Cnf["Dir::Root"], codename, component, section, os.path.basename(i[3]));
102         if not os.path.exists(dest):
103             src = i[2]+i[3];
104             src = utils.clean_symlink(src, dest, Cnf["Dir::Root"]);
105             if Cnf.Find("Claire::Options::Verbose"):
106                 print src+' -> '+dest
107             os.symlink(src, dest);
108         dislocated_files[i[4]] = dest;
109
110     # Binary
111     architectures = filter(utils.real_arch, Cnf.ValueList("Suite::Stable::Architectures"));
112     q = projectB.query("""
113 SELECT DISTINCT ON (f.id) c.name, a.arch_string, sec.section, b.package,
114                           b.version, l.path, f.filename, f.id
115     FROM architecture a, bin_associations ba, binaries b, component c, files f,
116          location l, override o, section sec, suite su
117     WHERE su.suite_name = 'stable' AND ba.suite = su.id AND ba.bin = b.id
118       AND f.id = b.file AND f.location = l.id AND o.package = b.package
119       AND sec.id = o.section AND NOT (f.filename ~ '^%s/')
120       AND b.architecture = a.id AND l.component = c.id AND o.suite = su.id""" %
121                        (codename));
122 # Only needed if you have files in legacy-mixed locations
123 #  UNION SELECT DISTINCT ON (f.id) null, a.arch_string, sec.section, b.package,
124 #                            b.version, l.path, f.filename, f.id
125 #      FROM architecture a, bin_associations ba, binaries b, component c, files f,
126 #           location l, override o, section sec, suite su
127 #      WHERE su.suite_name = 'stable' AND ba.suite = su.id AND ba.bin = b.id
128 #        AND f.id = b.file AND f.location = l.id AND o.package = b.package
129 #        AND sec.id = o.section AND NOT (f.filename ~ '^%s/')
130 #        AND b.architecture = a.id AND o.suite = su.id AND NOT EXISTS
131 #          (SELECT 1 FROM location l WHERE l.component IS NOT NULL AND f.location = l.id);
132     for i in q.getresult():
133         (component, section) = fix_component_section(i[0], i[2]);
134         if Cnf.FindB("Dinstall::LegacyStableHasNoSections"):
135             section="";
136         architecture = i[1];
137         package = i[3];
138         version = utils.re_no_epoch.sub('', i[4]);
139         src = i[5]+i[6];
140
141         dest = "%sdists/%s/%s/binary-%s/%s%s_%s.deb" % (Cnf["Dir::Root"], codename, component, architecture, section, package, version);
142         src = utils.clean_symlink(src, dest, Cnf["Dir::Root"]);
143         if not os.path.exists(dest):
144             if Cnf.Find("Claire::Options::Verbose"):
145                 print src+' -> '+dest;
146             os.symlink(src, dest);
147         dislocated_files[i[7]] = dest;
148         # Add per-arch symlinks for arch: all debs
149         if architecture == "all":
150             for arch in architectures:
151                 dest = "%sdists/%s/%s/binary-%s/%s%s_%s.deb" % (Cnf["Dir::Root"], codename, component, arch, section, package, version);
152                 if not os.path.exists(dest):
153                     if Cnf.Find("Claire::Options::Verbose"):
154                         print src+' -> '+dest
155                     os.symlink(src, dest);
156
157     return dislocated_files
158
159 ################################################################################
160
161 def main ():
162     global Cnf, projectB;
163
164     Cnf = utils.get_conf()
165
166     Arguments = [('h',"help","Claire::Options::Help"),
167                  ('v',"verbose","Claire::Options::Verbose")];
168     for i in ["help", "verbose" ]:
169         if not Cnf.has_key("Claire::Options::%s" % (i)):
170             Cnf["Claire::Options::%s" % (i)] = "";
171
172     apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv);
173     Options = Cnf.SubTree("Claire::Options")
174
175     if Options["Help"]:
176         usage();
177
178     projectB = pg.connect(Cnf["DB::Name"], Cnf["DB::Host"], int(Cnf["DB::Port"]));
179
180     db_access.init(Cnf, projectB);
181
182     find_dislocated_stable(Cnf, projectB);
183
184 #######################################################################################
185
186 if __name__ == '__main__':
187     main();
188