Coverage for src/debputy/plugin/debputy/debputy_plugin.py: 100%

78 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2024-04-07 12:14 +0200

1import textwrap 

2 

3from debputy.plugin.api import ( 

4 DebputyPluginInitializer, 

5 packager_provided_file_reference_documentation, 

6) 

7from debputy.plugin.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) 

20from debputy.plugin.debputy.paths import ( 

21 SYSTEMD_TMPFILES_DIR, 

22 INITRAMFS_HOOK_DIR, 

23 GSETTINGS_SCHEMA_DIR, 

24 SYSTEMD_SYSUSERS_DIR, 

25) 

26from debputy.plugin.debputy.private_api import initialize_via_private_api 

27 

28 

29def initialize_debputy_features(api: DebputyPluginInitializer) -> None: 

30 initialize_via_private_api(api) 

31 declare_manifest_variables(api) 

32 register_packager_provided_files(api) 

33 register_package_metadata_detectors(api) 

34 

35 

36def declare_manifest_variables(api: DebputyPluginInitializer) -> None: 

37 api.manifest_variable( 

38 "path:BASH_COMPLETION_DIR", 

39 "/usr/share/bash-completion/completions", 

40 variable_reference_documentation="Directory to install bash completions into", 

41 ) 

42 api.manifest_variable( 

43 "path:GNU_INFO_DIR", 

44 "/usr/share/info", 

45 variable_reference_documentation="Directory to install GNU INFO files into", 

46 ) 

47 

48 api.manifest_variable( 

49 "token:NL", 

50 "\n", 

51 variable_reference_documentation="Literal newline (linefeed) character", 

52 ) 

53 api.manifest_variable( 

54 "token:NEWLINE", 

55 "\n", 

56 variable_reference_documentation="Literal newline (linefeed) character", 

57 ) 

58 api.manifest_variable( 

59 "token:TAB", 

60 "\t", 

61 variable_reference_documentation="Literal tab character", 

62 ) 

63 api.manifest_variable( 

64 "token:OPEN_CURLY_BRACE", 

65 "{", 

66 variable_reference_documentation='Literal "{" character', 

67 ) 

68 api.manifest_variable( 

69 "token:CLOSE_CURLY_BRACE", 

70 "}", 

71 variable_reference_documentation='Literal "}" character', 

72 ) 

73 api.manifest_variable( 

74 "token:DOUBLE_OPEN_CURLY_BRACE", 

75 "{{", 

76 variable_reference_documentation='Literal "{{" character - useful to avoid triggering a substitution', 

77 ) 

78 api.manifest_variable( 

79 "token:DOUBLE_CLOSE_CURLY_BRACE", 

80 "}}", 

81 variable_reference_documentation='Literal "}}" string - useful to avoid triggering a substitution', 

82 ) 

83 

84 

85def register_package_metadata_detectors(api: DebputyPluginInitializer) -> None: 

86 api.metadata_or_maintscript_detector("systemd-tmpfiles", detect_systemd_tmpfiles) 

87 api.metadata_or_maintscript_detector("systemd-sysusers", detect_systemd_sysusers) 

88 api.metadata_or_maintscript_detector("kernel-modules", detect_kernel_modules) 

89 api.metadata_or_maintscript_detector("icon-cache", detect_icons) 

90 api.metadata_or_maintscript_detector( 

91 "gsettings-dependencies", 

92 detect_gsettings_dependencies, 

93 ) 

94 api.metadata_or_maintscript_detector("xfonts", detect_xfonts) 

95 api.metadata_or_maintscript_detector("initramfs-hooks", detect_initramfs_hooks) 

96 api.metadata_or_maintscript_detector("pycompile-files", detect_pycompile_files) 

97 api.metadata_or_maintscript_detector( 

98 "translate-capabilities", 

99 translate_capabilities, 

100 ) 

101 api.metadata_or_maintscript_detector("pam-auth-update", pam_auth_update) 

102 api.metadata_or_maintscript_detector( 

103 "auto-depends-arch-any-solink", 

104 auto_depends_arch_any_solink, 

105 ) 

106 

107 

108def register_packager_provided_files(api: DebputyPluginInitializer) -> None: 

109 api.packager_provided_file( 

110 "tmpfiles", 

111 f"{SYSTEMD_TMPFILES_DIR}/{{name}}.conf", 

112 reference_documentation=packager_provided_file_reference_documentation( 

113 format_documentation_uris=["man:tmpfiles.d(5)"] 

114 ), 

115 ) 

116 api.packager_provided_file( 

117 "sysusers", 

118 f"{SYSTEMD_SYSUSERS_DIR}/{{name}}.conf", 

119 reference_documentation=packager_provided_file_reference_documentation( 

120 format_documentation_uris=["man:sysusers.d(5)"] 

121 ), 

122 ) 

123 api.packager_provided_file( 

124 "bash-completion", "/usr/share/bash-completion/completions/{name}" 

125 ) 

126 api.packager_provided_file( 

127 "bug-script", 

128 "./usr/share/bug/{name}/script", 

129 default_mode=0o0755, 

130 allow_name_segment=False, 

131 ) 

132 api.packager_provided_file( 

133 "bug-control", 

134 "/usr/share/bug/{name}/control", 

135 allow_name_segment=False, 

136 ) 

137 

138 api.packager_provided_file( 

139 "bug-presubj", 

140 "/usr/share/bug/{name}/presubj", 

141 allow_name_segment=False, 

142 ) 

143 

144 api.packager_provided_file("pam", "/usr/lib/pam.d/{name}") 

145 api.packager_provided_file( 

146 "ppp.ip-up", 

147 "/etc/ppp/ip-up.d/{name}", 

148 default_mode=0o0755, 

149 ) 

150 api.packager_provided_file( 

151 "ppp.ip-down", 

152 "/etc/ppp/ip-down.d/{name}", 

153 default_mode=0o0755, 

154 ) 

155 api.packager_provided_file( 

156 "lintian-overrides", 

157 "/usr/share/lintian/overrides/{name}", 

158 allow_name_segment=False, 

159 ) 

160 api.packager_provided_file("logrotate", "/etc/logrotate.d/{name}") 

161 api.packager_provided_file( 

162 "logcheck.cracking", 

163 "/etc/logcheck/cracking.d/{name}", 

164 post_formatting_rewrite=_replace_dot_with_underscore, 

165 ) 

166 api.packager_provided_file( 

167 "logcheck.violations", 

168 "/etc/logcheck/violations.d/{name}", 

169 post_formatting_rewrite=_replace_dot_with_underscore, 

170 ) 

171 api.packager_provided_file( 

172 "logcheck.violations.ignore", 

173 "/etc/logcheck/violations.ignore.d/{name}", 

174 post_formatting_rewrite=_replace_dot_with_underscore, 

175 ) 

176 api.packager_provided_file( 

177 "logcheck.ignore.workstation", 

178 "/etc/logcheck/ignore.d.workstation/{name}", 

179 post_formatting_rewrite=_replace_dot_with_underscore, 

180 ) 

181 api.packager_provided_file( 

182 "logcheck.ignore.server", 

183 "/etc/logcheck/ignore.d.server/{name}", 

184 post_formatting_rewrite=_replace_dot_with_underscore, 

185 ) 

186 api.packager_provided_file( 

187 "logcheck.ignore.paranoid", 

188 "/etc/logcheck/ignore.d.paranoid/{name}", 

189 post_formatting_rewrite=_replace_dot_with_underscore, 

190 ) 

191 

192 api.packager_provided_file("mime", "/usr/lib/mime/packages/{name}") 

193 api.packager_provided_file("sharedmimeinfo", "/usr/share/mime/packages/{name}.xml") 

194 

195 api.packager_provided_file( 

196 "if-pre-up", 

197 "/etc/network/if-pre-up.d/{name}", 

198 default_mode=0o0755, 

199 ) 

200 api.packager_provided_file( 

201 "if-up", 

202 "/etc/network/if-up.d/{name}", 

203 default_mode=0o0755, 

204 ) 

205 api.packager_provided_file( 

206 "if-down", 

207 "/etc/network/if-down.d/{name}", 

208 default_mode=0o0755, 

209 ) 

210 api.packager_provided_file( 

211 "if-post-down", 

212 "/etc/network/if-post-down.d/{name}", 

213 default_mode=0o0755, 

214 ) 

215 

216 api.packager_provided_file( 

217 "cron.hourly", 

218 "/etc/cron.hourly/{name}", 

219 default_mode=0o0755, 

220 ) 

221 api.packager_provided_file( 

222 "cron.daily", 

223 "/etc/cron.daily/{name}", 

224 default_mode=0o0755, 

225 ) 

226 api.packager_provided_file( 

227 "cron.weekly", 

228 "/etc/cron.weekly/{name}", 

229 default_mode=0o0755, 

230 ) 

231 api.packager_provided_file( 

232 "cron.monthly", 

233 "./etc/cron.monthly/{name}", 

234 default_mode=0o0755, 

235 ) 

236 api.packager_provided_file( 

237 "cron.yearly", 

238 "/etc/cron.yearly/{name}", 

239 default_mode=0o0755, 

240 ) 

241 # cron.d uses 0644 unlike the others 

242 api.packager_provided_file( 

243 "cron.d", 

244 "/etc/cron.d/{name}", 

245 reference_documentation=packager_provided_file_reference_documentation( 

246 format_documentation_uris=["man:crontab(5)"] 

247 ), 

248 ) 

249 

250 api.packager_provided_file( 

251 "initramfs-hook", f"{INITRAMFS_HOOK_DIR}/{{name}}", default_mode=0o0755 

252 ) 

253 

254 api.packager_provided_file("modprobe", "/etc/modprobe.d/{name}.conf") 

255 

256 api.packager_provided_file( 

257 "init", 

258 "/etc/init.d/{name}", 

259 default_mode=0o755, 

260 ) 

261 api.packager_provided_file("default", "/etc/default/{name}") 

262 

263 for stem in [ 

264 "mount", 

265 "path", 

266 "service", 

267 "socket", 

268 "target", 

269 "timer", 

270 ]: 

271 api.packager_provided_file( 

272 stem, 

273 f"/usr/lib/systemd/system/{{name}}.{stem}", 

274 reference_documentation=packager_provided_file_reference_documentation( 

275 format_documentation_uris=[f"man:systemd.{stem}(5)"] 

276 ), 

277 ) 

278 

279 for stem in [ 

280 "path", 

281 "service", 

282 "socket", 

283 "target", 

284 "timer", 

285 ]: 

286 api.packager_provided_file( 

287 f"@{stem}", f"/usr/lib/systemd/system/{{name}}@.{stem}" 

288 ) 

289 

290 # api.packager_provided_file( 

291 # "udev", 

292 # "./lib/udev/rules.d/{priority:02}-{name}.rules", 

293 # default_priority=60, 

294 # ) 

295 

296 api.packager_provided_file( 

297 "gsettings-override", 

298 f"{GSETTINGS_SCHEMA_DIR}/{{priority:02}}_{{name}}.gschema.override", 

299 default_priority=10, 

300 ) 

301 

302 # Special-cases that will probably not be a good example for other plugins 

303 api.packager_provided_file( 

304 "changelog", 

305 # The "changelog.Debian" gets renamed to "changelog" for native packages elsewhere. 

306 # Also, the changelog trimming is also done elsewhere. 

307 "/usr/share/doc/{name}/changelog.Debian", 

308 allow_name_segment=False, 

309 packageless_is_fallback_for_all_packages=True, 

310 reference_documentation=packager_provided_file_reference_documentation( 

311 description=textwrap.dedent( 

312 """\ 

313 This file is the changelog of the package and is mandatory. 

314 

315 The changelog contains the version of the source package and is mandatory for all 

316 packages. 

317 

318 Use `dch --create` to create the changelog. 

319 

320 In theory, the binary package can have a different changelog than the source 

321 package (by having `debian/binary-package.changelog`). However, it is generally 

322 not useful and leads to double administration. It has not been used in practice. 

323 """ 

324 ), 

325 format_documentation_uris=[ 

326 "man:deb-changelog(5)", 

327 "https://www.debian.org/doc/debian-policy/ch-source.html#debian-changelog-debian-changelog", 

328 "man:dch(1)", 

329 ], 

330 ), 

331 ) 

332 api.packager_provided_file( 

333 "copyright", 

334 "/usr/share/doc/{name}/copyright", 

335 allow_name_segment=False, 

336 packageless_is_fallback_for_all_packages=True, 

337 reference_documentation=packager_provided_file_reference_documentation( 

338 description=textwrap.dedent( 

339 """\ 

340 This file documents the license and copyright information of the binary package. 

341 Packages aimed at the Debian archive (and must derivatives thereof) must have this file. 

342 

343 For packages not aimed at Debian, the file can still be useful to convey the license 

344 terms of the package (which is often a requirement in many licenses). However, it is 

345 not a strict *technical* requirement. Whether it is a legal requirement depends on 

346 license. 

347 

348 Often, the same file can be used for all packages. In the extremely rare case where 

349 one binary package has a "vastly different" license than the other packages, you can 

350 provide a package specific version for that package. 

351 """ 

352 ), 

353 format_documentation_uris=[ 

354 "https://www.debian.org/doc/debian-policy/ch-source.html#copyright-debian-copyright", 

355 "https://www.debian.org/doc/debian-policy/ch-docs.html#s-copyrightfile", 

356 "https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/", 

357 ], 

358 ), 

359 ) 

360 api.packager_provided_file( 

361 "NEWS", 

362 "/usr/share/doc/{name}/NEWS.Debian", 

363 allow_name_segment=False, 

364 packageless_is_fallback_for_all_packages=True, 

365 reference_documentation=packager_provided_file_reference_documentation( 

366 description=textwrap.dedent( 

367 """\ 

368 Important news that should be shown to the user/admin when upgrading. If a system has 

369 apt-listchanges installed, then contents of this file will be shown prior to upgrading 

370 the package. 

371 

372 Uses a similar format to that of debian/changelog (create with `dch --news --create`). 

373 """ 

374 ), 

375 format_documentation_uris=[ 

376 "https://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.en.html#supplementing-changelogs-with-news-debian-files", 

377 "man:dch(1)", 

378 ], 

379 ), 

380 ) 

381 api.packager_provided_file( 

382 "README.Debian", 

383 "/usr/share/doc/{name}/README.Debian", 

384 allow_name_segment=False, 

385 ) 

386 api.packager_provided_file( 

387 "TODO", 

388 "/usr/share/doc/{name}/TODO.Debian", 

389 allow_name_segment=False, 

390 ) 

391 # From dh-python / dh_python3 

392 # api.packager_provided_file( 

393 # "bcep", 

394 # "/usr/share/python3/bcep/{name}", 

395 # allow_name_segment=False, 

396 # ) 

397 

398 

399def _replace_dot_with_underscore(x: str) -> str: 

400 return x.replace(".", "_")