Coverage for frappe_manager / main.py: 0%

54 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-07-02 18:13 +0530

1import atexit 

2import signal 

3 

4from frappe_manager import CLI_LOG_DIRECTORY 

5from frappe_manager.commands import app 

6from frappe_manager.exceptions import FrappeManagerException 

7from frappe_manager.logger import log 

8from frappe_manager.output_manager.globals import get_global_output_handler, set_global_output_handler 

9from frappe_manager.output_manager.rich_output import RichOutputHandler 

10from frappe_manager.utils.docker import process_opened 

11from frappe_manager.utils.helpers import capture_and_format_exception, remove_zombie_subprocess_process 

12 

13 

14def cli_entrypoint(): 

15 """ 

16 Main CLI entry point. 

17 

18 Initializes a basic RichOutputHandler early, which will be upgraded 

19 to LoggingOutputHandler in app_callback (commands/__init__.py) after 

20 CLI arguments are parsed. Exception handling uses bare richprint for 

21 backward compatibility. 

22 """ 

23 if hasattr(signal, "SIGPIPE"): 

24 signal.signal(signal.SIGPIPE, signal.SIG_DFL) 

25 

26 # Initialize basic output handler early (before app() runs) 

27 # This will be upgraded to LoggingOutputHandler in app_callback after CLI args are parsed 

28 basic_handler = RichOutputHandler() 

29 set_global_output_handler(basic_handler) 

30 

31 try: 

32 app() 

33 except FrappeManagerException as e: 

34 try: 

35 from frappe_manager.metadata_manager import FMConfigManager 

36 

37 fm_config = FMConfigManager.import_from_toml() 

38 file_level = fm_config.logs.file_level 

39 except Exception: 

40 file_level = "DEBUG" 

41 

42 logger = log.get_logger(file_level=file_level) 

43 output = get_global_output_handler() 

44 

45 output.display_error(f"[red]Error Occurred[/red] {str(e).strip()}") 

46 

47 # Show details if available 

48 if e.details: 

49 output.display_error(f"Details: {e.details}") 

50 

51 output.print(f"More info about error is logged in {CLI_LOG_DIRECTORY / 'fm.log'}", emoji_code=":mag:") 

52 output.stop() 

53 

54 exception_traceback: str = capture_and_format_exception() 

55 logger.error(f"FM Exception: {e.__class__.__name__}: {e!s}\n{exception_traceback}") 

56 exit(1) 

57 

58 except Exception as e: 

59 try: 

60 from frappe_manager.metadata_manager import FMConfigManager 

61 

62 fm_config = FMConfigManager.import_from_toml() 

63 file_level = fm_config.logs.file_level 

64 except Exception: 

65 file_level = "DEBUG" 

66 

67 logger = log.get_logger(file_level=file_level) 

68 output = get_global_output_handler() 

69 

70 output.display_error(f"[red]Unexpected Error[/red] {str(e).strip()}") 

71 output.print(f"More info about error is logged in {CLI_LOG_DIRECTORY / 'fm.log'}", emoji_code=":mag:") 

72 output.stop() 

73 

74 exception_traceback: str = capture_and_format_exception() 

75 logger.error(f"Unexpected Exception:\n{exception_traceback}") 

76 exit(1) 

77 

78 finally: 

79 atexit.register(exit_cleanup) 

80 

81 

82def exit_cleanup(): 

83 """ 

84 This function is used to perform cleanup at the exit. 

85 """ 

86 remove_zombie_subprocess_process(process_opened) 

87 output = get_global_output_handler() 

88 output.stop()