sh_cpl/docs/source/tutorials.templating.md

182 lines
6.1 KiB
Markdown
Raw Normal View History

2022-12-08 15:29:48 +01:00
# Using cpl g & cpl n templating
## Contents
- [Prerequisites](#prerequisites)
- [Generate schematics](#cpl-generate-scmatics)
- [Project types](#cpl-new-project-types)
## Prerequisites
Create a folder called ```.cpl```
## cpl generate schematics
Create a file which begins with ```schematic_your_schematic.py```.
A schematic template is detected by starting with ```schematic_``` and endswith ```.py```.
You should replace ```your_schematic``` with an appropriate name of your schematic. For example, we will choose ```Enum```.
Attention: It is important that you do not overwrite templates by creating a file or class with the same name.
In the template create a class with the name of your schematic. For example:
```python
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:
import textwrap
code = textwrap.dedent("""\
from enum import Enum
class $Name(Enum):
atr = 0
""")
return self.build_code_str(code, Name=self._class_name)
@classmethod
def register(cls):
GenerateSchematicABC.register(
cls,
'enum',
['e', 'E']
)
```
You can test it by calling ```cpl g --help``` your schematic should be listed as available.
## cpl new project types
The project templating is a little more complex and is therefore divided into several files.
First of all, for information, it is very important not to overwrite any existing files or classes!
Template structure explained by the example of the internal type ```console```:
```
- project_console.py
- project_file_license.py
- project_file_appsettings.py
- project_file.py
- project_file_readme.py
- project_file_code_main.py
- project_file_code_startup.py
- project_file_code_application.py
```
Here the template ```project_console.py``` defines how a console project has to look like when it is generated. Here is the code to illustrate this:
```python
from cpl_cli.abc.project_type_abc import ProjectTypeABC
from cpl_cli.configuration import WorkspaceSettings
from cpl_core.utils import String
class Console(ProjectTypeABC):
def __init__(
self,
base_path: str,
project_name: str,
workspace: WorkspaceSettings,
use_application_api: bool,
use_startup: bool,
use_service_providing: bool,
use_async: bool,
project_file_data: dict,
):
from project_file import ProjectFile
from project_file_appsettings import ProjectFileAppsettings
from project_file_code_application import ProjectFileApplication
from project_file_code_main import ProjectFileMain
from project_file_code_startup import ProjectFileStartup
from project_file_readme import ProjectFileReadme
from project_file_license import ProjectFileLicense
from schematic_init import Init
ProjectTypeABC.__init__(self, base_path, project_name, workspace, use_application_api, use_startup, use_service_providing, use_async, project_file_data)
project_path = f'{base_path}{String.convert_to_snake_case(project_name.split("/")[-1])}/'
self.add_template(ProjectFile(project_name.split('/')[-1], project_path, project_file_data))
if workspace is None:
self.add_template(ProjectFileLicense(''))
self.add_template(ProjectFileReadme(''))
self.add_template(Init('', 'init', f'{base_path}tests/'))
self.add_template(Init('', 'init', project_path))
self.add_template(ProjectFileAppsettings(project_path))
if use_application_api:
self.add_template(ProjectFileApplication(project_path, use_application_api, use_startup, use_service_providing, use_async))
if use_startup:
self.add_template(ProjectFileStartup(project_path, use_application_api, use_startup, use_service_providing, use_async))
self.add_template(ProjectFileMain(project_name.split('/')[-1], project_path, use_application_api, use_startup, use_service_providing, use_async))
```
The class must be named exactly as the project type should be named. It is also checked on the initial letter of the class as alias.
Now create a class for normal files which inherits from ```FileTemplateABC``` and a class for code files which inherits from ```CodeFileTemplateABC```.
For example:
project_file_code_startup.py:
```python
from cpl_cli.abc.code_file_template_abc import CodeFileTemplateABC
class ProjectFileStartup(CodeFileTemplateABC):
def __init__(self, path: str, use_application_api: bool, use_startup: bool, use_service_providing: bool, use_async: bool):
CodeFileTemplateABC.__init__(self, 'startup', path, '', use_application_api, use_startup, use_service_providing, use_async)
def get_code(self) -> str:
import textwrap
return textwrap.dedent("""\
from cpl_core.application import StartupABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceProviderABC, ServiceCollectionABC
from cpl_core.environment import ApplicationEnvironment
class Startup(StartupABC):
def __init__(self):
StartupABC.__init__(self)
def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC:
return configuration
def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC:
return services.build_service_provider()
""")
```
project_file.py:
```python
import json
from cpl_cli.abc.file_template_abc import FileTemplateABC
class ProjectFile(FileTemplateABC):
def __init__(self, name: str, path: str, code: dict):
FileTemplateABC.__init__(self, '', path, '{}')
self._name = f'{name}.json'
self._code = code
def get_code(self) -> str:
return json.dumps(self._code, indent=2)
```