From 589ef4fd4caf61e0f693fa9f220ef519410a5bf1 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sun, 14 Nov 2021 12:32:11 +0100 Subject: [PATCH] Added logic to generate new projects with async --- .../new/console/source/name/application.py | 56 +++-- .../new/console/source/name/main.py | 224 ++++++++++++------ .../new/console/source/name/startup.py | 60 +++-- src/cpl_cli/command/new_service.py | 7 + src/cpl_cli/source_creator/console_builder.py | 25 +- src/cpl_cli/source_creator/library_builder.py | 21 +- 6 files changed, 271 insertions(+), 122 deletions(-) diff --git a/src/cpl_cli/_templates/new/console/source/name/application.py b/src/cpl_cli/_templates/new/console/source/name/application.py index 8230d308..56d9990f 100644 --- a/src/cpl_cli/_templates/new/console/source/name/application.py +++ b/src/cpl_cli/_templates/new/console/source/name/application.py @@ -5,29 +5,51 @@ from cpl_cli._templates.template_file_abc import TemplateFileABC class ApplicationTemplate(TemplateFileABC): - def __init__(self, name: str, path: str): + def __init__(self, name: str, path: str, use_async: bool): TemplateFileABC.__init__(self) self._name = 'application.py' self._path = path - self._value = textwrap.dedent("""\ - from cpl_core.application import ApplicationABC - from cpl_core.configuration import ConfigurationABC - from cpl_core.console import Console - from cpl_core.dependency_injection import ServiceProviderABC + self._use_async = use_async + + if self._use_async: + self._value = textwrap.dedent("""\ + from cpl_core.application import ApplicationABC + from cpl_core.configuration import ConfigurationABC + from cpl_core.console import Console + from cpl_core.dependency_injection import ServiceProviderABC + + + class Application(ApplicationABC): + def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): + ApplicationABC.__init__(self, config, services) - class Application(ApplicationABC): - - def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): - ApplicationABC.__init__(self, config, services) - - def configure(self): - pass - - def main(self): - Console.write_line('Hello World') - """) + async def configure(self): + pass + + async def main(self): + Console.write_line('Hello World') + """) + else: + self._value = textwrap.dedent("""\ + from cpl_core.application import ApplicationABC + from cpl_core.configuration import ConfigurationABC + from cpl_core.console import Console + from cpl_core.dependency_injection import ServiceProviderABC + + + class Application(ApplicationABC): + + def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): + ApplicationABC.__init__(self, config, services) + + def configure(self): + pass + + def main(self): + Console.write_line('Hello World') + """) @property def name(self) -> str: diff --git a/src/cpl_cli/_templates/new/console/source/name/main.py b/src/cpl_cli/_templates/new/console/source/name/main.py index 76734058..6d78bf15 100644 --- a/src/cpl_cli/_templates/new/console/source/name/main.py +++ b/src/cpl_cli/_templates/new/console/source/name/main.py @@ -6,31 +6,52 @@ from cpl_cli._templates.template_file_abc import TemplateFileABC class MainWithApplicationHostAndStartupTemplate(TemplateFileABC): - def __init__(self, name: str, path: str): + def __init__(self, name: str, path: str, use_async: bool): TemplateFileABC.__init__(self) name = String.convert_to_snake_case(name) self._name = 'main.py' self._path = path + self._use_async = use_async import_pkg = f'{name}.' - self._value = textwrap.dedent(f"""\ - from cpl_core.application import ApplicationBuilder - - from {import_pkg}application import Application - from {import_pkg}startup import Startup - - - def main(): - app_builder = ApplicationBuilder(Application) - app_builder.use_startup(Startup) - app_builder.build().run() - - - if __name__ == '__main__': - main() - """) + if use_async: + self._value = textwrap.dedent(f"""\ + from cpl_core.application import ApplicationBuilder + + from {import_pkg}application import Application + from {import_pkg}startup import Startup + + + async def main(): + app_builder = ApplicationBuilder(Application) + app_builder.use_startup(Startup) + app: Application = await app_builder.build_async() + await app.run() + + + if __name__ == '__main__': + ml = asyncio.get_event_loop() + ml.run_until_complete(main()) + """) + else: + self._value = textwrap.dedent(f"""\ + from cpl_core.application import ApplicationBuilder + + from {import_pkg}application import Application + from {import_pkg}startup import Startup + + + def main(): + app_builder = ApplicationBuilder(Application) + app_builder.use_startup(Startup) + app_builder.build().run() + + + if __name__ == '__main__': + main() + """) @property def name(self) -> str: @@ -47,29 +68,48 @@ class MainWithApplicationHostAndStartupTemplate(TemplateFileABC): class MainWithApplicationBaseTemplate(TemplateFileABC): - def __init__(self, name: str, path: str): + def __init__(self, name: str, path: str, use_async: bool): TemplateFileABC.__init__(self) name = String.convert_to_snake_case(name) self._name = 'main.py' self._path = path + self._use_async = use_async import_pkg = f'{name}.' - self._value = textwrap.dedent(f"""\ - from cpl_core.application import ApplicationBuilder - - from {import_pkg}application import Application - - - def main(): - app_builder = ApplicationBuilder(Application) - app_builder.build().run() - - - if __name__ == '__main__': - main() - """) + if use_async: + self._value = textwrap.dedent(f"""\ + from cpl_core.application import ApplicationBuilder + + from {import_pkg}application import Application + + + async def main(): + app_builder = ApplicationBuilder(Application) + app: Application = await app_builder.build_async() + await app.run() + + + if __name__ == '__main__': + ml = asyncio.get_event_loop() + ml.run_until_complete(main()) + """) + else: + self._value = textwrap.dedent(f"""\ + from cpl_core.application import ApplicationBuilder + + from {import_pkg}application import Application + + + def main(): + app_builder = ApplicationBuilder(Application) + app_builder.build().run() + + + if __name__ == '__main__': + main() + """) @property def name(self) -> str: @@ -86,26 +126,41 @@ class MainWithApplicationBaseTemplate(TemplateFileABC): class MainWithoutApplicationBaseTemplate(TemplateFileABC): - def __init__(self, name: str, path: str): + def __init__(self, name: str, path: str, use_async: bool): TemplateFileABC.__init__(self) name = String.convert_to_snake_case(name) self._name = 'main.py' self._path = path + self._use_async = use_async import_pkg = f'{name}.' - self._value = textwrap.dedent("""\ - from cpl_core.console import Console - - - def main(): - Console.write_line('Hello World') - - - if __name__ == '__main__': - main() - """) + if use_async: + self._value = textwrap.dedent("""\ + from cpl_core.console import Console + + + async def main(): + Console.write_line('Hello World') + + + if __name__ == '__main__': + ml = asyncio.get_event_loop() + ml.run_until_complete(main()) + """) + else: + self._value = textwrap.dedent("""\ + from cpl_core.console import Console + + + def main(): + Console.write_line('Hello World') + + + if __name__ == '__main__': + main() + """) @property def name(self) -> str: @@ -122,40 +177,69 @@ class MainWithoutApplicationBaseTemplate(TemplateFileABC): class MainWithDependencyInjection(TemplateFileABC): - def __init__(self, name: str, path: str): + def __init__(self, name: str, path: str, use_async: bool): TemplateFileABC.__init__(self) name = String.convert_to_snake_case(name) self._name = 'main.py' self._path = path + self._use_async = use_async import_pkg = f'{name}.' - self._value = textwrap.dedent("""\ - from cpl_core.configuration import Configuration, ConfigurationABC - from cpl_core.console import Console - from cpl_core.dependency_injection import ServiceCollection, ServiceProviderABC - - - def configure_configuration() -> ConfigurationABC: - config = Configuration() - return config - - - def configure_services(config: ConfigurationABC) -> ServiceProviderABC: - services = ServiceCollection(config) - return services.build_service_provider() - - - def main(): - config = configure_configuration() - provider = configure_services(config) - Console.write_line('Hello World') - - - if __name__ == '__main__': - main() - """) + if use_async: + self._value = textwrap.dedent("""\ + from cpl_core.configuration import Configuration, ConfigurationABC + from cpl_core.console import Console + from cpl_core.dependency_injection import ServiceCollection, ServiceProviderABC + + + async def configure_configuration() -> ConfigurationABC: + config = Configuration() + return config + + + async def configure_services(config: ConfigurationABC) -> ServiceProviderABC: + services = ServiceCollection(config) + return services.build_service_provider() + + + async def main(): + await config = configure_configuration() + await provider = configure_services(config) + Console.write_line('Hello World') + + + if __name__ == '__main__': + ml = asyncio.get_event_loop() + ml.run_until_complete(main()) + """) + else: + self._value = textwrap.dedent("""\ + from cpl_core.configuration import Configuration, ConfigurationABC + from cpl_core.console import Console + from cpl_core.dependency_injection import ServiceCollection, ServiceProviderABC + + + def configure_configuration() -> ConfigurationABC: + config = Configuration() + return config + + + def configure_services(config: ConfigurationABC) -> ServiceProviderABC: + services = ServiceCollection(config) + return services.build_service_provider() + + + def main(): + config = configure_configuration() + provider = configure_services(config) + Console.write_line('Hello World') + + + if __name__ == '__main__': + main() + """) @property def name(self) -> str: diff --git a/src/cpl_cli/_templates/new/console/source/name/startup.py b/src/cpl_cli/_templates/new/console/source/name/startup.py index 959bc0ce..f2d51009 100644 --- a/src/cpl_cli/_templates/new/console/source/name/startup.py +++ b/src/cpl_cli/_templates/new/console/source/name/startup.py @@ -5,29 +5,51 @@ from cpl_cli._templates.template_file_abc import TemplateFileABC class StartupTemplate(TemplateFileABC): - def __init__(self, name: str, path: str): + def __init__(self, name: str, path: str, use_async: bool): TemplateFileABC.__init__(self) self._name = 'startup.py' self._path = path - self._value = 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() - """) + self._use_async = use_async + + if self._use_async: + self._value = 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) + + async def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC: + return configuration + + async def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC: + return services.build_service_provider() + """) + else: + self._value = 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() + """) @property def name(self) -> str: diff --git a/src/cpl_cli/command/new_service.py b/src/cpl_cli/command/new_service.py index c8519192..715f4c8b 100644 --- a/src/cpl_cli/command/new_service.py +++ b/src/cpl_cli/command/new_service.py @@ -46,6 +46,7 @@ class NewService(CommandABC): self._use_application_api: bool = False self._use_startup: bool = False self._use_service_providing: bool = False + self._use_async: bool = False @property def help_message(self) -> str: @@ -177,6 +178,10 @@ class NewService(CommandABC): result = Console.read('Do you want to use service providing? (y/n) ') if result.lower() == 'y': self._use_service_providing = True + + result = Console.read('Do you want to use async? (y/n) ') + if result.lower == 'y': + self._use_async = True Console.set_foreground_color(ForegroundColorEnum.default) @@ -202,6 +207,7 @@ class NewService(CommandABC): self._use_application_api, self._use_startup, self._use_service_providing, + self._use_async, self._project.name, self._project_json, self._workspace @@ -231,6 +237,7 @@ class NewService(CommandABC): self._use_application_api, self._use_startup, self._use_service_providing, + self._use_async, self._project.name, self._project_json, self._workspace diff --git a/src/cpl_cli/source_creator/console_builder.py b/src/cpl_cli/source_creator/console_builder.py index b6e3a91c..1d10d52f 100644 --- a/src/cpl_cli/source_creator/console_builder.py +++ b/src/cpl_cli/source_creator/console_builder.py @@ -59,13 +59,14 @@ class ConsoleBuilder: @classmethod def build(cls, project_path: str, use_application_api: bool, use_startup: bool, use_service_providing: bool, - project_name: str, project_settings: dict, workspace: Optional[WorkspaceSettings]): + use_async: bool, project_name: str, project_settings: dict, workspace: Optional[WorkspaceSettings]): """ Builds the console project files :param project_path: :param use_application_api: :param use_startup: :param use_service_providing: + :param use_async: :param project_name: :param project_settings: :param workspace: @@ -79,7 +80,8 @@ class ConsoleBuilder: ReadmeTemplate(), TestsInitTemplate(), AppsettingsTemplate(), - MainInitTemplate(project_name, os.path.join('src/', project_name_snake)) + MainInitTemplate(project_name, os.path.join( + 'src/', project_name_snake)) ] else: project_path = os.path.join( @@ -103,18 +105,22 @@ class ConsoleBuilder: src_rel_path = os.path.join('src/', src_name) if use_application_api: - templates.append(ApplicationTemplate(src_name, src_rel_path)) + templates.append(ApplicationTemplate(src_name, src_rel_path, use_async)) if use_startup: - templates.append(StartupTemplate(src_name, src_rel_path)) - templates.append(MainWithApplicationHostAndStartupTemplate(src_name, src_rel_path)) + templates.append(StartupTemplate(src_name, src_rel_path, use_async)) + templates.append(MainWithApplicationHostAndStartupTemplate( + src_name, src_rel_path, use_async)) else: - templates.append(MainWithApplicationBaseTemplate(src_name, src_rel_path)) + templates.append(MainWithApplicationBaseTemplate( + src_name, src_rel_path, use_async)) else: if use_service_providing: - templates.append(MainWithDependencyInjection(src_name, src_rel_path)) + templates.append(MainWithDependencyInjection( + src_name, src_rel_path, use_async)) else: - templates.append(MainWithoutApplicationBaseTemplate(src_name, src_rel_path)) + templates.append(MainWithoutApplicationBaseTemplate( + src_name, src_rel_path, use_async)) proj_name = project_name if workspace is not None: @@ -132,7 +138,8 @@ class ConsoleBuilder: else: workspace.projects[project_name] = f'src/{project_file_path}' - cls._create_workspace('cpl-workspace.json', workspace.default_project, workspace.projects) + cls._create_workspace('cpl-workspace.json', + workspace.default_project, workspace.projects) Console.spinner( f'Creating {project_file_path}', diff --git a/src/cpl_cli/source_creator/library_builder.py b/src/cpl_cli/source_creator/library_builder.py index dd009a1e..15268a07 100644 --- a/src/cpl_cli/source_creator/library_builder.py +++ b/src/cpl_cli/source_creator/library_builder.py @@ -59,7 +59,7 @@ class LibraryBuilder: @classmethod def build(cls, project_path: str, use_application_api: bool, use_startup: bool, - use_service_providing: bool, project_name: str, project_settings: dict, + use_async: bool, use_service_providing: bool, project_name: str, project_settings: dict, workspace: Optional[WorkspaceSettings]): """ Builds the library project files @@ -67,6 +67,7 @@ class LibraryBuilder: :param use_application_api: :param use_startup: :param use_service_providing: + :param use_async: :param project_name: :param project_settings: :param workspace: @@ -79,7 +80,8 @@ class LibraryBuilder: LicenseTemplate(), ReadmeTemplate(), TestsInitTemplate(), - NameInitTemplate(project_name, os.path.join('src/', project_name_snake)), + NameInitTemplate(project_name, os.path.join( + 'src/', project_name_snake)), AppsettingsTemplate() ] else: @@ -108,14 +110,18 @@ class LibraryBuilder: if use_startup: templates.append(StartupTemplate(src_name, src_rel_path)) - templates.append(MainWithApplicationHostAndStartupTemplate(src_name, src_rel_path)) + templates.append(MainWithApplicationHostAndStartupTemplate( + src_name, src_rel_path)) else: - templates.append(MainWithApplicationBaseTemplate(src_name, src_rel_path)) + templates.append(MainWithApplicationBaseTemplate( + src_name, src_rel_path)) else: if use_service_providing: - templates.append(MainWithDependencyInjection(src_name, src_rel_path)) + templates.append(MainWithDependencyInjection( + src_name, src_rel_path)) else: - templates.append(MainWithoutApplicationBaseTemplate(src_name, src_rel_path)) + templates.append(MainWithoutApplicationBaseTemplate( + src_name, src_rel_path)) proj_name = project_name if workspace is not None: @@ -133,7 +139,8 @@ class LibraryBuilder: else: workspace.projects[project_name] = f'src/{project_file_path}' - cls._create_workspace('cpl-workspace.json', workspace.default_project, workspace.projects) + cls._create_workspace('cpl-workspace.json', + workspace.default_project, workspace.projects) Console.spinner( f'Creating {project_file_path}',