-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathharness-application
118 lines (87 loc) · 4.07 KB
/
harness-application
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python
import pathlib
import sys
import re
import logging
import argparse
from typing import Union
from ch_cli_tools.openapi import APPLICATIONS_SRC_PATH
from ch_cli_tools.utils import confirm, replaceindir, replace_in_file, save_yaml, \
to_python_module
from ch_cli_tools.common_types import CloudHarnessManifest, TemplateType
from ch_cli_tools.application_builders import AppBuilderPipeline
# Only allow lowercased alphabetical characters separated by "-".
name_pattern = re.compile("[a-z]+((-)?[a-z])?")
PLACEHOLDER = '__APP_NAME__'
def main() -> None:
app_name, templates = get_command_line_arguments()
app_path = pathlib.Path(APPLICATIONS_SRC_PATH) / app_name
app_path.mkdir(exist_ok=True)
templates = normalize_templates(templates)
pipeline = AppBuilderPipeline(app_name, app_path, templates)
pipeline.handle_pre_merge()
pipeline.handle_merge()
replace_in_file(app_path / 'api' / 'config.json', PLACEHOLDER, to_python_module(app_name))
replaceindir(app_path, PLACEHOLDER, app_name)
pipeline.handle_post_merge()
create_manifest_file(app_path, app_name, templates)
def get_command_line_arguments() -> tuple[str, list[str]]:
parser = argparse.ArgumentParser(description='Creates a new Application.')
parser.add_argument('name', metavar='name', type=str,
help='Application name')
parser.add_argument('-t', '--template',
dest='templates',
action="append",
default=[TemplateType.BASE],
type=str,
help="""Add a template name.
Available templates:
- flask-server (backend flask server based on openapi)
- webapp (React webapp including backend and frontend)
- db-postgres
- db-neo4j
- db-mongo
- django-fastapi (fastapi django backend based on openapi)
- django-ninja (django ninja backend)
""")
args, unknown = parser.parse_known_args(sys.argv[1:])
if unknown:
print('There are unknown args. Make sure to call the script with the accepted args. Try --help')
print(f'unknown: {unknown}')
exit(1)
try:
match = name_pattern.match(args.name)
if not match:
print("Invalid application name")
print(
f"Application name must start and end with lowercased alphabetical characters and may contain '-' as separator. Used expression: '{name_pattern.pattern}'")
exit(1)
except re.error:
print("Invalid regex")
exit(1)
return args.name, args.templates
def normalize_templates(templates: list[str]) -> list[str]:
templates = list(templates)
def django_template_index():
return next(index for index, template in enumerate(templates) if template in TemplateType.django_templates())
has_django_template = any(template in TemplateType.django_templates() for template in templates)
if TemplateType.WEBAPP not in templates:
if (confirm(f'Do you want to generate Vite frontend application?')):
templates.insert(django_template_index(), TemplateType.WEBAPP)
has_database_template = any(template in TemplateType.database_templates() for template in templates)
if has_django_template and not has_database_template:
if (confirm(f'Do you want to use a postgres database?')):
templates.insert(django_template_index(), TemplateType.DB_POSTGRES)
return templates
def create_manifest_file(app_path: pathlib.Path, app_name: str, templates: list[Union[str, TemplateType]]) -> None:
manifest_file = app_path / '.ch-manifest'
manifest = CloudHarnessManifest(
app_name=app_name,
version='1',
inferred=False,
templates=[str(template) for template in templates],
)
logging.info('Creating manifest file')
save_yaml(manifest_file, manifest.to_dict())
if __name__ == "__main__":
main()