]> git.decadent.org.uk Git - dak.git/blob - dak/dak.py
oops, forgot some changes to contents.py
[dak.git] / dak / dak.py
1 #!/usr/bin/env python
2
3 """
4 Wrapper to launch dak functionality
5
6 G{importgraph}
7
8 """
9 # Copyright (C) 2005, 2006 Anthony Towns <ajt@debian.org>
10 # Copyright (C) 2006 James Troup <james@nocrew.org>
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 # well I don't know where you're from but in AMERICA, there's a little
29 # thing called "abstinent until proven guilty."
30 #  -- http://harrietmiers.blogspot.com/2005/10/wow-i-feel-loved.html
31
32 # (if James had a blog, I bet I could find a funny quote in it to use!)
33
34 ################################################################################
35
36 import sys, imp
37 import daklib.utils, daklib.extensions
38
39 ################################################################################
40
41 class UserExtension:
42     def __init__(self, user_extension = None):
43         if user_extension:
44             m = imp.load_source("dak_userext", user_extension)
45             d = m.__dict__
46         else:
47             m, d = None, {}
48         self.__dict__["_module"] = m
49         self.__dict__["_d"] = d
50
51     def __getattr__(self, a):
52         if a in self.__dict__: return self.__dict__[a]
53         if a[0] == "_": raise AttributeError, a
54         return self._d.get(a, None)
55
56     def __setattr__(self, a, v):
57         self._d[a] = v
58
59 ################################################################################
60
61 class UserExtension:
62     def __init__(self, user_extension = None):
63         if user_extension:
64             m = imp.load_source("dak_userext", user_extension)
65             d = m.__dict__
66         else:
67             m, d = None, {}
68         self.__dict__["_module"] = m
69         self.__dict__["_d"] = d
70
71     def __getattr__(self, a):
72         if a in self.__dict__: return self.__dict__[a]
73         if a[0] == "_": raise AttributeError, a
74         return self._d.get(a, None)
75
76     def __setattr__(self, a, v):
77         self._d[a] = v
78
79 ################################################################################
80
81 def init():
82     """Setup the list of modules and brief explanation of what they
83     do."""
84
85     functionality = [
86         ("ls",
87          "Show which suites packages are in"),
88         ("override",
89          "Query/change the overrides"),
90         ("check-archive",
91          "Archive sanity checks"),
92         ("queue-report",
93          "Produce a report on NEW and BYHAND packages"),
94         ("show-new",
95          "Output html for packages in NEW"),
96         ("show-deferred",
97          "Output html and symlinks for packages in DEFERRED"),
98
99         ("rm",
100          "Remove packages from suites"),
101
102         ("process-new",
103          "Process NEW and BYHAND packages"),
104         ("process-unchecked",
105          "Process packages in queue/unchecked"),
106         ("process-accepted",
107          "Install packages into the pool"),
108
109         ("make-suite-file-list",
110          "Generate lists of packages per suite for apt-ftparchive"),
111         ("make-pkg-file-mapping",
112          "Generate package <-> file mapping"),
113         ("generate-releases",
114          "Generate Release files"),
115         ("contents",
116          "Generate contest files"),
117         ("generate-index-diffs",
118          "Generate .diff/Index files"),
119         ("clean-suites",
120          "Clean unused/superseded packages from the archive"),
121         ("clean-queues",
122          "Clean cruft from incoming"),
123         ("clean-proposed-updates",
124          "Remove obsolete .changes from proposed-updates"),
125
126         ("transitions",
127          "Manage the release transition file"),
128         ("check-overrides",
129          "Override cruft checks"),
130         ("check-proposed-updates",
131          "Dependency checking for proposed-updates"),
132         ("compare-suites",
133          "Show fixable discrepencies between suites"),
134         ("control-overrides",
135          "Manipulate/list override entries in bulk"),
136         ("control-suite",
137          "Manipulate suites in bulk"),
138         ("cruft-report",
139          "Check for obsolete or duplicated packages"),
140         ("decode-dot-dak",
141          "Display contents of a .dak file"),
142         ("examine-package",
143          "Show information useful for NEW processing"),
144         ("find-null-maintainers",
145          "Check for users with no packages in the archive"),
146         ("import-archive",
147          "Populate SQL database based from an archive tree"),
148         ("import-keyring",
149          "Populate fingerprint/uid table based on a new/updated keyring"),
150         ("import-ldap-fingerprints",
151          "Syncs fingerprint and uid tables with Debian LDAP db"),
152         ("import-users-from-passwd",
153          "Sync PostgreSQL users with passwd file"),
154         ("init-db",
155          "Update the database to match the conf file"),
156         ("update-db",
157          "Updates databae schema to latest revision"),
158         ("init-dirs",
159          "Initial setup of the archive"),
160         ("make-maintainers",
161          "Generates Maintainers file for BTS etc"),
162         ("make-overrides",
163          "Generates override files"),
164         ("poolize",
165          "Move packages from dists/ to pool/"),
166         ("reject-proposed-updates",
167          "Manually reject from proposed-updates"),
168         ("new-security-install",
169          "New way to install a security upload into the archive"),
170         ("split-done",
171          "Split queue/done into a date-based hierarchy"),
172         ("stats",
173          "Generate statistics"),
174         ("calculate-shasums",
175          "Calculate missing sha1sums and sha256sums"),
176         ("bts-categorize",
177          "Categorize uncategorized bugs filed against ftp.debian.org"),
178         ("add-user",
179          "Add a user to the archive"),
180         ]
181     return functionality
182
183 ################################################################################
184
185 def usage(functionality, exit_code=0):
186     """Print a usage message and exit with 'exit_code'."""
187
188     print """Usage: dak COMMAND [...]
189 Run DAK commands.  (Will also work if invoked as COMMAND.)
190
191 Available commands:"""
192     for (command, description) in functionality:
193         print "  %-23s %s" % (command, description)
194     sys.exit(exit_code)
195
196 ################################################################################
197
198 def main():
199     """Launch dak functionality."""
200
201     Cnf = daklib.utils.get_conf()
202
203     if Cnf.has_key("Dinstall::UserExtensions"):
204         userext = UserExtension(Cnf["Dinstall::UserExtensions"])
205     else:
206         userext = UserExtension()
207
208     functionality = init()
209     modules = [ command for (command, _) in functionality ]
210
211     if len(sys.argv) == 0:
212         daklib.utils.fubar("err, argc == 0? how is that possible?")
213     elif (len(sys.argv) == 1
214           or (len(sys.argv) == 2 and
215               (sys.argv[1] == "--help" or sys.argv[1] == "-h"))):
216         usage(functionality)
217
218     # First see if we were invoked with/as the name of a module
219     cmdname = sys.argv[0]
220     cmdname = cmdname[cmdname.rfind("/")+1:]
221     if cmdname in modules:
222         pass
223     # Otherwise the argument is the module
224     else:
225         cmdname = sys.argv[1]
226         sys.argv = [sys.argv[0] + " " + sys.argv[1]] + sys.argv[2:]
227         if cmdname not in modules:
228             match = []
229             for name in modules:
230                 if name.startswith(cmdname):
231                     match.append(name)
232             if len(match) == 1:
233                 cmdname = match[0]
234             elif len(match) > 1:
235                 daklib.utils.warn("ambiguous command '%s' - could be %s" \
236                            % (cmdname, ", ".join(match)))
237                 usage(functionality, 1)
238             else:
239                 daklib.utils.warn("unknown command '%s'" % (cmdname))
240                 usage(functionality, 1)
241
242     # Invoke the module
243     module = __import__(cmdname.replace("-","_"))
244
245     module.dak_userext = userext
246     userext.dak_module = module
247
248     daklib.extensions.init(cmdname, module, userext)
249     if userext.init is not None: userext.init(cmdname)
250
251     module.main()
252
253 ################################################################################
254
255 if __name__ == "__main__":
256     main()