Coverage for codexa/core/handler.py: 87%

23 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-08-10 07:53 +0000

1import logging 

2import sys 

3from typing import Any, Dict 

4 

5import click 

6 

7from codexa.core.errors import CodexaBaseError, ExitCode 

8from codexa.core.output import print_warning 

9 

10logger = logging.getLogger(__name__) 

11 

12 

13class CliHandler(click.Group): 

14 """A wrapped around CLI invocation that handles related errors.""" 

15 

16 AUTHOR_DETAILS: Dict[str, str] = { 

17 "Author": "Chino Franco", 

18 "Github": "https://github.com/jgfranco17", 

19 } 

20 

21 def invoke(self, ctx: click.Context) -> Any: 

22 """Invoke the CLI and catch, log and exit for any raised errors.""" 

23 try: 

24 return super().invoke(ctx) 

25 

26 except CodexaBaseError as err: 

27 logger.exception(err) 

28 print_warning(f"{err.help_text}") 

29 sys.exit(err.exit_code) 

30 

31 except click.UsageError as err: 

32 err.show() 

33 sys.exit(ExitCode.RUNTIME_ERROR) 

34 

35 def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None: 

36 """Customize help info.""" 

37 super().format_help(ctx, formatter) 

38 details = "\n".join( 

39 [f"{key}: {value}" for key, value in self.AUTHOR_DETAILS.items()] 

40 ) 

41 formatter.write(f"\n{details}")