diff --git a/cpl-workspace.json b/cpl-workspace.json index 116affef..5d9098a3 100644 --- a/cpl-workspace.json +++ b/cpl-workspace.json @@ -4,7 +4,8 @@ "Projects": { "cpl_core": "src/cpl_core/cpl_core.json", "cpl_cli": "src/cpl_cli/cpl_cli.json", - "cpl_query": "src/cpl_query/cpl_query.json" + "cpl_query": "src/cpl_query/cpl_query.json", + "set-version": "tools/set_version/set-version.json" }, "Scripts": { "hello-world": "echo 'Hello World'", @@ -12,55 +13,44 @@ "db": "cpl build-docs", "docs-open": "xdg-open $PWD/docs/build/html/index.html &", "do": "cpl docs-open", - "build-all": "cpl build-cli; cpl build-core; cpl build-query;", "ba": "cpl build-all", "build-cli": "echo 'Build cpl_cli'; cd ./src/cpl_cli; cpl build; cd ../../;", "build-core": "echo 'Build cpl_core'; cd ./src/cpl_core; cpl build; cd ../../;", "build-query": "echo 'Build cpl_query'; cd ./src/cpl_query; cpl build; cd ../../;", - "publish-all": "cpl publish-cli; cpl publish-core; cpl publish-query;", "pa": "cpl build-all", "publish-cli": "echo 'Publish cpl_cli'; cd ./src/cpl_cli; cpl publish; cd ../../;", "publish-core": "echo 'Publish cpl_core'; cd ./src/cpl_core; cpl publish; cd ../../;", "publish-query": "echo 'Publish cpl_query'; cd ./src/cpl_query; cpl publish; cd ../../;", - "upload-prod-cli": "echo 'PROD Upload cpl_cli'; cpl upl-prod-cli;", "upload-prod-core": "echo 'PROD Upload cpl_core'; cpl upl-prod-core;", "upload-prod-query": "echo 'PROD Upload cpl_query'; cpl upl-prod-query;", - "upload-exp-cli": "echo 'EXP Upload cpl_cli'; cpl upl-exp-cli;", "upload-exp-core": "echo 'EXP Upload cpl_core'; cpl upl-exp-core;", "upload-exp-query": "echo 'EXP Upload cpl_query'; cpl upl-exp-query;", - "upload-dev-cli": "echo 'DEV Upload cpl_cli'; cpl upl-dev-cli;", "upload-dev-core": "echo 'DEV Upload cpl_core'; cpl upl-dev-core;", "upload-dev-query": "echo 'DEV Upload cpl_query'; cpl upl-dev-query;", - "upl-prod-cli": "twine upload -r pip.sh-edraft.de dist/cpl-cli/publish/setup/*", "upl-prod-core": "twine upload -r pip.sh-edraft.de dist/cpl-core/publish/setup/*", "upl-prod-query": "twine upload -r pip.sh-edraft.de dist/cpl-query/publish/setup/*", - "upl-exp-cli": "twine upload -r pip-exp.sh-edraft.de dist/cpl-cli/publish/setup/*", "upl-exp-core": "twine upload -r pip-exp.sh-edraft.de dist/cpl-core/publish/setup/*", "upl-exp-query": "twine upload -r pip-exp.sh-edraft.de dist/cpl-query/publish/setup/*", - "upl-dev-cli": "twine upload -r pip-dev.sh-edraft.de dist/cpl-cli/publish/setup/*", "upl-dev-core": "twine upload -r pip-dev.sh-edraft.de dist/cpl-core/publish/setup/*", "upl-dev-query": "twine upload -r pip-dev.sh-edraft.de dist/cpl-query/publish/setup/*", - "deploy-prod": "cpl deploy-prod-cli; cpl deploy-prod-core; cpl deploy-prod-query;", "dp": "cpl deploy-prod", "deploy-prod-cli": "cpl publish-cli; cpl upload-prod-cli", "deploy-prod-core": "cpl publish-core; cpl upload-prod-core", "deploy-prod-query": "cpl publish-query; cpl upload-prod-query", - "deploy-exp": "cpl deploy-exp-cli; cpl deploy-exp-core; cpl deploy-exp-query;", "de": "cpl deploy-exp", "deploy-exp-cli": "cpl publish-cli; cpl upload-exp-cli", "deploy-exp-core": "cpl publish-core; cpl upload-exp-core", "deploy-exp-query": "cpl publish-query; cpl upload-exp-query", - "deploy-dev": "cpl deploy-dev-cli; cpl deploy-dev-core; cpl deploy-dev-query;", "dd": "cpl deploy-dev", "deploy-dev-cli": "cpl publish-cli; cpl upload-dev-cli", diff --git a/src/cpl_cli/command/run_service.py b/src/cpl_cli/command/run_service.py index e6be3878..78d48a34 100644 --- a/src/cpl_cli/command/run_service.py +++ b/src/cpl_cli/command/run_service.py @@ -1,33 +1,49 @@ import os +import sys import textwrap +from cpl_cli import Error from cpl_cli.command_abc import CommandABC -from cpl_core.console.console import Console -from cpl_core.environment.application_environment_abc import ApplicationEnvironmentABC +from cpl_cli.configuration import WorkspaceSettings from cpl_cli.configuration.build_settings import BuildSettings from cpl_cli.configuration.project_settings import ProjectSettings -from cpl_cli.live_server.live_server_thread import LiveServerThread +from cpl_cli.live_server.start_executable import StartExecutable +from cpl_core.configuration import ConfigurationABC +from cpl_core.console.console import Console +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_core.environment.application_environment_abc import ApplicationEnvironmentABC class RunService(CommandABC): - def __init__(self, env: ApplicationEnvironmentABC, project_settings: ProjectSettings, build_settings: BuildSettings): + def __init__(self, + config: ConfigurationABC, + env: ApplicationEnvironmentABC, + services: ServiceProviderABC, + project_settings: ProjectSettings, + build_settings: BuildSettings, + workspace: WorkspaceSettings + ): """ Service for the CLI command start + :param config: :param env: + :param services: :param project_settings: :param build_settings: + :param workspace: """ CommandABC.__init__(self) + self._config = config self._env = env + self._services = services self._project_settings = project_settings self._build_settings = build_settings + self._workspace = workspace self._src_dir = os.path.join(self._env.working_directory, self._build_settings.source_path) - self._args: list[str] = [] - @property def help_message(self) -> str: return textwrap.dedent("""\ @@ -35,19 +51,49 @@ class RunService(CommandABC): Usage: cpl run """) + def _set_project_by_args(self, name: str): + if self._workspace is None: + Error.error('The command requires to be run in an CPL workspace, but a workspace could not be found.') + sys.exit() + + if name not in self._workspace.projects: + Error.error(f'Project {name} not found in workspace') + sys.exit() + + project_path = self._workspace.projects[name] + + self._config.add_configuration(ProjectSettings, None) + self._config.add_configuration(BuildSettings, None) + + working_directory = self._config.get_configuration('PATH_WORKSPACE') + if working_directory is not None: + self._env.set_working_directory(working_directory) + + json_file = os.path.join(self._env.working_directory, project_path) + self._config.add_json_file(json_file, optional=True, output=False) + self._project_settings: ProjectSettings = self._config.get_configuration(ProjectSettings) + self._build_settings: BuildSettings = self._config.get_configuration(BuildSettings) + + if self._project_settings is None or self._build_settings is None: + Error.error(f'Project {name} not found') + sys.exit() + + self._src_dir = os.path.dirname(json_file) + def execute(self, args: list[str]): """ Entry point of command :param args: :return: """ - ls_thread = LiveServerThread( - self._project_settings.python_executable, - self._src_dir, - self._args, - self._env, - self._build_settings - ) - ls_thread.start() - ls_thread.join() + if len(args) > 1: + Error.error(f'Unexpected argument(s): {", ".join(args)}') + sys.exit() + + if len(args) == 1: + self._set_project_by_args(args[0]) + args.remove(args[0]) + + start_service = StartExecutable(self._env, self._build_settings) + start_service.run(args, self._project_settings.python_executable, self._src_dir, output=False) Console.write_line() diff --git a/src/cpl_cli/live_server/live_server_thread.py b/src/cpl_cli/live_server/live_server_thread.py index 3c88f841..3018b5ef 100644 --- a/src/cpl_cli/live_server/live_server_thread.py +++ b/src/cpl_cli/live_server/live_server_thread.py @@ -35,8 +35,6 @@ class LiveServerThread(threading.Thread): self._command = [] self._env_vars = os.environ - self._set_venv() - @property def command(self) -> list[str]: return self._command @@ -45,16 +43,6 @@ class LiveServerThread(threading.Thread): def main(self) -> str: return self._main - def _set_venv(self): - if self._executable != sys.executable: - path = os.path.abspath(os.path.dirname(os.path.dirname(self._executable))) - if sys.platform == 'win32': - self._env_vars['PATH'] = f'{path}\\bin' + os.pathsep + os.environ.get('PATH', '') - else: - self._env_vars['PATH'] = f'{path}/bin' + os.pathsep + os.environ.get('PATH', '') - - self._env_vars['VIRTUAL_ENV'] = path - def run(self): """ Starts the CPL project diff --git a/src/cpl_cli/live_server/start_executable.py b/src/cpl_cli/live_server/start_executable.py new file mode 100644 index 00000000..426f03e7 --- /dev/null +++ b/src/cpl_cli/live_server/start_executable.py @@ -0,0 +1,81 @@ +import os +import subprocess +import sys +import threading +from datetime import datetime + +from cpl_core.console.console import Console +from cpl_core.console.foreground_color_enum import ForegroundColorEnum +from cpl_core.environment.application_environment_abc import ApplicationEnvironmentABC +from cpl_cli.configuration import BuildSettings + + +class StartExecutable: + + def __init__(self, env: ApplicationEnvironmentABC, build_settings: BuildSettings): + """ + Service to start the CPL project for the live development server + :param env: + :param build_settings: + """ + + self._executable = None + + self._env = env + self._build_settings = build_settings + + self._main = '' + self._command = [] + self._env_vars = os.environ + + self._set_venv() + + def _set_venv(self): + if self._executable is None or self._executable == sys.executable: + return + + path = os.path.abspath(os.path.dirname(os.path.dirname(self._executable))) + if sys.platform == 'win32': + self._env_vars['PATH'] = f'{path}\\bin' + os.pathsep + os.environ.get('PATH', '') + else: + self._env_vars['PATH'] = f'{path}/bin' + os.pathsep + os.environ.get('PATH', '') + + self._env_vars['VIRTUAL_ENV'] = path + + def run(self, args: list[str], executable: str, path: str, output=True): + self._executable = os.path.abspath(executable) + + main = self._build_settings.main + if '.' in self._build_settings.main: + length = len(self._build_settings.main.split('.')) - 1 + main = self._build_settings.main.split('.')[length] + + self._main = os.path.join(path, f'{main}.py') + if not os.path.isfile(self._main): + Console.error('Entry point main.py not found') + return + + # set cwd to src/ + self._env.set_working_directory(os.path.abspath(os.path.join(path))) + src_cwd = os.path.abspath(os.path.join(path, '../')) + if sys.platform == 'win32': + self._env_vars['PYTHONPATH'] = f'{src_cwd};' \ + f'{os.path.join(self._env.working_directory, self._build_settings.source_path)}' + else: + self._env_vars['PYTHONPATH'] = f'{src_cwd}:' \ + f'{os.path.join(self._env.working_directory, self._build_settings.source_path)}' + + if output: + Console.set_foreground_color(ForegroundColorEnum.green) + Console.write_line('Read successfully') + Console.set_foreground_color(ForegroundColorEnum.cyan) + Console.write_line(f'Started at {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}\n\n') + Console.set_foreground_color(ForegroundColorEnum.default) + + self._command = [self._executable, self._main] + # if len(self._args) > 0: + # self._command.append(' '.join(self._args)) + for arg in args: + self._command.append(arg) + + subprocess.run(self._command, env=self._env_vars) diff --git a/src/cpl_cli/startup.py b/src/cpl_cli/startup.py index 6c90f01c..25aebea5 100644 --- a/src/cpl_cli/startup.py +++ b/src/cpl_cli/startup.py @@ -8,7 +8,7 @@ from cpl_core.application.startup_abc import StartupABC from cpl_core.configuration.configuration_abc import ConfigurationABC from cpl_core.dependency_injection.service_collection_abc import ServiceCollectionABC from cpl_core.dependency_injection.service_provider_abc import ServiceProviderABC -from cpl_core.environment import ApplicationEnvironment +from cpl_core.environment.application_environment_abc import ApplicationEnvironmentABC class Startup(StartupABC): @@ -16,7 +16,7 @@ class Startup(StartupABC): def __init__(self): StartupABC.__init__(self) - def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC: + def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironmentABC) -> ConfigurationABC: environment.set_runtime_directory(os.path.dirname(__file__)) configuration.argument_error_function = Error.error @@ -26,7 +26,7 @@ class Startup(StartupABC): return configuration - def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC: + def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironmentABC) -> ServiceProviderABC: services.add_transient(PublisherABC, PublisherService) services.add_transient(LiveServerService) diff --git a/src/cpl_cli/startup_argument_extension.py b/src/cpl_cli/startup_argument_extension.py index 1430e699..41b905f8 100644 --- a/src/cpl_cli/startup_argument_extension.py +++ b/src/cpl_cli/startup_argument_extension.py @@ -1,6 +1,8 @@ import os from typing import Optional +from cpl_core.console import Console + from cpl_cli.command.add_service import AddService from cpl_cli.command.build_service import BuildService from cpl_cli.command.custom_script_service import CustomScriptService @@ -47,6 +49,7 @@ class StartupArgumentExtension(StartupExtensionABC): def _read_cpl_environment(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): workspace: Optional[WorkspaceSettings] = config.get_configuration(WorkspaceSettings) + config.add_configuration('PATH_WORKSPACE', env.working_directory) if workspace is not None: for script in workspace.scripts: config.create_console_argument(ArgumentTypeEnum.Executable, '', script, [], CustomScriptService) diff --git a/src/cpl_core/configuration/configuration.py b/src/cpl_core/configuration/configuration.py index d4a83eb9..9b344ace 100644 --- a/src/cpl_core/configuration/configuration.py +++ b/src/cpl_core/configuration/configuration.py @@ -340,7 +340,7 @@ class Configuration(ConfigurationABC): prevent = exe.prevent_next_executable success = True except Exception as e: - Console.error('An error occurred while executing arguments.') + Console.error('An error occurred while executing arguments.', traceback.format_exc()) sys.exit() return success diff --git a/tools/set_version/__init__.py b/tools/set_version/__init__.py new file mode 100644 index 00000000..ad5eca30 --- /dev/null +++ b/tools/set_version/__init__.py @@ -0,0 +1 @@ +# imports: diff --git a/tools/set_version/application.py b/tools/set_version/application.py new file mode 100644 index 00000000..9ce6fc0a --- /dev/null +++ b/tools/set_version/application.py @@ -0,0 +1,16 @@ +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 from tools') diff --git a/tools/set_version/appsettings.json b/tools/set_version/appsettings.json new file mode 100644 index 00000000..629e6ebd --- /dev/null +++ b/tools/set_version/appsettings.json @@ -0,0 +1,15 @@ +{ + "TimeFormatSettings": { + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }, + + "LoggingSettings": { + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "ERROR", + "FileLogLevel": "WARN" + } +} diff --git a/tools/set_version/main.py b/tools/set_version/main.py new file mode 100644 index 00000000..71943f43 --- /dev/null +++ b/tools/set_version/main.py @@ -0,0 +1,14 @@ +from cpl_core.application import ApplicationBuilder + +from set_version.application import Application +from set_version.startup import Startup + + +def main(): + app_builder = ApplicationBuilder(Application) + app_builder.use_startup(Startup) + app_builder.build().run() + + +if __name__ == '__main__': + main() diff --git a/tools/set_version/set-version.json b/tools/set_version/set-version.json new file mode 100644 index 00000000..3039cf07 --- /dev/null +++ b/tools/set_version/set-version.json @@ -0,0 +1,43 @@ +{ + "ProjectSettings": { + "Name": "set-version", + "Version": { + "Major": "0", + "Minor": "0", + "Micro": "0" + }, + "Author": "", + "AuthorEmail": "", + "Description": "", + "LongDescription": "", + "URL": "", + "CopyrightDate": "", + "CopyrightName": "", + "LicenseName": "", + "LicenseDescription": "", + "Dependencies": [ + "sh_cpl-core>=2022.6.1.dev4" + ], + "PythonVersion": ">=3.10.4", + "PythonPath": { + "linux": "" + }, + "Classifiers": [] + }, + "BuildSettings": { + "ProjectType": "console", + "SourcePath": "", + "OutputPath": "../../dist", + "Main": "set_version.main", + "EntryPoint": "set-version", + "IncludePackageData": false, + "Included": [], + "Excluded": [ + "*/__pycache__", + "*/logs", + "*/tests" + ], + "PackageData": {}, + "ProjectReferences": [] + } +} \ No newline at end of file diff --git a/tools/set_version/startup.py b/tools/set_version/startup.py new file mode 100644 index 00000000..359c03d2 --- /dev/null +++ b/tools/set_version/startup.py @@ -0,0 +1,16 @@ +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()