sh_cpl/src/cpl_cli/command/generate_service.py

260 lines
8.2 KiB
Python
Raw Normal View History

2021-03-10 22:29:42 +01:00
import os
2022-01-19 12:44:23 +01:00
import sys
2021-04-11 16:36:59 +02:00
import textwrap
2021-03-10 22:29:42 +01:00
from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC
2022-05-26 13:17:58 +02:00
from cpl_cli.command_abc import CommandABC
from cpl_cli.configuration import WorkspaceSettings
from cpl_cli.configuration.schematic_collection import SchematicCollection
2022-05-26 13:17:58 +02:00
from cpl_core.configuration.configuration_abc import ConfigurationABC
from cpl_core.console.console import Console
from cpl_core.console.foreground_color_enum import ForegroundColorEnum
from cpl_core.utils.string import String
2021-03-10 22:29:42 +01:00
2021-03-12 16:06:30 +01:00
class GenerateService(CommandABC):
2021-03-10 22:29:42 +01:00
def __init__(
self,
configuration: ConfigurationABC,
workspace: WorkspaceSettings,
):
2021-03-14 16:01:15 +01:00
"""
Service for the CLI command generate
:param configuration:
"""
2021-03-10 22:29:42 +01:00
CommandABC.__init__(self)
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
# }
# }
2021-03-10 22:29:42 +01:00
self._config = configuration
2021-03-29 09:21:58 +02:00
self._env = self._config.environment
2021-03-10 22:29:42 +01:00
2021-04-11 16:36:59 +02:00
@property
def help_message(self) -> str:
return textwrap.dedent("""\
2021-04-12 19:44:29 +02:00
Generate a file based on schematic.
2021-04-12 20:05:55 +02:00
Usage: cpl generate <schematic> <name>
2021-04-12 19:44:29 +02:00
2021-04-12 20:05:55 +02:00
Arguments:
2021-04-12 19:44:29 +02:00
schematic: The schematic to generate.
name: The name of the generated file
2021-04-12 20:05:55 +02:00
Schematics:
2021-04-12 19:44:29 +02:00
abc
class
enum
2022-05-22 18:48:33 +02:00
pipe
2021-04-12 19:44:29 +02:00
service
settings
2022-05-26 13:17:58 +02:00
test_case
2021-04-12 19:44:29 +02:00
thread
2022-05-20 10:34:09 +02:00
validator
2021-04-11 16:36:59 +02:00
""")
2021-03-10 22:29:42 +01:00
@staticmethod
def _help(message: str):
2021-03-14 16:01:15 +01:00
"""
Internal help output
:param message:
:return:
"""
2021-03-10 22:29:42 +01:00
Console.error(message)
schematics = [
2021-03-12 15:44:55 +01:00
'abc (a|A)',
'class (c|C)',
'enum (e|E)',
2022-05-22 18:48:33 +02:00
'pipe (p|P)',
2021-03-12 15:44:55 +01:00
'service (s|S)',
2022-05-20 10:34:09 +02:00
'settings (st|ST)',
2022-05-26 13:17:58 +02:00
'test-case (tc|TC)',
2022-05-20 10:34:09 +02:00
'thread (t|T)',
'validator (v|V)'
2021-03-10 22:29:42 +01:00
]
Console.write_line('Available Schematics:')
for name in schematics:
Console.write(f'\n\t{name} ')
@staticmethod
def _create_file(file_path: str, value: str):
2021-03-14 16:01:15 +01:00
"""
Creates the given file with content
:param file_path:
:param value:
:return:
"""
2021-03-10 22:29:42 +01:00
with open(file_path, 'w') as template:
template.write(value)
template.close()
def _create_init_files(self, file_path: str, template: GenerateSchematicABC, class_name: str, schematic: str, rel_path: str):
2021-03-10 22:29:42 +01:00
if not os.path.isdir(os.path.dirname(file_path)):
os.makedirs(os.path.dirname(file_path))
2021-03-30 09:47:47 +02:00
directory = ''
for subdir in template.path.split('/'):
directory = os.path.join(directory, subdir)
if subdir == 'src':
continue
file = self._schematics['init']['Template'](class_name, 'init', rel_path)
if os.path.exists(os.path.join(os.path.abspath(directory), file.name)):
continue
Console.spinner(
f'Creating {os.path.abspath(directory)}/{file.name}',
self._create_file,
os.path.join(os.path.abspath(directory), file.name),
file.get_code(),
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.cyan
)
2021-03-10 22:29:42 +01:00
def _generate(self, schematic: str, name: str, template: type):
"""
Generates files by given schematic, name and template
:param schematic:
:param name:
:param template:
:return:
"""
class_name = name
rel_path = ''
if '/' in name:
parts = name.split('/')
rel_path = '/'.join(parts[:-1])
class_name = parts[len(parts) - 1]
if self._workspace is not None and parts[0] in self._workspace.projects:
rel_path = os.path.join(os.path.dirname(self._workspace.projects[parts[0]]), *parts[1:-1])
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)
2021-03-10 22:29:42 +01:00
if os.path.isfile(file_path):
2022-05-20 09:17:51 +02:00
Console.error(f'{String.first_to_upper(schematic)} already exists!\n')
2022-01-19 12:44:23 +01:00
sys.exit()
2021-03-10 22:29:42 +01:00
2021-03-29 09:21:58 +02:00
message = f'Creating {self._env.working_directory}/{template.path}/{template.name}'
if template.path == '':
2021-03-29 09:21:58 +02:00
message = f'Creating {self._env.working_directory}/{template.name}'
2021-03-10 22:29:42 +01:00
Console.spinner(
message,
self._create_file,
file_path,
template.get_code(),
2021-03-12 16:06:30 +01:00
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.cyan
2021-03-10 22:29:42 +01:00
)
@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
2022-05-22 18:33:07 +02:00
def execute(self, args: list[str]):
2021-03-14 16:01:15 +01:00
"""
Entry point of command
:param args:
:return:
"""
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()
2022-05-20 08:50:50 +02:00
schematic = None
value = None
for s in self._schematics:
value = self._config.get_configuration(s)
if value is not None:
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]
2022-05-20 08:50:50 +02:00
if schematic is None:
2021-03-10 22:29:42 +01:00
self._help('Usage: cpl generate <schematic> [options]')
2022-05-25 17:08:03 +02:00
Console.write_line()
2022-01-19 12:44:23 +01:00
sys.exit()
2021-03-10 22:29:42 +01:00
2022-05-20 08:50:50 +02:00
name = value
2021-03-10 22:29:42 +01:00
if name is None:
name = Console.read(f'Name for the {args[0]}: ')
if schematic in self._schematics:
s = self._schematics[schematic]
self._generate(schematic, name, s["Template"])
2021-03-10 22:29:42 +01:00
else:
2021-03-11 09:43:45 +01:00
self._help('Usage: cpl generate <schematic> [options]')
2022-05-25 17:08:03 +02:00
Console.write_line()
2022-01-19 12:44:23 +01:00
sys.exit()