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