Coverage for lobster/common/meta_data_tool_base.py: 74%

19 statements  

« prev     ^ index     » next       coverage.py v7.10.5, created at 2025-08-27 13:02 +0000

1from abc import abstractmethod, ABCMeta 

2from argparse import ArgumentParser, Namespace, RawTextHelpFormatter 

3from typing import Optional, Sequence 

4from lobster.common.version import FULL_NAME 

5 

6 

7BUG_URL = "https://github.com/bmw-software-engineering/lobster/issues" 

8 

9 

10class MetaDataToolBase(metaclass=ABCMeta): 

11 def __init__( 

12 self, 

13 name: str, 

14 description: str, 

15 official: bool, 

16 ) -> None: 

17 """Base class for LOBSTER tools. 

18 

19 It provides an ArgumentParser and implements the --version and --help 

20 features. 

21 

22 params: 

23 name (str): The name of the tool, without the 'lobster-' prefix. 

24 description (str): A brief description of the tool. 

25 It will be used in the help message. 

26 official (bool): Whether the tool is an official LOBSTER tool. 

27 This flag determines the URL for the bug ticker.""" 

28 

29 self._name = f"lobster-{name}" 

30 self._argument_parser = ArgumentParser( 

31 prog = self._name, 

32 description = description, 

33 epilog = (f"Part of {FULL_NAME}, licensed under the AGPLv3." 

34 f" Please report bugs to {BUG_URL}." 

35 if official else None), 

36 allow_abbrev = False, 

37 formatter_class=RawTextHelpFormatter, 

38 fromfile_prefix_chars="@", # lobster-trace: req.Args_From_File 

39 ) 

40 self._argument_parser.add_argument( 

41 "-v", 

42 "--version", 

43 action="version", 

44 default=None, 

45 help="print version and exit", 

46 version=FULL_NAME, 

47 ) 

48 

49 @property 

50 def name(self) -> str: 

51 """The name of the tool, prefixed with 'lobster-'.""" 

52 return self._name 

53 

54 def run(self, args: Optional[Sequence[str]] = None) -> int: 

55 """ 

56 Parse the command line arguments and run the tool implementation. 

57 

58 If the --version or --help flag is set, it prints those messages. 

59 Otherwise it calls the _run_impl method with the parsed arguments. 

60 """ 

61 

62 # parse_args calls sys.exit if 'args' contains --help or --version 

63 # so we wrap the call in a try-catch block 

64 try: 

65 parsed_arguments = self._argument_parser.parse_args(args) 

66 return self._run_impl(parsed_arguments) 

67 except SystemExit as e: 

68 return e.code 

69 

70 @abstractmethod 

71 def _run_impl(self, options: Namespace) -> int: 

72 """This method should be implemented by subclasses to run the tool. 

73 

74 The return value shall be an exit code. 

75 """