]> git.decadent.org.uk Git - dak.git/blob - dak/dak.py
Add nicer and stricter regular expressions.
[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 os
37 import sys
38 import traceback
39 import daklib.utils
40
41 from daklib.daklog import Logger
42 from daklib.config import Config
43 from daklib.dak_exceptions import CantOpenError
44
45 ################################################################################
46
47 def init():
48     """Setup the list of modules and brief explanation of what they
49     do."""
50
51     functionality = [
52         ("ls",
53          "Show which suites packages are in"),
54         ("override",
55          "Query/change the overrides"),
56         ("check-archive",
57          "Archive sanity checks"),
58         ("queue-report",
59          "Produce a report on NEW and BYHAND packages"),
60         ("show-new",
61          "Output html for packages in NEW"),
62         ("show-deferred",
63          "Output html and symlinks for packages in DEFERRED"),
64         ("graph",
65          "Output graphs of number of packages in various queues"),
66
67         ("rm",
68          "Remove packages from suites"),
69
70         ("process-new",
71          "Process NEW and BYHAND packages"),
72         ("process-upload",
73          "Process packages in queue/unchecked"),
74         ("process-policy",
75          "Process packages in policy queues from COMMENTS files"),
76
77         ("dominate",
78          "Remove obsolete source and binary associations from suites"),
79         ("make-pkg-file-mapping",
80          "Generate package <-> file mapping"),
81         ("generate-filelist",
82          "Generate file lists for apt-ftparchive"),
83         ("generate-releases",
84          "Generate Release files"),
85         ("generate-packages-sources",
86          "Generate Packages/Sources files"),
87         ("generate-packages-sources2",
88          "Generate Packages/Sources files [directly from database]"),
89         ("contents",
90          "Generate content files"),
91         ("metadata",
92          "Load data for packages/sources files"),
93         ("generate-index-diffs",
94          "Generate .diff/Index files"),
95         ("clean-suites",
96          "Clean unused/superseded packages from the archive"),
97         ("manage-build-queues",
98          "Clean and update metadata for build queues"),
99         ("clean-queues",
100          "Clean cruft from incoming"),
101
102         ("transitions",
103          "Manage the release transition file"),
104         ("check-overrides",
105          "Override cruft checks"),
106         ("control-overrides",
107          "Manipulate/list override entries in bulk"),
108         ("control-suite",
109          "Manipulate suites in bulk"),
110         ("cruft-report",
111          "Check for obsolete or duplicated packages"),
112         ("examine-package",
113          "Show information useful for NEW processing"),
114         ("find-null-maintainers",
115          "Check for users with no packages in the archive"),
116         ("import-keyring",
117          "Populate fingerprint/uid table based on a new/updated keyring"),
118         ("import-ldap-fingerprints",
119          "Syncs fingerprint and uid tables with Debian LDAP db"),
120         ("import-users-from-passwd",
121          "Sync PostgreSQL users with passwd file"),
122         ("admin",
123          "Perform administration on the dak database"),
124         ("update-db",
125          "Updates databae schema to latest revision"),
126         ("init-dirs",
127          "Initial setup of the archive"),
128         ("make-maintainers",
129          "Generates Maintainers file for BTS etc"),
130         ("make-overrides",
131          "Generates override files"),
132         ("new-security-install",
133          "New way to install a security upload into the archive"),
134         ("stats",
135          "Generate statistics"),
136         ("bts-categorize",
137          "Categorize uncategorized bugs filed against ftp.debian.org"),
138         ("add-user",
139          "Add a user to the archive"),
140         ("make-changelog",
141          "Generate changelog between two suites"),
142         ("copy-installer",
143          "Copies the installer from one suite to another"),
144         ("override-disparity",
145          "Generate a list of override disparities"),
146         ("external-overrides",
147          "Modify external overrides"),
148         ]
149     return functionality
150
151 ################################################################################
152
153 def usage(functionality, exit_code=0):
154     """Print a usage message and exit with 'exit_code'."""
155
156     print """Usage: dak COMMAND [...]
157 Run DAK commands.  (Will also work if invoked as COMMAND.)
158
159 Available commands:"""
160     for (command, description) in functionality:
161         print "  %-23s %s" % (command, description)
162     sys.exit(exit_code)
163
164 ################################################################################
165
166 def main():
167     """Launch dak functionality."""
168
169
170     try:
171         logger = Logger('dak top-level', print_starting=False)
172     except CantOpenError:
173         logger = None
174
175     functionality = init()
176     modules = [ command for (command, _) in functionality ]
177
178     if len(sys.argv) == 0:
179         daklib.utils.fubar("err, argc == 0? how is that possible?")
180     elif (len(sys.argv) == 1
181           or (len(sys.argv) == 2 and
182               (sys.argv[1] == "--help" or sys.argv[1] == "-h"))):
183         usage(functionality)
184
185     # First see if we were invoked with/as the name of a module
186     cmdname = sys.argv[0]
187     cmdname = cmdname[cmdname.rfind("/")+1:]
188     if cmdname in modules:
189         pass
190     # Otherwise the argument is the module
191     else:
192         cmdname = sys.argv[1]
193         sys.argv = [sys.argv[0] + " " + sys.argv[1]] + sys.argv[2:]
194         if cmdname not in modules:
195             match = []
196             for name in modules:
197                 if name.startswith(cmdname):
198                     match.append(name)
199             if len(match) == 1:
200                 cmdname = match[0]
201             elif len(match) > 1:
202                 daklib.utils.warn("ambiguous command '%s' - could be %s" \
203                            % (cmdname, ", ".join(match)))
204                 usage(functionality, 1)
205             else:
206                 daklib.utils.warn("unknown command '%s'" % (cmdname))
207                 usage(functionality, 1)
208
209     # Invoke the module
210     module = __import__(cmdname.replace("-","_"))
211
212     try:
213         module.main()
214     except KeyboardInterrupt:
215         msg = 'KeyboardInterrupt caught; exiting'
216         print msg
217         if logger:
218             logger.log([msg])
219         sys.exit(1)
220     except SystemExit:
221         pass
222     except:
223         if logger:
224             for line in traceback.format_exc().split('\n')[:-1]:
225                 logger.log(['exception', line])
226         raise
227
228 ################################################################################
229
230 if __name__ == "__main__":
231     os.environ['LANG'] = 'C'
232     os.environ['LC_ALL'] = 'C'
233     main()