diff options
Diffstat (limited to 'tools/cru-py/cru')
| -rw-r--r-- | tools/cru-py/cru/_iter.py | 4 | ||||
| -rw-r--r-- | tools/cru-py/cru/app.py | 4 | ||||
| -rw-r--r-- | tools/cru-py/cru/service/_base.py | 58 | ||||
| -rw-r--r-- | tools/cru-py/cru/service/_template.py | 29 | ||||
| -rw-r--r-- | tools/cru-py/cru/template.py | 4 | 
5 files changed, 82 insertions, 17 deletions
diff --git a/tools/cru-py/cru/_iter.py b/tools/cru-py/cru/_iter.py index 12d1d1f..5d3766a 100644 --- a/tools/cru-py/cru/_iter.py +++ b/tools/cru-py/cru/_iter.py @@ -415,8 +415,8 @@ class CruIterator(Generic[_T]):          return self.first_n(1).single_or(fallback)      @_wrap -    def flatten(self) -> Iterable[_T | Iterable[_T]]: -        return _Generic.iterable_flatten(self) +    def flatten(self, max_depth: int = -1) -> Iterable[Any]: +        return _Generic.iterable_flatten(self, max_depth)      def select_by_indices(self, indices: Iterable[int]) -> CruIterator[_T]:          index_set = set(indices) diff --git a/tools/cru-py/cru/app.py b/tools/cru-py/cru/app.py index c9e57f4..d45fd30 100644 --- a/tools/cru-py/cru/app.py +++ b/tools/cru-py/cru/app.py @@ -40,6 +40,10 @@ class ApplicationPath:          return self._full_path      @property +    def full_path_str(self) -> str: +        return str(self._full_path) + +    @property      def is_dir(self) -> bool:          return self._is_dir diff --git a/tools/cru-py/cru/service/_base.py b/tools/cru-py/cru/service/_base.py index 707fb66..7bb09ad 100644 --- a/tools/cru-py/cru/service/_base.py +++ b/tools/cru-py/cru/service/_base.py @@ -1,23 +1,73 @@ +from __future__ import annotations +  from argparse import ArgumentParser, Namespace -from typing import Protocol +from abc import ABC, abstractmethod +from collections.abc import Iterable + +from cru import CruIterator, CruInternalError  from cru.app import ApplicationPath, CruApplication -class AppFunction(Protocol): +class AppFeatureProvider(ABC): +    def __init__(self, name: str, /, app: AppBase | None = None): +        super().__init__() +        self._name = name +        self._app = app if app else AppBase.get_instance() +        self._app_paths: list[ApplicationPath] = [] +        self.app.add_app_feature(self) + +    @property +    def app(self) -> AppBase: +        return self._app + +    @property +    def name(self) -> str: +        return self._name +      @property -    def name(self) -> str: ... +    def app_paths(self) -> list[ApplicationPath]: +        return self._app_paths + +    def add_app_path(self, subpath: str, is_dir: bool) -> ApplicationPath: +        p = ApplicationPath(self.app.app_dir, subpath, is_dir) +        self._app_paths.append(p) +        return p +    @abstractmethod      def add_arg_parser(self, arg_parser: ArgumentParser) -> None: ... +    @abstractmethod      def run_command(self, args: Namespace) -> None: ...  class AppBase(CruApplication): +    _instance: AppBase | None = None + +    @staticmethod +    def get_instance() -> AppBase: +        if AppBase._instance is None: +            raise CruInternalError("App instance not initialized") +        return AppBase._instance +      def __init__(self, name: str, app_dir: str):          super().__init__(name) +        AppBase._instance = self          self._app_dir = app_dir -        self._template_dir = ApplicationPath(app_dir, "templates", True) +        self._app_features: list[AppFeatureProvider] = []      @property      def app_dir(self) -> str:          return self._app_dir + +    @property +    def app_features(self) -> list[AppFeatureProvider]: +        return self._app_features + +    @property +    def app_paths(self) -> Iterable[ApplicationPath]: +        return ( +            CruIterator(self._app_features).transform(lambda x: x.app_paths).flatten(1) +        ) + +    def add_app_feature(self, feature: AppFeatureProvider) -> None: +        self._app_features.append(feature) diff --git a/tools/cru-py/cru/service/_template.py b/tools/cru-py/cru/service/_template.py index 0ca4b63..5da00ba 100644 --- a/tools/cru-py/cru/service/_template.py +++ b/tools/cru-py/cru/service/_template.py @@ -1,20 +1,31 @@  from argparse import ArgumentParser, Namespace -from ._base import AppBase, AppFunction +from ._base import AppFeatureProvider +from cru.app import ApplicationPath +from cru.template import TemplateTree -class TemplateManager(AppFunction): -    def __init__(self, app: AppBase): -        self._app = app -        pass + +class TemplateManager(AppFeatureProvider): +    def __init__(self, prefix: str = "CRUPEST"): +        super().__init__("template-manager") +        self._templates_dir = self.add_app_path("templates", True) +        self._generated_dir = self.add_app_path("generated", True) +        self._template_tree = TemplateTree( +            prefix, self._templates_dir.full_path_str, self._generated_dir.full_path_str +        ) + +    @property +    def templates_dir(self) -> ApplicationPath: +        return self._templates_dir      @property -    def name(self): -        return "template-manager" +    def generated_dir(self) -> ApplicationPath: +        return self._generated_dir      def add_arg_parser(self, arg_parser: ArgumentParser) -> None:          subparsers = arg_parser.add_subparsers(dest="template_command") -        list_parser = subparsers.add_parser("list", help="List templates") -        generate_parser = subparsers.add_parser("generate", help="Generate template") +        list_parser = subparsers.add_parser("list", help="List templates.") +        generate_parser = subparsers.add_parser("generate", help="Generate template.")      def run_command(self, args: Namespace) -> None: ... diff --git a/tools/cru-py/cru/template.py b/tools/cru-py/cru/template.py index 2161804..ccb3ad8 100644 --- a/tools/cru-py/cru/template.py +++ b/tools/cru-py/cru/template.py @@ -79,14 +79,14 @@ class TemplateTree:          prefix: str,          source: str,          destination: str, -        exclude: Iterable[str], +        exclude: Iterable[str] | None = None,          template_file_suffix: str = ".template",      ):          self._prefix = prefix          self._files: list[CruTemplateFile] | None = None          self._source = source          self._destination = destination -        self._exclude = [os.path.normpath(p) for p in exclude] +        self._exclude = [os.path.normpath(p) for p in exclude or []]          self._template_file_suffix = template_file_suffix      @property  | 
