]> git.decadent.org.uk Git - dak.git/blob - dak/symlink_dists.py
[??] sync with ftp-master/dak master
[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, 2006  James Troup <james@nocrew.org>
5
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20 ################################################################################
21
22 #  _   _ ____
23 # | \ | | __ )_
24 # |  \| |  _ (_)
25 # | |\  | |_) |   This has been obsoleted since the release of woody.
26 # |_| \_|____(_)
27 #
28
29 ################################################################################
30
31 import os, pg, re, sys
32 import apt_pkg
33 import daklib.database
34 import daklib.utils
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: dak symlink-dists [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 = daklib.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     if section == "main" or section == "contrib" or section == "non-free":
63         section = ''
64     if section != '':
65         section += '/'
66
67     return (component, section)
68
69 ################################################################################
70
71 def find_dislocated_stable(Cnf, projectB):
72     dislocated_files = {}
73
74     codename = Cnf["Suite::Stable::Codename"]
75
76     # Source
77     q = projectB.query("""
78 SELECT DISTINCT ON (f.id) c.name, sec.section, l.path, f.filename, f.id
79     FROM component c, override o, section sec, source s, files f, location l,
80          dsc_files df, suite su, src_associations sa, files f2, location l2
81     WHERE su.suite_name = 'stable' AND sa.suite = su.id AND sa.source = s.id
82       AND f2.id = s.file AND f2.location = l2.id AND df.source = s.id
83       AND f.id = df.file AND f.location = l.id AND o.package = s.source
84       AND sec.id = o.section AND NOT (f.filename ~ '^%s/')
85       AND l.component = c.id AND o.suite = su.id
86 """ % (codename))
87 # Only needed if you have files in legacy-mixed locations
88 #  UNION SELECT DISTINCT ON (f.id) null, sec.section, l.path, f.filename, f.id
89 #      FROM component c, override o, section sec, source s, files f, location l,
90 #           dsc_files df, suite su, src_associations sa, files f2, location l2
91 #      WHERE su.suite_name = 'stable' AND sa.suite = su.id AND sa.source = s.id
92 #        AND f2.id = s.file AND f2.location = l2.id AND df.source = s.id
93 #        AND f.id = df.file AND f.location = l.id AND o.package = s.source
94 #        AND sec.id = o.section AND NOT (f.filename ~ '^%s/') AND o.suite = su.id
95 #        AND NOT EXISTS (SELECT 1 FROM location l WHERE l.component IS NOT NULL AND f.location = l.id)
96     for i in q.getresult():
97         (component, section) = fix_component_section(i[0], i[1])
98         if Cnf.FindB("Dinstall::LegacyStableHasNoSections"):
99             section=""
100         dest = "%sdists/%s/%s/source/%s%s" % (Cnf["Dir::Root"], codename, component, section, os.path.basename(i[3]))
101         if not os.path.exists(dest):
102             src = i[2]+i[3]
103             src = daklib.utils.clean_symlink(src, dest, Cnf["Dir::Root"])
104             if Cnf.Find("Symlink-Dists::Options::Verbose"):
105                 print src+' -> '+dest
106             os.symlink(src, dest)
107         dislocated_files[i[4]] = dest
108
109     # Binary
110     architectures = filter(daklib.utils.real_arch, Cnf.ValueList("Suite::Stable::Architectures"))
111     q = projectB.query("""
112 SELECT DISTINCT ON (f.id) c.name, a.arch_string, sec.section, b.package,
113                           b.version, l.path, f.filename, f.id
114     FROM architecture a, bin_associations ba, binaries b, component c, files f,
115          location l, override o, section sec, suite su
116     WHERE su.suite_name = 'stable' AND ba.suite = su.id AND ba.bin = b.id
117       AND f.id = b.file AND f.location = l.id AND o.package = b.package
118       AND sec.id = o.section AND NOT (f.filename ~ '^%s/')
119       AND b.architecture = a.id AND l.component = c.id AND o.suite = su.id""" %
120                        (codename))
121 # Only needed if you have files in legacy-mixed locations
122 #  UNION SELECT DISTINCT ON (f.id) null, a.arch_string, sec.section, b.package,
123 #                            b.version, l.path, f.filename, f.id
124 #      FROM architecture a, bin_associations ba, binaries b, component c, files f,
125 #           location l, override o, section sec, suite su
126 #      WHERE su.suite_name = 'stable' AND ba.suite = su.id AND ba.bin = b.id
127 #        AND f.id = b.file AND f.location = l.id AND o.package = b.package
128 #        AND sec.id = o.section AND NOT (f.filename ~ '^%s/')
129 #        AND b.architecture = a.id AND o.suite = su.id AND NOT EXISTS
130 #          (SELECT 1 FROM location l WHERE l.component IS NOT NULL AND f.location = l.id)
131     for i in q.getresult():
132         (component, section) = fix_component_section(i[0], i[2])
133         if Cnf.FindB("Dinstall::LegacyStableHasNoSections"):
134             section=""
135         architecture = i[1]
136         package = i[3]
137         version = daklib.utils.re_no_epoch.sub('', i[4])
138         src = i[5]+i[6]
139
140         dest = "%sdists/%s/%s/binary-%s/%s%s_%s.deb" % (Cnf["Dir::Root"], codename, component, architecture, section, package, version)
141         src = daklib.utils.clean_symlink(src, dest, Cnf["Dir::Root"])
142         if not os.path.exists(dest):
143             if Cnf.Find("Symlink-Dists::Options::Verbose"):
144                 print src+' -> '+dest
145             os.symlink(src, dest)
146         dislocated_files[i[7]] = dest
147         # Add per-arch symlinks for arch: all debs
148         if architecture == "all":
149             for arch in architectures:
150                 dest = "%sdists/%s/%s/binary-%s/%s%s_%s.deb" % (Cnf["Dir::Root"], codename, component, arch, section, package, version)
151                 if not os.path.exists(dest):
152                     if Cnf.Find("Symlink-Dists::Options::Verbose"):
153                         print src+' -> '+dest
154                     os.symlink(src, dest)
155
156     return dislocated_files
157
158 ################################################################################
159
160 def main ():
161     global Cnf, projectB
162
163     Cnf = daklib.utils.get_conf()
164
165     Arguments = [('h',"help","Symlink-Dists::Options::Help"),
166                  ('v',"verbose","Symlink-Dists::Options::Verbose")]
167     for i in ["help", "verbose" ]:
168         if not Cnf.has_key("Symlink-Dists::Options::%s" % (i)):
169             Cnf["Symlink-Dists::Options::%s" % (i)] = ""
170
171     apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv)
172     Options = Cnf.SubTree("Symlink-Dists::Options")
173
174     if Options["Help"]:
175         usage()
176
177     projectB = pg.connect(Cnf["DB::Name"], Cnf["DB::Host"], int(Cnf["DB::Port"]))
178
179     daklib.database.init(Cnf, projectB)
180
181     find_dislocated_stable(Cnf, projectB)
182
183 #######################################################################################
184
185 if __name__ == '__main__':
186     main()
187