Coverage for /home/runner/work/bijux-cli/bijux-cli/src/bijux_cli/services/plugins/hooks.py: 100%

30 statements  

« prev     ^ index     » next       coverage.py v7.10.4, created at 2025-08-19 23:36 +0000

1# SPDX-License-Identifier: MIT 

2# Copyright © 2025 Bijan Mousavi 

3 

4"""Defines the hook specifications for the Bijux CLI plugin system. 

5 

6This module uses `pluggy`'s hook specification markers to define the formal 

7set of hooks that plugins can implement. The `CoreSpec` class groups all 

8standard lifecycle and execution hooks that the core application will invoke 

9on registered plugins. This provides a clear and versioned interface for 

10plugin developers. 

11""" 

12 

13from __future__ import annotations 

14 

15from typing import Any 

16 

17import pluggy 

18 

19import bijux_cli 

20from bijux_cli.contracts import ObservabilityProtocol 

21from bijux_cli.core.di import DIContainer 

22 

23PRE_EXECUTE = "pre_execute" 

24POST_EXECUTE = "post_execute" 

25SPEC_VERSION = bijux_cli.version 

26 

27hookspec = pluggy.HookspecMarker("bijux") 

28 

29 

30class CoreSpec: 

31 """Defines the core hook specifications for CLI plugins. 

32 

33 Plugins can implement methods matching these specifications to integrate with 

34 the CLI's lifecycle and command execution flow. 

35 

36 Attributes: 

37 _log (ObservabilityProtocol): The logging service. 

38 """ 

39 

40 def __init__(self, dependency_injector: DIContainer) -> None: 

41 """Initializes the `CoreSpec`. 

42 

43 Args: 

44 dependency_injector (DIContainer): The DI container for resolving 

45 services like the logger. 

46 """ 

47 self._log = dependency_injector.resolve(ObservabilityProtocol) 

48 

49 @hookspec 

50 async def startup(self) -> None: 

51 """A hook that is called once when the CLI engine starts up. 

52 

53 Plugins can use this hook to perform initialization tasks, such as 

54 setting up resources or starting background tasks. 

55 """ 

56 self._log.log("debug", "Hook startup called", extra={}) 

57 

58 @hookspec 

59 async def shutdown(self) -> None: 

60 """A hook that is called once when the CLI engine shuts down. 

61 

62 Plugins can use this hook to perform cleanup tasks, such as releasing 

63 resources or flushing buffers. 

64 """ 

65 self._log.log("debug", "Hook shutdown called", extra={}) 

66 

67 @hookspec 

68 async def pre_execute( 

69 self, name: str, args: tuple[Any, ...], kwargs: dict[str, Any] 

70 ) -> None: 

71 """A hook that is called immediately before a command is executed. 

72 

73 Args: 

74 name (str): The name of the command to be executed. 

75 args (tuple[Any, ...]): The positional arguments passed to the command. 

76 kwargs (dict[str, Any]): The keyword arguments passed to the command. 

77 """ 

78 self._log.log( 

79 "debug", 

80 "Hook pre_execute called", 

81 extra={"name": name, "args": args, "kwargs": kwargs}, 

82 ) 

83 

84 @hookspec 

85 async def post_execute(self, name: str, result: Any) -> None: 

86 """A hook that is called immediately after a command has executed. 

87 

88 Args: 

89 name (str): The name of the command that was executed. 

90 result (Any): The result object returned from the command. 

91 """ 

92 self._log.log( 

93 "debug", 

94 "Hook post_execute called", 

95 extra={"name": name, "result": repr(result)}, 

96 ) 

97 

98 @hookspec 

99 def health(self) -> bool | str: 

100 """A hook to check the health of a plugin. 

101 

102 This hook is called by the `bijux plugins check` command. A plugin can 

103 return a boolean or a string to indicate its status. 

104 

105 Returns: 

106 bool | str: `True` for healthy, `False` for unhealthy, or a string 

107 with a descriptive status message. 

108 """ 

109 self._log.log("debug", "Hook health called", extra={}) 

110 return True 

111 

112 

113__all__ = ["CoreSpec", "SPEC_VERSION", "PRE_EXECUTE", "POST_EXECUTE"]