diff --git a/src/cpl_cli/.cpl/__init__.py b/src/cpl_cli/.cpl/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/cpl_cli/.cpl/abc_schematic.py b/src/cpl_cli/.cpl/abc_schematic.py new file mode 100644 index 00000000..917a60a6 --- /dev/null +++ b/src/cpl_cli/.cpl/abc_schematic.py @@ -0,0 +1,30 @@ +import textwrap + +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC + + +class ABC(GenerateSchematicABC): + + def __init__(self, *args): + GenerateSchematicABC.__init__(self, *args) + + def get_code(self) -> str: + code = """\ + from abc import ABC, abstractmethod + + + class $Name(ABC): + + @abstractmethod + def __init__(self): pass + """ + x = self.build_code_str(code, Name=self._class_name) + return x + + @classmethod + def register(cls): + GenerateSchematicABC.register( + cls, + 'abc', + ['a', 'A'] + ) diff --git a/src/cpl_cli/.cpl/class_schematic.py b/src/cpl_cli/.cpl/class_schematic.py new file mode 100644 index 00000000..f5cdb462 --- /dev/null +++ b/src/cpl_cli/.cpl/class_schematic.py @@ -0,0 +1,28 @@ +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC +from cpl_core.utils import String + + +class Class(GenerateSchematicABC): + + def __init__(self, name: str, path: str, schematic: str): + GenerateSchematicABC.__init__(self, name, path, schematic) + self._name = f'{String.convert_to_snake_case(name)}.py' + self._class_name = f'{String.first_to_upper(name)}' + + def get_code(self) -> str: + code = """\ + class $Name: + + def __init__(self): + pass + """ + x = self.build_code_str(code, Name=self._class_name) + return x + + @classmethod + def register(cls): + GenerateSchematicABC.register( + cls, + 'class', + ['c', 'C'] + ) diff --git a/src/cpl_cli/.cpl/configmodel_schematic.py b/src/cpl_cli/.cpl/configmodel_schematic.py new file mode 100644 index 00000000..e692f1e1 --- /dev/null +++ b/src/cpl_cli/.cpl/configmodel_schematic.py @@ -0,0 +1,46 @@ +import textwrap + +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC + + +class ConfigModel(GenerateSchematicABC): + + def __init__(self, *args: str): + GenerateSchematicABC.__init__(self, *args) + + def get_code(self) -> str: + code = """\ + import traceback + + from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC + from cpl_core.console import Console + + + class $Name(ConfigurationModelABC): + + def __init__(self): + ConfigurationModelABC.__init__(self) + + self._atr = '' + + @property + def atr(self) -> str: + return self._atr + + def from_dict(self, settings: dict): + try: + self._atr = settings['atr'] + except Exception as e: + Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') + Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + """ + x = self.build_code_str(code, Name=self._class_name) + return x + + @classmethod + def register(cls): + GenerateSchematicABC.register( + cls, + 'settings', + ['st', 'ST'] + ) diff --git a/src/cpl_cli/.cpl/enum_schematic.py b/src/cpl_cli/.cpl/enum_schematic.py new file mode 100644 index 00000000..bd838159 --- /dev/null +++ b/src/cpl_cli/.cpl/enum_schematic.py @@ -0,0 +1,29 @@ +import textwrap + +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC + + +class Enum(GenerateSchematicABC): + + def __init__(self, *args: str): + GenerateSchematicABC.__init__(self, *args) + + def get_code(self) -> str: + code = """\ + from enum import Enum + + + class $Name(Enum): + + atr = 0 + """ + x = self.build_code_str(code, Name=self._class_name) + return x + + @classmethod + def register(cls): + GenerateSchematicABC.register( + cls, + 'enum', + ['e', 'E'] + ) diff --git a/src/cpl_cli/.cpl/init_schematic.py b/src/cpl_cli/.cpl/init_schematic.py new file mode 100644 index 00000000..f089ac18 --- /dev/null +++ b/src/cpl_cli/.cpl/init_schematic.py @@ -0,0 +1,25 @@ +import textwrap + +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC + + +class Init(GenerateSchematicABC): + + def __init__(self, *args: str): + GenerateSchematicABC.__init__(self, *args) + self._name = f'__init__.py' + + def get_code(self) -> str: + code = """\ + # imports + """ + x = self.build_code_str(code, Name=self._class_name) + return x + + @classmethod + def register(cls): + GenerateSchematicABC.register( + cls, + 'init', + [] + ) diff --git a/src/cpl_cli/.cpl/pipe_schematic.py b/src/cpl_cli/.cpl/pipe_schematic.py new file mode 100644 index 00000000..fe7ab972 --- /dev/null +++ b/src/cpl_cli/.cpl/pipe_schematic.py @@ -0,0 +1,32 @@ +import textwrap + +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC + + +class Pipe(GenerateSchematicABC): + + def __init__(self, *args: str): + GenerateSchematicABC.__init__(self, *args) + + def get_code(self) -> str: + code = """\ + from cpl_core.pipes.pipe_abc import PipeABC + + + class $Name(PipeABC): + + def __init__(self): pass + + def transform(self, value: any, *args): + return value + """ + x = self.build_code_str(code, Name=self._class_name) + return x + + @classmethod + def register(cls): + GenerateSchematicABC.register( + cls, + 'pipe', + ['p', 'P'] + ) diff --git a/src/cpl_cli/.cpl/service_schematic.py b/src/cpl_cli/.cpl/service_schematic.py new file mode 100644 index 00000000..9651f7de --- /dev/null +++ b/src/cpl_cli/.cpl/service_schematic.py @@ -0,0 +1,27 @@ +import textwrap + +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC + + +class Service(GenerateSchematicABC): + + def __init__(self, *args: str): + GenerateSchematicABC.__init__(self, *args) + + def get_code(self) -> str: + code = """\ + class $Name: + + def __init__(self): + pass + """ + x = self.build_code_str(code, Name=self._class_name) + return x + + @classmethod + def register(cls): + GenerateSchematicABC.register( + cls, + 'service', + ['s', 'S'] + ) diff --git a/src/cpl_cli/.cpl/test_case_schematic.py b/src/cpl_cli/.cpl/test_case_schematic.py new file mode 100644 index 00000000..63ffe56c --- /dev/null +++ b/src/cpl_cli/.cpl/test_case_schematic.py @@ -0,0 +1,33 @@ +import textwrap + +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC + + +class TestCase(GenerateSchematicABC): + + def __init__(self, *args: str): + GenerateSchematicABC.__init__(self, *args) + + def get_code(self) -> str: + code = """\ + import unittest + + + class $Name(unittest.TestCase): + + def setUp(self): + pass + + def test_equal(self): + pass + """ + x = self.build_code_str(code, Name=self._class_name) + return x + + @classmethod + def register(cls): + GenerateSchematicABC.register( + cls, + 'test-case', + ['tc', 'TC'] + ) diff --git a/src/cpl_cli/.cpl/thread_schematic.py b/src/cpl_cli/.cpl/thread_schematic.py new file mode 100644 index 00000000..4bb19e98 --- /dev/null +++ b/src/cpl_cli/.cpl/thread_schematic.py @@ -0,0 +1,33 @@ +import textwrap + +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC + + +class Thread(GenerateSchematicABC): + + def __init__(self, *args: str): + GenerateSchematicABC.__init__(self, *args) + + def get_code(self) -> str: + code = """\ + import threading + + + class $Name(threading.Thread): + + def __init__(self): + threading.Thread.__init__(self) + + def run(self) -> None: + pass + """ + x = self.build_code_str(code, Name=self._class_name) + return x + + @classmethod + def register(cls): + GenerateSchematicABC.register( + cls, + 'thread', + ['t', 'T'] + ) diff --git a/src/cpl_cli/.cpl/validator_schematic.py b/src/cpl_cli/.cpl/validator_schematic.py new file mode 100644 index 00000000..a7a17cb1 --- /dev/null +++ b/src/cpl_cli/.cpl/validator_schematic.py @@ -0,0 +1,33 @@ +import textwrap + +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC + + +class Validator(GenerateSchematicABC): + + def __init__(self, *args: str): + GenerateSchematicABC.__init__(self, *args) + + def get_code(self) -> str: + code = """\ + from cpl_core.configuration.validator_abc import ValidatorABC + + + class $Name(ValidatorABC): + + def __init__(self): + ValidatorABC.__init__(self) + + def validate(self) -> bool: + return True + """ + x = self.build_code_str(code, Name=self._class_name) + return x + + @classmethod + def register(cls): + GenerateSchematicABC.register( + cls, + 'validator', + ['v', 'V'] + ) diff --git a/src/cpl_cli/_templates/generate/__init__.py b/src/cpl_cli/_templates/generate/__init__.py deleted file mode 100644 index 07d118a6..00000000 --- a/src/cpl_cli/_templates/generate/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -cpl-cli sh-edraft Common Python library CLI -~~~~~~~~~~~~~~~~~~~ - -sh-edraft Common Python library Command Line Interface - -:copyright: (c) 2020 - 2022 sh-edraft.de -:license: MIT, see LICENSE for more details. - -""" - -__title__ = 'cpl_cli._templates.generate' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.12.0' - -from collections import namedtuple - - -# imports: - -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='12', micro='0') diff --git a/src/cpl_cli/_templates/generate/abc_template.py b/src/cpl_cli/_templates/generate/abc_template.py deleted file mode 100644 index 3e292182..00000000 --- a/src/cpl_cli/_templates/generate/abc_template.py +++ /dev/null @@ -1,44 +0,0 @@ -import textwrap -from string import Template - -from cpl_core.utils.string import String -from cpl_cli._templates.template_file_abc import TemplateFileABC - - -class ABCTemplate(TemplateFileABC): - - def __init__(self, name: str, schematic: str, schematic_upper: str, path: str): - TemplateFileABC.__init__(self) - - self._name = f'{String.convert_to_snake_case(name)}_{schematic}.py' - if schematic in name.lower(): - self._name = f'{String.convert_to_snake_case(name)}.py' - - self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' - if schematic in name.lower(): - self._class_name = f'{String.first_to_upper(name)}' - - self._path = path - self._value = textwrap.dedent("""\ - from abc import ABC, abstractmethod - - - class $Name(ABC): - - @abstractmethod - def __init__(self): pass - """) - - @property - def name(self) -> str: - return self._name - - @property - def path(self) -> str: - return self._path - - @property - def value(self) -> str: - return Template(self._value).substitute( - Name=self._class_name - ) diff --git a/src/cpl_cli/_templates/generate/class_template.py b/src/cpl_cli/_templates/generate/class_template.py deleted file mode 100644 index 6d01d659..00000000 --- a/src/cpl_cli/_templates/generate/class_template.py +++ /dev/null @@ -1,35 +0,0 @@ -import textwrap -from string import Template - -from cpl_core.utils.string import String -from cpl_cli._templates.template_file_abc import TemplateFileABC - - -class ClassTemplate(TemplateFileABC): - - def __init__(self, name: str, schematic: str, schematic_upper: str, path: str): - TemplateFileABC.__init__(self) - - self._name = f'{String.convert_to_snake_case(name)}.py' - self._class_name = f'{String.first_to_upper(name)}' - self._path = path - self._value = textwrap.dedent("""\ - class $Name: - - def __init__(self): - pass - """) - - @property - def name(self) -> str: - return self._name - - @property - def path(self) -> str: - return self._path - - @property - def value(self) -> str: - return Template(self._value).substitute( - Name=self._class_name - ) diff --git a/src/cpl_cli/_templates/generate/configmodel_template.py b/src/cpl_cli/_templates/generate/configmodel_template.py deleted file mode 100644 index f4b9ce41..00000000 --- a/src/cpl_cli/_templates/generate/configmodel_template.py +++ /dev/null @@ -1,60 +0,0 @@ -import textwrap -from string import Template - -from cpl_core.utils.string import String -from cpl_cli._templates.template_file_abc import TemplateFileABC - - -class ConfigModelTemplate(TemplateFileABC): - - def __init__(self, name: str, schematic: str, schematic_upper: str, path: str): - TemplateFileABC.__init__(self) - - self._name = f'{String.convert_to_snake_case(name)}_{schematic}.py' - if schematic in name.lower(): - self._name = f'{String.convert_to_snake_case(name)}.py' - - self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' - if schematic in name.lower(): - self._class_name = f'{String.first_to_upper(name)}' - - self._path = path - self._value = textwrap.dedent("""\ - import traceback - - from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC - from cpl_core.console import Console - - - class $Name(ConfigurationModelABC): - - def __init__(self): - ConfigurationModelABC.__init__(self) - - self._atr = '' - - @property - def atr(self) -> str: - return self._atr - - def from_dict(self, settings: dict): - try: - self._atr = settings['atr'] - except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') - """) - - @property - def name(self) -> str: - return self._name - - @property - def path(self) -> str: - return self._path - - @property - def value(self) -> str: - return Template(self._value).substitute( - Name=self._class_name - ) diff --git a/src/cpl_cli/_templates/generate/enum_template.py b/src/cpl_cli/_templates/generate/enum_template.py deleted file mode 100644 index b8c04b49..00000000 --- a/src/cpl_cli/_templates/generate/enum_template.py +++ /dev/null @@ -1,43 +0,0 @@ -import textwrap -from string import Template - -from cpl_core.utils.string import String -from cpl_cli._templates.template_file_abc import TemplateFileABC - - -class EnumTemplate(TemplateFileABC): - - def __init__(self, name: str, schematic: str, schematic_upper: str, path: str): - TemplateFileABC.__init__(self) - - self._name = f'{String.convert_to_snake_case(name)}_{schematic}.py' - if schematic in name.lower(): - self._name = f'{String.convert_to_snake_case(name)}.py' - - self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' - if schematic in name.lower(): - self._class_name = f'{String.first_to_upper(name)}' - - self._path = path - self._value = textwrap.dedent("""\ - from enum import Enum - - - class $Name(Enum): - - atr = 0 - """) - - @property - def name(self) -> str: - return self._name - - @property - def path(self) -> str: - return self._path - - @property - def value(self) -> str: - return Template(self._value).substitute( - Name=self._class_name - ) diff --git a/src/cpl_cli/_templates/generate/init_template.py b/src/cpl_cli/_templates/generate/init_template.py deleted file mode 100644 index 48c2e2da..00000000 --- a/src/cpl_cli/_templates/generate/init_template.py +++ /dev/null @@ -1,35 +0,0 @@ -import textwrap -from string import Template - -from cpl_core.utils.string import String -from cpl_cli._templates.template_file_abc import TemplateFileABC - - -class InitTemplate(TemplateFileABC): - - def __init__(self, name: str, schematic: str, schematic_upper: str, path: str): - TemplateFileABC.__init__(self) - - self._name = f'__init__.py' - self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' - if schematic in name.lower(): - self._class_name = f'{String.first_to_upper(name)}' - - self._path = path - self._value = textwrap.dedent("""\ - # imports - """) - - @property - def name(self) -> str: - return self._name - - @property - def path(self) -> str: - return self._path - - @property - def value(self) -> str: - return Template(self._value).substitute( - Name=self._class_name - ) diff --git a/src/cpl_cli/_templates/generate/pipe_template.py b/src/cpl_cli/_templates/generate/pipe_template.py deleted file mode 100644 index 6a33035b..00000000 --- a/src/cpl_cli/_templates/generate/pipe_template.py +++ /dev/null @@ -1,46 +0,0 @@ -import textwrap -from string import Template - -from cpl_core.utils.string import String -from cpl_cli._templates.template_file_abc import TemplateFileABC - - -class PipeTemplate(TemplateFileABC): - - def __init__(self, name: str, schematic: str, schematic_upper: str, path: str): - TemplateFileABC.__init__(self) - - self._name = f'{String.convert_to_snake_case(name)}_{schematic}.py' - if schematic in name.lower(): - self._name = f'{String.convert_to_snake_case(name)}.py' - - self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' - if schematic in name.lower(): - self._class_name = f'{String.first_to_upper(name)}' - - self._path = path - self._value = textwrap.dedent("""\ - from cpl_core.pipes.pipe_abc import PipeABC - - - class $Name(PipeABC): - - def __init__(self): pass - - def transform(self, value: any, *args): - return value - """) - - @property - def name(self) -> str: - return self._name - - @property - def path(self) -> str: - return self._path - - @property - def value(self) -> str: - return Template(self._value).substitute( - Name=self._class_name - ) diff --git a/src/cpl_cli/_templates/generate/service_template.py b/src/cpl_cli/_templates/generate/service_template.py deleted file mode 100644 index 24846155..00000000 --- a/src/cpl_cli/_templates/generate/service_template.py +++ /dev/null @@ -1,41 +0,0 @@ -import textwrap -from string import Template - -from cpl_core.utils.string import String -from cpl_cli._templates.template_file_abc import TemplateFileABC - - -class ServiceTemplate(TemplateFileABC): - - def __init__(self, name: str, schematic: str, schematic_upper: str, path: str): - TemplateFileABC.__init__(self) - - self._name = f'{String.convert_to_snake_case(name)}_{schematic}.py' - if schematic in name.lower(): - self._name = f'{String.convert_to_snake_case(name)}.py' - - self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' - if schematic in name.lower(): - self._class_name = f'{String.first_to_upper(name)}' - - self._path = path - self._value = textwrap.dedent("""\ - class $Name: - - def __init__(self): - pass - """) - - @property - def name(self) -> str: - return self._name - - @property - def path(self) -> str: - return self._path - - @property - def value(self) -> str: - return Template(self._value).substitute( - Name=self._class_name - ) diff --git a/src/cpl_cli/_templates/generate/test_case_template.py b/src/cpl_cli/_templates/generate/test_case_template.py deleted file mode 100644 index 5888bb5c..00000000 --- a/src/cpl_cli/_templates/generate/test_case_template.py +++ /dev/null @@ -1,47 +0,0 @@ -import textwrap -from string import Template - -from cpl_core.utils.string import String -from cpl_cli._templates.template_file_abc import TemplateFileABC - - -class TestCaseTemplate(TemplateFileABC): - - def __init__(self, name: str, schematic: str, schematic_upper: str, path: str): - TemplateFileABC.__init__(self) - - self._name = f'{String.convert_to_snake_case(name)}_{schematic}.py' - if schematic in name.lower(): - self._name = f'{String.convert_to_snake_case(name)}.py' - - self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' - if schematic in name.lower(): - self._class_name = f'{String.first_to_upper(name)}' - - self._path = path - self._value = textwrap.dedent("""\ - import unittest - - - class $Name(unittest.TestCase): - - def setUp(self): - pass - - def test_equal(self): - pass - """) - - @property - def name(self) -> str: - return self._name - - @property - def path(self) -> str: - return self._path - - @property - def value(self) -> str: - return Template(self._value).substitute( - Name=self._class_name - ) diff --git a/src/cpl_cli/_templates/generate/thread_template.py b/src/cpl_cli/_templates/generate/thread_template.py deleted file mode 100644 index 4609d678..00000000 --- a/src/cpl_cli/_templates/generate/thread_template.py +++ /dev/null @@ -1,47 +0,0 @@ -import textwrap -from string import Template - -from cpl_core.utils.string import String -from cpl_cli._templates.template_file_abc import TemplateFileABC - - -class ThreadTemplate(TemplateFileABC): - - def __init__(self, name: str, schematic: str, schematic_upper: str, path: str): - TemplateFileABC.__init__(self) - - self._name = f'{String.convert_to_snake_case(name)}_{schematic}.py' - if schematic in name.lower(): - self._name = f'{String.convert_to_snake_case(name)}.py' - - self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' - if schematic in name.lower(): - self._class_name = f'{String.first_to_upper(name)}' - - self._path = path - self._value = textwrap.dedent("""\ - import threading - - - class $Name(threading.Thread): - - def __init__(self): - threading.Thread.__init__(self) - - def run(self) -> None: - pass - """) - - @property - def name(self) -> str: - return self._name - - @property - def path(self) -> str: - return self._path - - @property - def value(self) -> str: - return Template(self._value).substitute( - Name=self._class_name - ) diff --git a/src/cpl_cli/_templates/generate/validator_template.py b/src/cpl_cli/_templates/generate/validator_template.py deleted file mode 100644 index 683cea5e..00000000 --- a/src/cpl_cli/_templates/generate/validator_template.py +++ /dev/null @@ -1,47 +0,0 @@ -import textwrap -from string import Template - -from cpl_core.utils.string import String -from cpl_cli._templates.template_file_abc import TemplateFileABC - - -class ValidatorTemplate(TemplateFileABC): - - def __init__(self, name: str, schematic: str, schematic_upper: str, path: str): - TemplateFileABC.__init__(self) - - self._name = f'{String.convert_to_snake_case(name)}_{schematic}.py' - if schematic in name.lower(): - self._name = f'{String.convert_to_snake_case(name)}.py' - - self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' - if schematic in name.lower(): - self._class_name = f'{String.first_to_upper(name)}' - - self._path = path - self._value = textwrap.dedent("""\ - from cpl_core.configuration.validator_abc import ValidatorABC - - - class $Name(ValidatorABC): - - def __init__(self): - ValidatorABC.__init__(self) - - def validate(self) -> bool: - return True - """) - - @property - def name(self) -> str: - return self._name - - @property - def path(self) -> str: - return self._path - - @property - def value(self) -> str: - return Template(self._value).substitute( - Name=self._class_name - ) diff --git a/src/cpl_cli/abc/__init__.py b/src/cpl_cli/abc/__init__.py new file mode 100644 index 00000000..425ab6c1 --- /dev/null +++ b/src/cpl_cli/abc/__init__.py @@ -0,0 +1 @@ +# imports diff --git a/src/cpl_cli/abc/file_template_abc.py b/src/cpl_cli/abc/file_template_abc.py new file mode 100644 index 00000000..09e39f23 --- /dev/null +++ b/src/cpl_cli/abc/file_template_abc.py @@ -0,0 +1,28 @@ +from abc import ABC, abstractmethod + +from cpl_core.utils import String + + +class FileTemplateABC(ABC): + + @abstractmethod + def __init__(self, name: str, path: str, code: str): + self._name = f'{String.convert_to_snake_case(name)}.py' + self._path = path + self._code = code + + @property + def name(self) -> str: + return self._name + + @property + def path(self) -> str: + return self._path + + @property + def value(self) -> str: + return self.get_code() + + @abstractmethod + def get_code(self) -> str: + return self._code diff --git a/src/cpl_cli/abc/generate_schematic_abc.py b/src/cpl_cli/abc/generate_schematic_abc.py new file mode 100644 index 00000000..7254e176 --- /dev/null +++ b/src/cpl_cli/abc/generate_schematic_abc.py @@ -0,0 +1,37 @@ +import textwrap +from abc import abstractmethod +from string import Template + +from cpl_cli.abc.file_template_abc import FileTemplateABC +from cpl_cli.configuration.schematic_collection import SchematicCollection +from cpl_core.utils import String + + +class GenerateSchematicABC(FileTemplateABC): + + def __init__(self, name: str, schematic: str, path: str): + FileTemplateABC.__init__(self, name, path, '') + self._name = f'{String.convert_to_snake_case(name)}_{schematic}.py' + if schematic in name.lower(): + self._name = f'{String.convert_to_snake_case(name)}.py' + + self._class_name = f'{String.first_to_upper(name)}{String.first_to_upper(schematic)}' + if schematic in name.lower(): + self._class_name = f'{String.first_to_upper(name)}' + + @property + def class_name(self) -> str: + return self._class_name + + @abstractmethod + def get_code(self) -> str: pass + + @classmethod + def build_code_str(cls, code: str, **kwargs) -> str: + text = textwrap.dedent(code) + return Template(text).substitute(**kwargs) + + @classmethod + @abstractmethod + def register(cls, *args): + SchematicCollection.register(*args) diff --git a/src/cpl_cli/command/generate_service.py b/src/cpl_cli/command/generate_service.py index 12236c83..975770d7 100644 --- a/src/cpl_cli/command/generate_service.py +++ b/src/cpl_cli/command/generate_service.py @@ -2,19 +2,10 @@ import os import sys import textwrap -from cpl_cli._templates.generate.abc_template import ABCTemplate -from cpl_cli._templates.generate.class_template import ClassTemplate -from cpl_cli._templates.generate.configmodel_template import ConfigModelTemplate -from cpl_cli._templates.generate.enum_template import EnumTemplate -from cpl_cli._templates.generate.init_template import InitTemplate -from cpl_cli._templates.generate.pipe_template import PipeTemplate -from cpl_cli._templates.generate.service_template import ServiceTemplate -from cpl_cli._templates.generate.test_case_template import TestCaseTemplate -from cpl_cli._templates.generate.thread_template import ThreadTemplate -from cpl_cli._templates.generate.validator_template import ValidatorTemplate -from cpl_cli._templates.template_file_abc import TemplateFileABC +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC from cpl_cli.command_abc import CommandABC from cpl_cli.configuration import WorkspaceSettings +from cpl_cli.configuration.schematic_collection import SchematicCollection from cpl_core.configuration.configuration_abc import ConfigurationABC from cpl_core.console.console import Console from cpl_core.console.foreground_color_enum import ForegroundColorEnum @@ -37,51 +28,28 @@ class GenerateService(CommandABC): self._config = configuration self._workspace = workspace - self._schematics = { - "abc": { - "Upper": "ABC", - "Template": ABCTemplate - }, - "class": { - "Upper": "Class", - "Template": ClassTemplate - }, - "enum": { - "Upper": "Enum", - "Template": EnumTemplate - }, - "pipe": { - "Upper": "Pipe", - "Template": PipeTemplate - }, - "service": { - "Upper": "Service", - "Template": ServiceTemplate - }, - "settings": { - "Upper": "Settings", - "Template": ConfigModelTemplate - }, - "test_case": { - "Upper": "TestCase", - "Template": TestCaseTemplate - }, - "thread": { - "Upper": "Thread", - "Template": ThreadTemplate - }, - "validator": { - "Upper": "Validator", - "Template": ValidatorTemplate - } - } - self._config = configuration self._env = self._config.environment + self._schematics = {} + + self._read_custom_schematics_from_path(self._env.runtime_directory) + self._read_custom_schematics_from_path(self._env.working_directory) + for schematic in GenerateSchematicABC.__subclasses__(): + schematic.register() + + self._schematics = SchematicCollection.get_schematics() @property def help_message(self) -> str: - return textwrap.dedent("""\ + schematics = [] + for schematic in self._schematics: + aliases = '|'.join(self._schematics[schematic]['Aliases']) + schematic_str = schematic + if len(aliases) > 0: + schematic_str = f'{schematic} ({aliases})' + + schematics.append(schematic_str) + help_msg = textwrap.dedent("""\ Generate a file based on schematic. Usage: cpl generate @@ -89,41 +57,11 @@ class GenerateService(CommandABC): schematic: The schematic to generate. name: The name of the generated file - Schematics: - abc - class - enum - pipe - service - settings - test_case - thread - validator - """) + Schematics:""") - @staticmethod - def _help(message: str): - """ - Internal help output - :param message: - :return: - """ - Console.error(message) - - schematics = [ - 'abc (a|A)', - 'class (c|C)', - 'enum (e|E)', - 'pipe (p|P)', - 'service (s|S)', - 'settings (st|ST)', - 'test-case (tc|TC)', - 'thread (t|T)', - 'validator (v|V)' - ] - Console.write_line('Available Schematics:') - for name in schematics: - Console.write(f'\n\t{name} ') + for schematic in schematics: + help_msg += f'\n {schematic}' + return help_msg @staticmethod def _create_file(file_path: str, value: str): @@ -137,7 +75,7 @@ class GenerateService(CommandABC): template.write(value) template.close() - def _create_init_files(self, file_path: str, template: TemplateFileABC, class_name: str, schematic: str, rel_path: str): + def _create_init_files(self, file_path: str, template: GenerateSchematicABC, class_name: str, schematic: str, rel_path: str): if not os.path.isdir(os.path.dirname(file_path)): os.makedirs(os.path.dirname(file_path)) directory = '' @@ -146,7 +84,7 @@ class GenerateService(CommandABC): if subdir == 'src': continue - file = InitTemplate(class_name, schematic, self._schematics[schematic]["Upper"], rel_path) + file = self._schematics['init']['Template'](class_name, 'init', rel_path) if os.path.exists(os.path.join(os.path.abspath(directory), file.name)): continue @@ -154,12 +92,12 @@ class GenerateService(CommandABC): f'Creating {os.path.abspath(directory)}/{file.name}', self._create_file, os.path.join(os.path.abspath(directory), file.name), - file.value, + file.get_code(), text_foreground_color=ForegroundColorEnum.green, spinner_foreground_color=ForegroundColorEnum.cyan ) - def _generate(self, schematic: str, name: str, template: TemplateFileABC): + def _generate(self, schematic: str, name: str, template: type): """ Generates files by given schematic, name and template :param schematic: @@ -175,9 +113,9 @@ class GenerateService(CommandABC): class_name = parts[len(parts) - 1] if self._workspace is not None and parts[0] in self._workspace.projects: - rel_path = os.path.dirname(self._workspace.projects[parts[0]]) + rel_path = os.path.join(os.path.dirname(self._workspace.projects[parts[0]]), *parts[1:-1]) - template = template(class_name, schematic, self._schematics[schematic]["Upper"], rel_path) + template = template(class_name, String.convert_to_snake_case(schematic), rel_path) file_path = os.path.join(self._env.working_directory, template.path, template.name) self._create_init_files(file_path, template, class_name, schematic, rel_path) @@ -194,11 +132,35 @@ class GenerateService(CommandABC): message, self._create_file, file_path, - template.value, + template.get_code(), text_foreground_color=ForegroundColorEnum.green, spinner_foreground_color=ForegroundColorEnum.cyan ) + @staticmethod + def _read_custom_schematics_from_path(path: str): + if not os.path.exists(os.path.join(path, '.cpl')): + return + + for r, d, f in os.walk(os.path.join(path, '.cpl')): + for file in f: + if not file.endswith('_schematic.py'): + continue + + code = '' + with open(os.path.join(r, file), 'r') as py_file: + code = py_file.read() + py_file.close() + + exec(code) + + def _get_schematic_by_alias(self, schematic: str) -> str: + for key in self._schematics: + if schematic in self._schematics[key]['Aliases']: + return key + + return schematic + def execute(self, args: list[str]): """ Entry point of command @@ -213,9 +175,15 @@ class GenerateService(CommandABC): schematic = s break + schematic_by_alias = self._get_schematic_by_alias(args[0]) + if schematic is None and len(args) >= 1 and (args[0] in self._schematics or schematic_by_alias != args[0]): + schematic = schematic_by_alias + self._config.add_configuration(schematic, args[1]) + value = args[1] + if schematic is None: - self._help('Usage: cpl generate [options]') - Console.write_line() + Console.error(f'Schematic not found') + Console.write_line(self.help_message) sys.exit() name = value diff --git a/src/cpl_cli/command/new_service.py b/src/cpl_cli/command/new_service.py index 9740a324..5715f5cd 100644 --- a/src/cpl_cli/command/new_service.py +++ b/src/cpl_cli/command/new_service.py @@ -67,29 +67,11 @@ class NewService(CommandABC): name Name of the workspace or the project Types: - console - library - unittest + console (c|C) + library (l|L) + unittest (ut|UT) """) - @staticmethod - def _help(message: str): - """ - Internal help output - :param message: - :return: - """ - Console.error(message) - - schematics = [ - 'console (c|C) ', - 'library (l|L) ', - 'unittest (ut|UT) ', - ] - Console.write_line('Available Schematics:') - for name in schematics: - Console.write(f'\n\t{name} ') - def _create_project_settings(self): self._rel_path = os.path.dirname(self._name) self._project_dict = { @@ -369,5 +351,6 @@ class NewService(CommandABC): self._create_venv() else: - self._help('Usage: cpl new [options]') + Console.error(f'Project type not found') + Console.write_line(self.help_message) return diff --git a/src/cpl_cli/configuration/schematic_collection.py b/src/cpl_cli/configuration/schematic_collection.py new file mode 100644 index 00000000..a3469077 --- /dev/null +++ b/src/cpl_cli/configuration/schematic_collection.py @@ -0,0 +1,16 @@ +from cpl_core.utils import String + + +class SchematicCollection: + _schematics: dict = {} + + @classmethod + def register(cls, template: type, schematic: str, aliases: list[str]): + cls._schematics[schematic] = { + "Template": template, + "Aliases": aliases + } + + @classmethod + def get_schematics(cls) -> dict: + return cls._schematics diff --git a/src/cpl_cli/startup_argument_extension.py b/src/cpl_cli/startup_argument_extension.py index 16bd5449..835a9b67 100644 --- a/src/cpl_cli/startup_argument_extension.py +++ b/src/cpl_cli/startup_argument_extension.py @@ -29,16 +29,7 @@ class StartupArgumentExtension(StartupExtensionABC): config.create_console_argument(ArgumentTypeEnum.Executable, '', 'add', ['a', 'A'], AddService, True, validators=[WorkspaceValidator]) \ .add_console_argument(ArgumentTypeEnum.Flag, '--', 'simulate', ['s', 'S']) config.create_console_argument(ArgumentTypeEnum.Executable, '', 'build', ['b', 'B'], BuildService, True, validators=[ProjectValidator]) - config.create_console_argument(ArgumentTypeEnum.Executable, '', 'generate', ['g', 'G'], GenerateService, True) \ - .add_console_argument(ArgumentTypeEnum.Variable, '', 'abc', ['a', 'A'], ' ') \ - .add_console_argument(ArgumentTypeEnum.Variable, '', 'class', ['c', 'C'], ' ') \ - .add_console_argument(ArgumentTypeEnum.Variable, '', 'enum', ['e', 'E'], ' ') \ - .add_console_argument(ArgumentTypeEnum.Variable, '', 'pipe', ['p', 'P'], ' ') \ - .add_console_argument(ArgumentTypeEnum.Variable, '', 'service', ['s', 'S'], ' ') \ - .add_console_argument(ArgumentTypeEnum.Variable, '', 'settings', ['st', 'ST'], ' ') \ - .add_console_argument(ArgumentTypeEnum.Variable, '', 'test_case', ['tc', 'TC'], ' ') \ - .add_console_argument(ArgumentTypeEnum.Variable, '', 'thread', ['t', 'T'], ' ') \ - .add_console_argument(ArgumentTypeEnum.Variable, '', 'validator', ['v', 'V'], ' ') + config.create_console_argument(ArgumentTypeEnum.Executable, '', 'generate', ['g', 'G'], GenerateService, True) config.create_console_argument(ArgumentTypeEnum.Executable, '', 'install', ['i', 'I'], InstallService, True, validators=[ProjectValidator]) \ .add_console_argument(ArgumentTypeEnum.Flag, '--', 'dev', ['d', 'D']) \ .add_console_argument(ArgumentTypeEnum.Flag, '--', 'virtual', ['v', 'V']) \ diff --git a/src/cpl_cli/test_enum.py b/src/cpl_cli/test_enum.py new file mode 100644 index 00000000..425ab6c1 --- /dev/null +++ b/src/cpl_cli/test_enum.py @@ -0,0 +1 @@ +# imports diff --git a/src/cpl_cli/test_init.py b/src/cpl_cli/test_init.py new file mode 100644 index 00000000..425ab6c1 --- /dev/null +++ b/src/cpl_cli/test_init.py @@ -0,0 +1 @@ +# imports diff --git a/src/cpl_core/configuration/argument_executable_abc.py b/src/cpl_core/configuration/argument_executable_abc.py index 8263b338..d7f3319a 100644 --- a/src/cpl_core/configuration/argument_executable_abc.py +++ b/src/cpl_core/configuration/argument_executable_abc.py @@ -7,4 +7,4 @@ class ArgumentExecutableABC(ABC): def __init__(self): pass @abstractmethod - def execute(self, args: list[str]): pass + def run(self, args: list[str]): pass diff --git a/src/cpl_core/configuration/configuration.py b/src/cpl_core/configuration/configuration.py index dbe2574f..f2b8dd5c 100644 --- a/src/cpl_core/configuration/configuration.py +++ b/src/cpl_core/configuration/configuration.py @@ -341,7 +341,7 @@ class Configuration(ConfigurationABC): continue self._additional_arguments.append(arg) - cmd.execute(self._additional_arguments) + cmd.run(self._additional_arguments) self._handle_pre_or_post_executables(False, exe, services) prevent = exe.prevent_next_executable success = True diff --git a/tests/custom/general/.cpl/custom_schematic.py b/tests/custom/general/.cpl/custom_schematic.py new file mode 100644 index 00000000..dd951a69 --- /dev/null +++ b/tests/custom/general/.cpl/custom_schematic.py @@ -0,0 +1,27 @@ + + +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC + + +class Custom(GenerateSchematicABC): + + def __init__(self, *args: str): + GenerateSchematicABC.__init__(self, *args) + + def get_code(self) -> str: + code = """\ + class $Name: + + def __init__(self): + print('hello') + """ + x = self.build_code_str(code, Name=self._class_name) + return x + + @classmethod + def register(cls): + GenerateSchematicABC.register( + cls, + 'custom', + ['cm', 'CM'] + ) diff --git a/tests/custom/general/test/__init__.py b/tests/custom/general/test/__init__.py new file mode 100644 index 00000000..425ab6c1 --- /dev/null +++ b/tests/custom/general/test/__init__.py @@ -0,0 +1 @@ +# imports diff --git a/tests/custom/general/test/custom.py b/tests/custom/general/test/custom.py new file mode 100644 index 00000000..16baa336 --- /dev/null +++ b/tests/custom/general/test/custom.py @@ -0,0 +1,4 @@ +class Custom: + + def __init__(self): + print('hello') diff --git a/unittests/unittests_cli/generate_test_case.py b/unittests/unittests_cli/generate_test_case.py index cba7d8a7..16bb382b 100644 --- a/unittests/unittests_cli/generate_test_case.py +++ b/unittests/unittests_cli/generate_test_case.py @@ -78,8 +78,8 @@ class GenerateTestCase(CommandTestCase): self._test_file_with_project('settings', '_settings', path=self._project) def test_test_case(self): - self._test_file('test_case', '_test_case') - self._test_file_with_project('test_case', '_test_case', path=self._project) + self._test_file('test-case', '_test_case') + self._test_file_with_project('test-case', '_test_case', path=self._project) def test_thread(self): self._test_file('thread', '_thread')