Coverage for dak/dak.py: 64%
60 statements
« prev ^ index » next coverage.py v7.6.0, created at 2026-05-10 21:38 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2026-05-10 21:38 +0000
1#!/usr/bin/env python3
3"""
4Wrapper to launch dak functionality
6G{importgraph}
8"""
9# Copyright (C) 2005, 2006 Anthony Towns <ajt@debian.org>
10# Copyright (C) 2006 James Troup <james@nocrew.org>
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.
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.
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
26################################################################################
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
32# (if James had a blog, I bet I could find a funny quote in it to use!)
34################################################################################
36import importlib
37import os
38import sys
39import traceback
41sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
43import daklib.utils
44from daklib.daklog import Logger
46################################################################################
49def init():
50 """Setup the list of modules and brief explanation of what they
51 do."""
53 functionality = [
54 ("ls", "Show which suites packages are in"),
55 ("override", "Query/change the overrides"),
56 ("check-archive", "Archive sanity checks"),
57 ("queue-report", "Produce a report on NEW and BYHAND packages"),
58 ("show-new", "Output html for packages in NEW"),
59 ("show-deferred", "Output html and symlinks for packages in DEFERRED"),
60 ("graph", "Output graphs of number of packages in various queues"),
61 ("graph-new", "Output graphs of age of packages in the NEW queue"),
62 ("rm", "Remove packages from suites"),
63 ("process-new", "Process NEW and BYHAND packages"),
64 ("process-upload", "Process packages in queue/unchecked"),
65 ("process-commands", "Process command files (*.dak-commands)"),
66 ("process-policy", "Process packages in policy queues from COMMENTS files"),
67 ("dominate", "Remove obsolete source and binary associations from suites"),
68 ("export", "Export uploads from policy queues"),
69 ("export-suite", "export a suite to a flat directory structure"),
70 ("make-pkg-file-mapping", "Generate package <-> file mapping"),
71 ("generate-releases", "Generate Release files"),
72 ("generate-packages-sources2", "Generate Packages/Sources files"),
73 ("contents", "Generate content files"),
74 ("metadata", "Load data for packages/sources files"),
75 ("generate-index-diffs", "Generate .diff/Index files"),
76 ("clean-suites", "Clean unused/superseded packages from the archive"),
77 ("manage-build-queues", "Clean and update metadata for build queues"),
78 ("manage-debug-suites", "Clean obsolete packages from debug suites"),
79 ("manage-external-signature-requests", "Maintain external signature requests"),
80 ("clean-queues", "Clean cruft from incoming"),
81 ("archive-dedup-pool", "De-duplicates files in the pool directory"),
82 ("transitions", "Manage the release transition file"),
83 ("check-overrides", "Override cruft checks"),
84 ("control-overrides", "Manipulate/list override entries in bulk"),
85 ("control-suite", "Manipulate suites in bulk"),
86 ("update-suite", "Update suite with packages from a different suite"),
87 ("cruft-report", "Check for obsolete or duplicated packages"),
88 ("auto-decruft", "Clean cruft without reverse dependencies automatically"),
89 ("examine-package", "Show information useful for NEW processing"),
90 ("import", "Import existing source and binary packages"),
91 ("import-repository", "Import packages from another repository"),
92 (
93 "import-keyring",
94 "Populate fingerprint/uid table based on a new/updated keyring",
95 ),
96 ("import-users-from-passwd", "Sync PostgreSQL users with passwd file"),
97 ("acl", "Manage upload ACLs"),
98 ("admin", "Perform administration on the dak database"),
99 ("update-db", "Updates databae schema to latest revision"),
100 ("init-dirs", "Initial setup of the archive"),
101 ("make-maintainers", "Generates Maintainers file for BTS etc"),
102 ("make-overrides", "Generates override files"),
103 (
104 "new-security-install",
105 "New way to install a security upload into the archive",
106 ),
107 ("rpc-server", "RPC server"),
108 ("stats", "Generate statistics"),
109 (
110 "bts-categorize",
111 "Categorize uncategorized bugs filed against ftp.debian.org",
112 ),
113 ("add-user", "Add a user to the archive"),
114 ("make-changelog", "Generate changelog between two suites"),
115 ("copy-installer", "Copies the installer from one suite to another"),
116 ("external-overrides", "Modify external overrides"),
117 ("write-sections", "Write out section descriptions"),
118 ("find-files", "Find files related to a given source package and version"),
119 ]
120 return functionality
123################################################################################
126def usage(functionality, exit_code=0):
127 """Print a usage message and exit with 'exit_code'."""
129 print(
130 """Usage: dak COMMAND [...]
131Run DAK commands. (Will also work if invoked as COMMAND.)
133Available commands:"""
134 )
135 for command, description in functionality:
136 print(" %-23s %s" % (command, description))
137 sys.exit(exit_code)
140################################################################################
143def main():
144 """Launch dak functionality."""
146 try:
147 logger = Logger("dak top-level", print_starting=False)
148 except OSError:
149 logger = None
151 functionality = init()
152 modules = [command for (command, _) in functionality]
154 if len(sys.argv) == 0: 154 ↛ 155line 154 didn't jump to line 155 because the condition on line 154 was never true
155 daklib.utils.fubar("err, argc == 0? how is that possible?")
156 elif len(sys.argv) == 1 or (
157 len(sys.argv) == 2 and (sys.argv[1] == "--help" or sys.argv[1] == "-h")
158 ):
159 usage(functionality)
161 # First see if we were invoked with/as the name of a module
162 cmdname = sys.argv[0]
163 cmdname = cmdname[cmdname.rfind("/") + 1 :]
164 if cmdname in modules: 164 ↛ 165line 164 didn't jump to line 165 because the condition on line 164 was never true
165 pass
166 # Otherwise the argument is the module
167 else:
168 cmdname = sys.argv[1]
169 sys.argv = [sys.argv[0] + " " + sys.argv[1]] + sys.argv[2:]
170 if cmdname not in modules:
171 match = []
172 for name in modules:
173 if name.startswith(cmdname):
174 match.append(name)
175 if len(match) == 1: 175 ↛ 177line 175 didn't jump to line 177 because the condition on line 175 was always true
176 cmdname = match[0]
177 elif len(match) > 1:
178 daklib.utils.warn(
179 "ambiguous command '%s' - could be %s" % (cmdname, ", ".join(match))
180 )
181 usage(functionality, 1)
182 else:
183 daklib.utils.warn("unknown command '%s'" % (cmdname))
184 usage(functionality, 1)
186 # Invoke the module
187 module = importlib.import_module("dak.{}".format(cmdname.replace("-", "_")))
189 try:
190 module.main()
191 except KeyboardInterrupt: 191 ↛ 192line 191 didn't jump to line 192 because the exception caught by line 191 didn't happen
192 msg = "KeyboardInterrupt caught; exiting"
193 print(msg)
194 if logger:
195 logger.log([msg])
196 sys.exit(1)
197 except SystemExit: 197 ↛ 199line 197 didn't jump to line 199
198 raise
199 except:
200 if logger:
201 for line in traceback.format_exc().split("\n")[:-1]:
202 logger.log(["exception", line])
203 raise
206################################################################################
209if __name__ == "__main__":
210 os.environ["LANG"] = "C"
211 os.environ["LC_ALL"] = "C"
212 main()