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

24 statements  

« prev     ^ index     » next       coverage.py v7.8.2, created at 2025-09-07 09:27 +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( 

36 f"""\ 

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

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

39 py3clean {PRIVATE_PYTHON_DIR} 

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

41 py3compile {PRIVATE_PYTHON_DIR} 

42 fi 

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

44 pypy3compile {PRIVATE_PYTHON_DIR} || true 

45 fi 

46 fi 

47 """ 

48 ), 

49 ) 

50 maintscript.unconditionally_in_script( 

51 "prerm", 

52 textwrap.dedent( 

53 f"""\ 

54 if command -v py3clean >/dev/null 2>&1; then 

55 py3clean {PRIVATE_PYTHON_DIR} 

56 else 

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

58 fi 

59 """ 

60 ), 

61 ) 

62 

63 

64def _rtupdate_generator( 

65 fs_root: VirtualPath, 

66 _: Any, 

67 context: "PackageProcessingContext", 

68) -> None: 

69 package_name = context.binary_package.name 

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

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

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

73 rtupdate_dir: VirtualPathBase = cast( 

74 "VirtualPathBase", 

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

76 ) 

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

78 template = textwrap.dedent( 

79 f"""\ 

80 #! /bin/sh 

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

82 py3clean {PRIVATE_PYTHON_DIR} 

83 py3compile {PRIVATE_PYTHON_DIR} 

84 fi 

85 """ 

86 ) 

87 fd.write(template) 

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

89 

90 

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

92 api.metadata_or_maintscript_detector( 

93 "debputy-self-hosting", 

94 _maintscript_generator, 

95 ) 

96 internal_api: DebputyPluginInitializerProvider = cast( 

97 "DebputyPluginInitializerProvider", api 

98 ) 

99 internal_api.package_processor( 

100 "rtupdate", 

101 _rtupdate_generator, 

102 )