Coverage for self-hosting-plugins/debputy_self_hosting.py: 58%

24 statements  

« prev     ^ index     » next       coverage.py v7.8.2, created at 2026-04-19 20:37 +0000

1import textwrap 

2from typing import cast, Any, TYPE_CHECKING 

3 

4from debputy.plugin.api import ( 

5 DebputyPluginInitializer, 

6 VirtualPath, 

7 BinaryCtrlAccessor, 

8 PackageProcessingContext, 

9) 

10 

11from debputy.util import POSTINST_DEFAULT_CONDITION 

12 

13if TYPE_CHECKING: 

14 from debputy.filesystem_scan import VirtualPathBase 

15 from debputy.plugin.api.impl import DebputyPluginInitializerProvider 

16 

17PRIVATE_PYTHON_DIR = "/usr/share/debputy" 

18 

19 

20def _maintscript_generator( 

21 _path: VirtualPath, 

22 ctrl: BinaryCtrlAccessor, 

23 context: PackageProcessingContext, 

24) -> None: 

25 maintscript = ctrl.maintscript 

26 package_name = context.binary_package.name 

27 

28 # When `debputy` becomes a stand-alone package, it should have these maintscripts instead of dh-debputy 

29 # Admittedly, I hope to get rid of this plugin before then, but ... 

30 assert package_name == "dh-debputy", "Update the self-hosting plugin" 

31 

32 ctrl.dpkg_trigger("interest-noawait", PRIVATE_PYTHON_DIR) 

33 maintscript.unconditionally_in_script( 

34 "postinst", 

35 textwrap.dedent(f"""\ 

36 if {POSTINST_DEFAULT_CONDITION} || [ "$1" = "triggered" ] ; then 

37 # Ensure all plugins are byte-compiled (plus uninstalled plugins are cleaned up) 

38 py3clean {PRIVATE_PYTHON_DIR} 

39 if command -v py3compile >/dev/null 2>&1; then 

40 py3compile {PRIVATE_PYTHON_DIR} 

41 fi 

42 if command -v pypy3compile >/dev/null 2>&1; then 

43 pypy3compile {PRIVATE_PYTHON_DIR} || true 

44 fi 

45 fi 

46 """), 

47 ) 

48 maintscript.unconditionally_in_script( 

49 "prerm", 

50 textwrap.dedent(f"""\ 

51 if command -v py3clean >/dev/null 2>&1 && python3 -c 'pass' 2>/dev/null; then 

52 py3clean {PRIVATE_PYTHON_DIR} 

53 else 

54 find {PRIVATE_PYTHON_DIR}/ -type d -name __pycache__ -empty -print0 | xargs --null --no-run-if-empty rmdir 

55 fi 

56 """), 

57 ) 

58 

59 

60def _rtupdate_generator( 

61 fs_root: VirtualPath, 

62 _: Any, 

63 context: "PackageProcessingContext", 

64) -> None: 

65 package_name = context.binary_package.name 

66 # When `debputy` becomes a stand-alone package, it should have these scripts instead of dh-debputy 

67 # Admittedly, I hope to get rid of this plugin before then, but ... 

68 assert package_name == "dh-debputy", "Update the self-hosting plugin" 

69 rtupdate_dir: VirtualPathBase = cast( 

70 "VirtualPathBase", 

71 fs_root.mkdirs("/usr/share/python3/runtime.d/"), 

72 ) 

73 with rtupdate_dir.open_child("debputy.rtupdate", "w") as fd: 

74 template = textwrap.dedent(f"""\ 

75 #! /bin/sh 

76 if [ "$1" = rtupdate ]; then 

77 py3clean {PRIVATE_PYTHON_DIR} 

78 py3compile {PRIVATE_PYTHON_DIR} 

79 fi 

80 """) 

81 fd.write(template) 

82 rtupdate_dir["debputy.rtupdate"].chmod(0o755) 

83 

84 

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

86 api.metadata_or_maintscript_detector( 

87 "debputy-self-hosting", 

88 _maintscript_generator, 

89 ) 

90 internal_api: DebputyPluginInitializerProvider = cast( 

91 "DebputyPluginInitializerProvider", api 

92 ) 

93 internal_api.package_processor( 

94 "rtupdate", 

95 _rtupdate_generator, 

96 )