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