aboutsummaryrefslogtreecommitdiff
path: root/tools/cru-py/cru/service/_base.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/cru-py/cru/service/_base.py')
-rw-r--r--tools/cru-py/cru/service/_base.py50
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