]> git.decadent.org.uk Git - dak.git/blob - dak/generate_filelist.py
Write an additional arch all (only) file in generate-filelist.
[dak.git] / dak / generate_filelist.py
1 #!/usr/bin/python
2
3 """
4 Generate file lists for apt-ftparchive.
5
6 @contact: Debian FTP Master <ftpmaster@debian.org>
7 @copyright: 2009  Torsten Werner <twerner@debian.org>
8 @license: GNU General Public License version 2 or later
9 """
10
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2 of the License, or
14 # (at your option) any later version.
15
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 # GNU General Public License for more details.
20
21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, write to the Free Software
23 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
25 ################################################################################
26
27 # Ganneff> Please go and try to lock mhy now. After than try to lock NEW.
28 # twerner> !lock mhy
29 # dak> twerner: You suck, this is already locked by Ganneff
30 # Ganneff> now try with NEW
31 # twerner> !lock NEW
32 # dak> twerner: also locked NEW
33 # mhy> Ganneff: oy, stop using me for locks and highlighting me you tall muppet
34 # Ganneff> hehe :)
35
36 ################################################################################
37
38 from daklib.dbconn import *
39 from daklib.config import Config
40 from daklib.threadpool import ThreadPool
41 from daklib import utils
42 import apt_pkg, os, stat, sys
43
44 from daklib.lists import getSources, getBinaries, getArchAll
45
46 def listPath(suite, component, architecture = None, type = None,
47         incremental_mode = False):
48     """returns full path to the list file"""
49     suffixMap = { 'deb': "binary-",
50                   'udeb': "debian-installer_binary-" }
51     if architecture:
52         suffix = suffixMap[type] + architecture.arch_string
53     else:
54         suffix = "source"
55     filename = "%s_%s_%s.list" % \
56         (suite.suite_name, component.component_name, suffix)
57     pathname = os.path.join(Config()["Dir::Lists"], filename)
58     file = utils.open_file(pathname, "a")
59     timestamp = None
60     if incremental_mode:
61         timestamp = os.fstat(file.fileno())[stat.ST_MTIME]
62     else:
63         file.seek(0)
64         file.truncate()
65     return (file, timestamp)
66
67 def writeSourceList(args):
68     (suite, component, incremental_mode) = args
69     (file, timestamp) = listPath(suite, component,
70             incremental_mode = incremental_mode)
71     session = DBConn().session()
72     for _, filename in getSources(suite, component, session, timestamp):
73         file.write(filename + '\n')
74     session.close()
75     file.close()
76
77 def writeAllList(args):
78     (suite, component, architecture, type, incremental_mode) = args
79     (file, timestamp) = listPath(suite, component, architecture, type,
80             incremental_mode)
81     session = DBConn().session()
82     for _, filename in getArchAll(suite, component, architecture, type,
83             session, timestamp):
84         file.write(filename + '\n')
85     session.close()
86     file.close()
87
88 def writeBinaryList(args):
89     (suite, component, architecture, type, incremental_mode) = args
90     (file, timestamp) = listPath(suite, component, architecture, type,
91             incremental_mode)
92     session = DBConn().session()
93     for _, filename in getBinaries(suite, component, architecture, type,
94             session, timestamp):
95         file.write(filename + '\n')
96     session.close()
97     file.close()
98
99 def usage():
100     print """Usage: dak generate_filelist [OPTIONS]
101 Create filename lists for apt-ftparchive.
102
103   -s, --suite=SUITE            act on this suite
104   -c, --component=COMPONENT    act on this component
105   -a, --architecture=ARCH      act on this architecture
106   -h, --help                   show this help and exit
107   -i, --incremental            activate incremental mode
108
109 ARCH, COMPONENT and SUITE can be comma (or space) separated list, e.g.
110     --suite=testing,unstable
111
112 Incremental mode appends only newer files to existing lists."""
113     sys.exit()
114
115 def main():
116     cnf = Config()
117     Arguments = [('h', "help",         "Filelist::Options::Help"),
118                  ('s', "suite",        "Filelist::Options::Suite", "HasArg"),
119                  ('c', "component",    "Filelist::Options::Component", "HasArg"),
120                  ('a', "architecture", "Filelist::Options::Architecture", "HasArg"),
121                  ('i', "incremental",  "Filelist::Options::Incremental")]
122     session = DBConn().session()
123     query_suites = session.query(Suite)
124     suites = [suite.suite_name for suite in query_suites]
125     if not cnf.has_key('Filelist::Options::Suite'):
126         cnf['Filelist::Options::Suite'] = ','.join(suites).encode()
127     query_components = session.query(Component)
128     components = \
129         [component.component_name for component in query_components]
130     if not cnf.has_key('Filelist::Options::Component'):
131         cnf['Filelist::Options::Component'] = ','.join(components).encode()
132     query_architectures = session.query(Architecture)
133     architectures = \
134         [architecture.arch_string for architecture in query_architectures]
135     if not cnf.has_key('Filelist::Options::Architecture'):
136         cnf['Filelist::Options::Architecture'] = ','.join(architectures).encode()
137     cnf['Filelist::Options::Help'] = ''
138     cnf['Filelist::Options::Incremental'] = ''
139     apt_pkg.ParseCommandLine(cnf.Cnf, Arguments, sys.argv)
140     Options = cnf.SubTree("Filelist::Options")
141     if Options['Help']:
142         usage()
143     threadpool = ThreadPool()
144     query_suites = query_suites. \
145         filter(Suite.suite_name.in_(utils.split_args(Options['Suite'])))
146     query_components = query_components. \
147         filter(Component.component_name.in_(utils.split_args(Options['Component'])))
148     query_architectures = query_architectures. \
149         filter(Architecture.arch_string.in_(utils.split_args(Options['Architecture'])))
150     for suite in query_suites:
151         for component in query_components:
152             for architecture in query_architectures:
153                 if architecture not in suite.architectures:
154                     pass
155                 elif architecture.arch_string == 'source':
156                     threadpool.queueTask(writeSourceList,
157                         (suite, component, Options['Incremental']))
158                 elif architecture.arch_string == 'all':
159                     threadpool.queueTask(writeAllList,
160                         (suite, component, architecture, 'deb',
161                             Options['Incremental']))
162                     threadpool.queueTask(writeAllList,
163                         (suite, component, architecture, 'udeb',
164                             Options['Incremental']))
165                 else: # arch any
166                     threadpool.queueTask(writeBinaryList,
167                         (suite, component, architecture, 'deb',
168                             Options['Incremental']))
169                     threadpool.queueTask(writeBinaryList,
170                         (suite, component, architecture, 'udeb',
171                             Options['Incremental']))
172     threadpool.joinAll()
173     # this script doesn't change the database
174     session.close()
175
176 if __name__ == '__main__':
177     main()
178