Coverage for lobster/common/meta_data_tool_base.py: 100%
19 statements
« prev ^ index » next coverage.py v7.10.5, created at 2025-08-27 13:02 +0000
« 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
7BUG_URL = "https://github.com/bmw-software-engineering/lobster/issues"
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.
19 It provides an ArgumentParser and implements the --version and --help
20 features.
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."""
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 )
49 @property
50 def name(self) -> str:
51 """The name of the tool, prefixed with 'lobster-'."""
52 return self._name
54 def run(self, args: Optional[Sequence[str]] = None) -> int:
55 """
56 Parse the command line arguments and run the tool implementation.
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 """
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
70 @abstractmethod
71 def _run_impl(self, options: Namespace) -> int:
72 """This method should be implemented by subclasses to run the tool.
74 The return value shall be an exit code.
75 """