Coverage for src/debputy/plugins/debputy/debputy_plugin.py: 100%
84 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-09-07 09:27 +0000
« prev ^ index » next coverage.py v7.8.2, created at 2025-09-07 09:27 +0000
1import textwrap
3from debputy.plugin.api import (
4 DebputyPluginInitializer,
5 packager_provided_file_reference_documentation,
6)
7from debputy.plugins.debputy.metadata_detectors import (
8 detect_systemd_tmpfiles,
9 detect_kernel_modules,
10 detect_icons,
11 detect_gsettings_dependencies,
12 detect_xfonts,
13 detect_initramfs_hooks,
14 detect_systemd_sysusers,
15 detect_pycompile_files,
16 translate_capabilities,
17 pam_auth_update,
18 auto_depends_arch_any_solink,
19 detect_commands,
20)
21from debputy.plugins.debputy.paths import (
22 SYSTEMD_TMPFILES_DIR,
23 INITRAMFS_HOOK_DIR,
24 GSETTINGS_SCHEMA_DIR,
25 SYSTEMD_SYSUSERS_DIR,
26)
27from debputy.plugins.debputy.private_api import initialize_via_private_api
30def initialize_debputy_features(api: DebputyPluginInitializer) -> None:
31 initialize_via_private_api(api)
32 declare_manifest_variables(api)
33 register_packager_provided_files(api)
34 register_package_metadata_detectors(api)
37def declare_manifest_variables(api: DebputyPluginInitializer) -> None:
38 api.manifest_variable(
39 "path:BASH_COMPLETION_DIR",
40 "/usr/share/bash-completion/completions",
41 variable_reference_documentation="Directory to install bash completions into",
42 )
43 api.manifest_variable(
44 "path:FISH_COMPLETION_DIR",
45 "/usr/share/fish/vendor_completions.d",
46 variable_reference_documentation="Directory to install fish completions into",
47 )
48 api.manifest_variable(
49 "path:ZSH_COMPLETION_DIR",
50 "/usr/share/zsh/vendor-completions",
51 variable_reference_documentation="Directory to install zsh completions into",
52 )
53 api.manifest_variable(
54 "path:GNU_INFO_DIR",
55 "/usr/share/info",
56 variable_reference_documentation="Directory to install GNU INFO files into",
57 )
59 api.manifest_variable(
60 "token:NL",
61 "\n",
62 variable_reference_documentation="Literal newline (linefeed) character",
63 )
64 api.manifest_variable(
65 "token:NEWLINE",
66 "\n",
67 variable_reference_documentation="Literal newline (linefeed) character",
68 )
69 api.manifest_variable(
70 "token:TAB",
71 "\t",
72 variable_reference_documentation="Literal tab character",
73 )
74 api.manifest_variable(
75 "token:OPEN_CURLY_BRACE",
76 "{",
77 variable_reference_documentation='Literal "{" character',
78 )
79 api.manifest_variable(
80 "token:CLOSE_CURLY_BRACE",
81 "}",
82 variable_reference_documentation='Literal "}" character',
83 )
84 api.manifest_variable(
85 "token:DOUBLE_OPEN_CURLY_BRACE",
86 "{{",
87 variable_reference_documentation='Literal "{{" character - useful to avoid triggering a substitution',
88 )
89 api.manifest_variable(
90 "token:DOUBLE_CLOSE_CURLY_BRACE",
91 "}}",
92 variable_reference_documentation='Literal "}}" string - useful to avoid triggering a substitution',
93 )
96def register_package_metadata_detectors(api: DebputyPluginInitializer) -> None:
97 api.metadata_or_maintscript_detector("systemd-tmpfiles", detect_systemd_tmpfiles)
98 api.metadata_or_maintscript_detector("systemd-sysusers", detect_systemd_sysusers)
99 api.metadata_or_maintscript_detector("list-commands", detect_commands)
100 api.metadata_or_maintscript_detector("kernel-modules", detect_kernel_modules)
101 api.metadata_or_maintscript_detector("icon-cache", detect_icons)
102 api.metadata_or_maintscript_detector(
103 "gsettings-dependencies",
104 detect_gsettings_dependencies,
105 )
106 api.metadata_or_maintscript_detector("xfonts", detect_xfonts)
107 api.metadata_or_maintscript_detector("initramfs-hooks", detect_initramfs_hooks)
108 api.metadata_or_maintscript_detector("pycompile-files", detect_pycompile_files)
109 api.metadata_or_maintscript_detector(
110 "translate-capabilities",
111 translate_capabilities,
112 )
113 api.metadata_or_maintscript_detector("pam-auth-update", pam_auth_update)
114 api.metadata_or_maintscript_detector(
115 "auto-depends-arch-any-solink",
116 auto_depends_arch_any_solink,
117 )
120def register_packager_provided_files(api: DebputyPluginInitializer) -> None:
121 api.packager_provided_file(
122 "tmpfiles",
123 f"{SYSTEMD_TMPFILES_DIR}/{ name} .conf",
124 reference_documentation=packager_provided_file_reference_documentation(
125 format_documentation_uris=["man:tmpfiles.d(5)"]
126 ),
127 )
128 api.packager_provided_file(
129 "sysusers",
130 f"{SYSTEMD_SYSUSERS_DIR}/{ name} .conf",
131 reference_documentation=packager_provided_file_reference_documentation(
132 format_documentation_uris=["man:sysusers.d(5)"]
133 ),
134 )
135 api.packager_provided_file(
136 "bash-completion", "/usr/share/bash-completion/completions/{name}"
137 )
138 api.packager_provided_file(
139 "fish-completion", "/usr/share/fish/vendor_completions.d/{name}"
140 )
141 api.packager_provided_file(
142 "zsh-completion", "/usr/share/zsh/vendor-completions/{name}"
143 )
144 api.packager_provided_file(
145 "bug-script",
146 "./usr/share/bug/{name}/script",
147 default_mode=0o0755,
148 allow_name_segment=False,
149 )
150 api.packager_provided_file(
151 "bug-control",
152 "/usr/share/bug/{name}/control",
153 allow_name_segment=False,
154 )
156 api.packager_provided_file(
157 "bug-presubj",
158 "/usr/share/bug/{name}/presubj",
159 allow_name_segment=False,
160 )
162 api.packager_provided_file("pam", "/usr/lib/pam.d/{name}")
163 api.packager_provided_file(
164 "ppp.ip-up",
165 "/etc/ppp/ip-up.d/{name}",
166 default_mode=0o0755,
167 )
168 api.packager_provided_file(
169 "ppp.ip-down",
170 "/etc/ppp/ip-down.d/{name}",
171 default_mode=0o0755,
172 )
173 api.packager_provided_file(
174 "lintian-overrides",
175 "/usr/share/lintian/overrides/{name}",
176 allow_name_segment=False,
177 )
178 api.packager_provided_file("logrotate", "/etc/logrotate.d/{name}")
179 api.packager_provided_file(
180 "logcheck.cracking",
181 "/etc/logcheck/cracking.d/{name}",
182 post_formatting_rewrite=_replace_dot_with_underscore,
183 )
184 api.packager_provided_file(
185 "logcheck.violations",
186 "/etc/logcheck/violations.d/{name}",
187 post_formatting_rewrite=_replace_dot_with_underscore,
188 )
189 api.packager_provided_file(
190 "logcheck.violations.ignore",
191 "/etc/logcheck/violations.ignore.d/{name}",
192 post_formatting_rewrite=_replace_dot_with_underscore,
193 )
194 api.packager_provided_file(
195 "logcheck.ignore.workstation",
196 "/etc/logcheck/ignore.d.workstation/{name}",
197 post_formatting_rewrite=_replace_dot_with_underscore,
198 )
199 api.packager_provided_file(
200 "logcheck.ignore.server",
201 "/etc/logcheck/ignore.d.server/{name}",
202 post_formatting_rewrite=_replace_dot_with_underscore,
203 )
204 api.packager_provided_file(
205 "logcheck.ignore.paranoid",
206 "/etc/logcheck/ignore.d.paranoid/{name}",
207 post_formatting_rewrite=_replace_dot_with_underscore,
208 )
210 api.packager_provided_file("mime", "/usr/lib/mime/packages/{name}")
211 api.packager_provided_file("sharedmimeinfo", "/usr/share/mime/packages/{name}.xml")
213 api.packager_provided_file(
214 "if-pre-up",
215 "/etc/network/if-pre-up.d/{name}",
216 default_mode=0o0755,
217 )
218 api.packager_provided_file(
219 "if-up",
220 "/etc/network/if-up.d/{name}",
221 default_mode=0o0755,
222 )
223 api.packager_provided_file(
224 "if-down",
225 "/etc/network/if-down.d/{name}",
226 default_mode=0o0755,
227 )
228 api.packager_provided_file(
229 "if-post-down",
230 "/etc/network/if-post-down.d/{name}",
231 default_mode=0o0755,
232 )
234 api.packager_provided_file(
235 "cron.hourly",
236 "/etc/cron.hourly/{name}",
237 default_mode=0o0755,
238 )
239 api.packager_provided_file(
240 "cron.daily",
241 "/etc/cron.daily/{name}",
242 default_mode=0o0755,
243 )
244 api.packager_provided_file(
245 "cron.weekly",
246 "/etc/cron.weekly/{name}",
247 default_mode=0o0755,
248 )
249 api.packager_provided_file(
250 "cron.monthly",
251 "./etc/cron.monthly/{name}",
252 default_mode=0o0755,
253 )
254 api.packager_provided_file(
255 "cron.yearly",
256 "/etc/cron.yearly/{name}",
257 default_mode=0o0755,
258 )
259 # cron.d uses 0644 unlike the others
260 api.packager_provided_file(
261 "cron.d",
262 "/etc/cron.d/{name}",
263 reference_documentation=packager_provided_file_reference_documentation(
264 format_documentation_uris=["man:crontab(5)"]
265 ),
266 )
268 api.packager_provided_file(
269 "initramfs-hook", f"{INITRAMFS_HOOK_DIR}/{ name} ", default_mode=0o0755
270 )
272 api.packager_provided_file("modprobe", "/etc/modprobe.d/{name}.conf")
274 api.packager_provided_file(
275 "init",
276 "/etc/init.d/{name}",
277 default_mode=0o755,
278 )
279 api.packager_provided_file("default", "/etc/default/{name}")
281 for stem in [
282 "mount",
283 "path",
284 "service",
285 "socket",
286 "target",
287 "timer",
288 ]:
289 api.packager_provided_file(
290 stem,
291 f"/usr/lib/systemd/system/{ name} .{stem}",
292 reference_documentation=packager_provided_file_reference_documentation(
293 format_documentation_uris=[f"man:systemd.{stem}(5)"]
294 ),
295 )
297 for stem in [
298 "path",
299 "service",
300 "socket",
301 "target",
302 "timer",
303 ]:
304 api.packager_provided_file(
305 f"@{stem}", f"/usr/lib/systemd/system/{ name} @.{stem}"
306 )
308 api.packager_provided_file(
309 "udev",
310 "/usr/lib/udev/rules.d/{priority:02}-{name}.rules",
311 default_priority=60,
312 )
314 api.packager_provided_file(
315 "gsettings-override",
316 f"{GSETTINGS_SCHEMA_DIR}/{ priority:02} _{ name} .gschema.override",
317 default_priority=10,
318 )
320 # Special-cases that will probably not be a good example for other plugins
321 api.packager_provided_file(
322 "changelog",
323 # The "changelog.Debian" gets renamed to "changelog" for native packages elsewhere.
324 # Also, the changelog trimming is also done elsewhere.
325 "/usr/share/doc/{name}/changelog.Debian",
326 allow_name_segment=False,
327 packageless_is_fallback_for_all_packages=True,
328 reference_documentation=packager_provided_file_reference_documentation(
329 description=textwrap.dedent(
330 """\
331 This file is the changelog of the package and is mandatory.
333 The changelog contains the version of the source package and is mandatory for all
334 packages.
336 Use `dch --create` to create the changelog.
338 In theory, the binary package can have a different changelog than the source
339 package (by having `debian/binary-package.changelog`). However, it is generally
340 not useful and leads to double administration. It has not been used in practice.
341 """
342 ),
343 format_documentation_uris=[
344 "man:deb-changelog(5)",
345 "https://www.debian.org/doc/debian-policy/ch-source.html#debian-changelog-debian-changelog",
346 "man:dch(1)",
347 ],
348 ),
349 )
350 api.packager_provided_file(
351 "copyright",
352 "/usr/share/doc/{name}/copyright",
353 allow_name_segment=False,
354 packageless_is_fallback_for_all_packages=True,
355 reference_documentation=packager_provided_file_reference_documentation(
356 description=textwrap.dedent(
357 """\
358 This file documents the license and copyright information of the binary package.
359 Packages aimed at the Debian archive (and must derivatives thereof) must have this file.
361 For packages not aimed at Debian, the file can still be useful to convey the license
362 terms of the package (which is often a requirement in many licenses). However, it is
363 not a strict *technical* requirement. Whether it is a legal requirement depends on
364 license.
366 Often, the same file can be used for all packages. In the extremely rare case where
367 one binary package has a "vastly different" license than the other packages, you can
368 provide a package specific version for that package.
369 """
370 ),
371 format_documentation_uris=[
372 "https://www.debian.org/doc/debian-policy/ch-source.html#copyright-debian-copyright",
373 "https://www.debian.org/doc/debian-policy/ch-docs.html#s-copyrightfile",
374 "https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/",
375 ],
376 ),
377 )
378 api.packager_provided_file(
379 "NEWS",
380 "/usr/share/doc/{name}/NEWS.Debian",
381 allow_name_segment=False,
382 packageless_is_fallback_for_all_packages=True,
383 reference_documentation=packager_provided_file_reference_documentation(
384 description=textwrap.dedent(
385 """\
386 Important news that should be shown to the user/admin when upgrading. If a system has
387 apt-listchanges installed, then contents of this file will be shown prior to upgrading
388 the package.
390 Uses a similar format to that of debian/changelog (create with `dch --news --create`).
391 """
392 ),
393 format_documentation_uris=[
394 "https://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.en.html#supplementing-changelogs-with-news-debian-files",
395 "man:dch(1)",
396 ],
397 ),
398 )
399 api.packager_provided_file(
400 "README.Debian",
401 "/usr/share/doc/{name}/README.Debian",
402 allow_name_segment=False,
403 )
404 api.packager_provided_file(
405 "TODO",
406 "/usr/share/doc/{name}/TODO.Debian",
407 allow_name_segment=False,
408 )
409 # From dh-python / dh_python3
410 # api.packager_provided_file(
411 # "bcep",
412 # "/usr/share/python3/bcep/{name}",
413 # allow_name_segment=False,
414 # )
417def _replace_dot_with_underscore(x: str) -> str:
418 return x.replace(".", "_")