diff --git a/src/cpl/utils/string.py b/src/cpl/utils/string.py index 83076004..5ae35ad6 100644 --- a/src/cpl/utils/string.py +++ b/src/cpl/utils/string.py @@ -9,3 +9,11 @@ class String: pattern2 = re.compile(r'([a-z0-9])([A-Z])') file_name = re.sub(pattern1, r'\1_\2', name) return re.sub(pattern2, r'\1_\2', file_name).lower() + + @staticmethod + def first_to_upper(string: str) -> str: + return f'{string[0].upper()}{string[1:]}' + + @staticmethod + def first_to_lower(string: str) -> str: + return f'{string[0].lower()}{string[1:]}' diff --git a/src/cpl_cli/command/generate.py b/src/cpl_cli/command/generate.py index ab311583..c5e355ea 100644 --- a/src/cpl_cli/command/generate.py +++ b/src/cpl_cli/command/generate.py @@ -1,12 +1,18 @@ import os +from collections import Callable from cpl.application.application_abc import ApplicationRuntimeABC from cpl.configuration.configuration_abc import ConfigurationABC -from cpl.console import ForegroundColor +from cpl.console.foreground_color import ForegroundColor from cpl.console.console import Console from cpl.utils.string import String from cpl_cli.command_abc import CommandABC 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.service_template import ServiceTemplate +from cpl_cli.templates.template_file_abc import TemplateFileABC class Generate(CommandABC): @@ -14,6 +20,29 @@ class Generate(CommandABC): def __init__(self, configuration: ConfigurationABC, runtime: ApplicationRuntimeABC): CommandABC.__init__(self) + self._schematics = { + "abc": { + "Upper": "ABC", + "Template": ABCTemplate + }, + "class": { + "Upper": "Class", + "Template": ClassTemplate + }, + "configmodel": { + "Upper": "Settings", + "Template": ConfigModelTemplate + }, + "enum": { + "Upper": "Enum", + "Template": EnumTemplate + }, + "service": { + "Upper": "Service", + "Template": ServiceTemplate + } + } + self._config = configuration self._runtime = runtime @@ -38,30 +67,33 @@ class Generate(CommandABC): template.write(value) template.close() - def _generate_abc(self, name: str): + def _generate(self, schematic: str, name: str, template: Callable[TemplateFileABC]): + class_name = name rel_path = '' if '/' in name: parts = name.split('/') rel_path = '/'.join(parts[:-1]) - name = parts[len(parts) - 1] + class_name = parts[len(parts) - 1] - file_path = os.path.join(self._runtime.working_directory, rel_path, f'{String.convert_to_snake_case(name)}.py') + template = template(class_name, schematic, self._schematics[schematic]["Upper"], rel_path) + + file_path = os.path.join(self._runtime.working_directory, template.path, template.name) if not os.path.isdir(os.path.dirname(file_path)): os.makedirs(os.path.dirname(file_path)) if os.path.isfile(file_path): - Console.error('ABC already exists!') + Console.error(f'{String.first_to_upper(schematic)} already exists!') exit() - message = f'Creating {self._runtime.working_directory}/{rel_path}/{String.convert_to_snake_case(name)}.py' - if rel_path == '': - message = f'Creating {self._runtime.working_directory}/{String.convert_to_snake_case(name)}.py' + message = f'Creating {self._runtime.working_directory}/{template.path}/{template.name}' + if template.path == '': + message = f'Creating {self._runtime.working_directory}/{template.name}' Console.spinner( message, self._create_file, file_path, - ABCTemplate.get_abc_py(name), + template.value, text_foreground_color=ForegroundColor.green, spinner_foreground_color=ForegroundColor.cyan ) @@ -76,20 +108,9 @@ class Generate(CommandABC): if name is None: name = Console.read(f'Name for the {args[0]}: ') - if schematic == 'abc': - self._generate_abc(name) - - elif schematic == 'class': - pass - - elif schematic == 'configmodel': - pass - - elif schematic == 'enum': - pass - - elif schematic == 'service': - pass + if schematic in self._schematics: + s = self._schematics[schematic] + self._generate(schematic, name, s["Template"]) else: self._help('Usage: cpl generate [options]') diff --git a/src/cpl_cli/templates/generate/abc_template.py b/src/cpl_cli/templates/generate/abc_template.py index 9a2cd56f..9891bd40 100644 --- a/src/cpl_cli/templates/generate/abc_template.py +++ b/src/cpl_cli/templates/generate/abc_template.py @@ -1,12 +1,19 @@ import textwrap from string import Template +from cpl.utils.string import String +from cpl_cli.templates.template_file_abc import TemplateFileABC -class ABCTemplate: - @staticmethod - def get_abc_py(name: str) -> str: - string = textwrap.dedent("""\ +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' + self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' + self._path = path + self._value = textwrap.dedent("""\ from abc import ABC, abstractmethod @@ -14,9 +21,18 @@ class ABCTemplate: @abstractmethod def __init__(self): pass - """) - return Template(string).substitute( - Name=name + @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 new file mode 100644 index 00000000..b37972eb --- /dev/null +++ b/src/cpl_cli/templates/generate/class_template.py @@ -0,0 +1,35 @@ +import textwrap +from string import Template + +from cpl.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)}.{schematic}.py' + self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' + 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 new file mode 100644 index 00000000..f4c4afb3 --- /dev/null +++ b/src/cpl_cli/templates/generate/configmodel_template.py @@ -0,0 +1,54 @@ +import textwrap +from string import Template + +from cpl.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' + self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' + self._path = path + self._value = textwrap.dedent("""\ + import traceback + + from cpl.configuration.configuration_model_abc import ConfigurationModelABC + from cpl.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 {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 new file mode 100644 index 00000000..d0f69e50 --- /dev/null +++ b/src/cpl_cli/templates/generate/enum_template.py @@ -0,0 +1,37 @@ +import textwrap +from string import Template + +from cpl.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' + self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' + 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/service_template.py b/src/cpl_cli/templates/generate/service_template.py new file mode 100644 index 00000000..3fd3a9cf --- /dev/null +++ b/src/cpl_cli/templates/generate/service_template.py @@ -0,0 +1,38 @@ +import textwrap +from string import Template + +from cpl.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' + self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' + self._path = path + self._value = textwrap.dedent("""\ + from cpl.dependency_injection import ServiceABC + + + class $Name(ServiceABC): + + def __init__(self): + ServiceABC.__init__(self) + """) + + @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 + )