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