|
2 | 2 |
|
3 | 3 | import argparse |
4 | 4 | import logging |
5 | | -from inspect import getfile |
6 | 5 | from pathlib import Path |
7 | 6 | from typing import Any |
8 | 7 |
|
9 | 8 | from qfc_worker.workflow import Workflow, run_workflow |
10 | 9 |
|
11 | 10 | logger = logging.getLogger(__name__) |
12 | 11 |
|
13 | | -registry = {} |
14 | 12 |
|
15 | 13 | parser = argparse.ArgumentParser(prog="COMMAND") |
16 | 14 | subparsers = parser.add_subparsers(dest="cmd") |
17 | 15 |
|
18 | 16 |
|
19 | | -class QfcBaseCommand: |
20 | | - def __init__(self) -> None: |
21 | | - self.name = Path(getfile(self.__class__)).stem |
| 17 | +class QfcBaseCommandRegistry(type): |
| 18 | + registry = {} |
| 19 | + |
| 20 | + def __new__(mcs, name, bases, attrs): |
| 21 | + cls = super().__new__(mcs, name, bases, attrs) |
| 22 | + |
| 23 | + if name == "QfcBaseCommand": |
| 24 | + return cls |
| 25 | + |
| 26 | + module_path = attrs.get("__module__") |
| 27 | + |
| 28 | + if module_path: |
| 29 | + command_name = module_path.split(".")[-1] |
| 30 | + |
| 31 | + if command_name in mcs.registry: |
| 32 | + raise Exception( |
| 33 | + f"Only one command definition allowed per file. Check the definition of {cls.__name__}." |
| 34 | + ) |
22 | 35 |
|
23 | | - if self.name in registry: |
24 | | - raise Exception( |
25 | | - f"Only one command allowed per file. Check the definition of {self.__class__.__name__}" |
26 | | - ) |
| 36 | + setattr(cls, "command_name", command_name) |
27 | 37 |
|
| 38 | + mcs.registry[command_name] = cls |
| 39 | + |
| 40 | + return cls |
| 41 | + |
| 42 | + |
| 43 | +class QfcBaseCommand(metaclass=QfcBaseCommandRegistry): |
| 44 | + command_name: str |
| 45 | + """Command name, derived from the module (file) name and used to call the command from CLI""" |
| 46 | + |
| 47 | + command_help: str = "" |
| 48 | + """Help text for the command, shown in CLI help""" |
| 49 | + |
| 50 | + def __init__(self) -> None: |
28 | 51 | self.parser = self.create_parser() |
29 | 52 |
|
30 | 53 | def create_parser(self) -> argparse.ArgumentParser: |
31 | | - parser = subparsers.add_parser(self.name, help=self.name) |
| 54 | + parser = subparsers.add_parser(self.command_name, help=self.command_help) |
32 | 55 | parser.set_defaults(func=self.handle) |
33 | 56 |
|
34 | 57 | self.add_arguments(parser) |
|
0 commit comments