diff options
Diffstat (limited to 'tools/cru-py/cru/service/_base.py')
-rw-r--r-- | tools/cru-py/cru/service/_base.py | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/tools/cru-py/cru/service/_base.py b/tools/cru-py/cru/service/_base.py index 98eed89..3b511a1 100644 --- a/tools/cru-py/cru/service/_base.py +++ b/tools/cru-py/cru/service/_base.py @@ -2,6 +2,8 @@ from __future__ import annotations from argparse import ArgumentParser, Namespace from abc import ABC, abstractmethod +import argparse +from collections.abc import Sequence import os from pathlib import Path from typing import TypeVar, overload @@ -12,6 +14,7 @@ _F = TypeVar("_F") OWNER_NAME = "crupest" + class InternalAppException(CruInternalError): pass @@ -153,7 +156,7 @@ class AppRootPath(AppPath): return self._app -class AppFeatureProvider: +class AppFeatureProvider(ABC): def __init__(self, name: str, /, app: AppBase | None = None): super().__init__() self._name = name @@ -168,15 +171,56 @@ class AppFeatureProvider: def name(self) -> str: return self._name + @abstractmethod + def setup(self) -> None: ... + + +class AppCommandFeatureProvider(AppFeatureProvider): + @abstractmethod + def get_command_info(self) -> tuple[str, str]: ... -class AppCommandFeatureProvider(AppFeatureProvider, ABC): @abstractmethod - def add_arg_parser(self, arg_parser: ArgumentParser) -> None: ... + def setup_arg_parser(self, arg_parser: ArgumentParser): ... @abstractmethod def run_command(self, args: Namespace) -> None: ... +DATA_DIR_NAME = "data" + + +class CommandDispatcher(AppFeatureProvider): + def __init__(self) -> None: + super().__init__("command-dispatcher") + + def _setup_arg_parser(self) -> None: + self._map: dict[str, AppCommandFeatureProvider] = {} + arg_parser = argparse.ArgumentParser(description="Service management") + subparsers = arg_parser.add_subparsers(dest="command") + for feature in self.app.features: + if isinstance(feature, AppCommandFeatureProvider): + info = feature.get_command_info() + command_subparser = subparsers.add_parser(info[0], help=info[1]) + feature.setup_arg_parser(command_subparser) + self._map[info[0]] = feature + self._arg_parser = arg_parser + + def setup(self): + self._setup_arg_parser() + + @property + def arg_parser(self) -> argparse.ArgumentParser: + return self._arg_parser + + @property + def map(self) -> dict[str, AppCommandFeatureProvider]: + return self._map + + def run_command(self, _args: Sequence[str] | None = None) -> None: + args = self.arg_parser.parse_args(_args) + self.map[args.command].run_command(args) + + class AppBase: _instance: AppBase | None = None |