Improved workspace handling in start command
This commit is contained in:
		@@ -446,6 +446,8 @@ class Console:
 | 
			
		||||
        for call in cls._hold_back_calls:
 | 
			
		||||
            call.function(*call.args)
 | 
			
		||||
 | 
			
		||||
        cls._hold_back_calls = []
 | 
			
		||||
 | 
			
		||||
        time.sleep(0.1)
 | 
			
		||||
 | 
			
		||||
        return return_value
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import pathlib
 | 
			
		||||
import os
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
from socket import gethostname
 | 
			
		||||
from typing import Optional
 | 
			
		||||
@@ -22,8 +22,8 @@ class ApplicationEnvironment(ApplicationEnvironmentABC):
 | 
			
		||||
 | 
			
		||||
        self._start_time: datetime = datetime.now()
 | 
			
		||||
        self._end_time: datetime = datetime.now()
 | 
			
		||||
        self._working_directory = pathlib.Path().absolute()
 | 
			
		||||
        self._runtime_directory = pathlib.Path(__file__).parent.absolute()
 | 
			
		||||
        self._working_directory = os.path.abspath('./')
 | 
			
		||||
        self._runtime_directory = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def environment_name(self) -> str:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
from abc import ABC
 | 
			
		||||
from typing import Optional
 | 
			
		||||
 | 
			
		||||
from cpl.configuration.configuration_abc import ConfigurationABC
 | 
			
		||||
from cpl.console.console import Console
 | 
			
		||||
@@ -48,39 +49,44 @@ class CommandHandler(ABC):
 | 
			
		||||
        """
 | 
			
		||||
        for command in self._commands:
 | 
			
		||||
            if cmd == command.name or cmd in command.aliases:
 | 
			
		||||
                if command.is_project_needed and \
 | 
			
		||||
                        not os.path.isfile(os.path.join(self._env.working_directory, 'cpl-workspace.json')):
 | 
			
		||||
                    Error.error(
 | 
			
		||||
                        'The command requires to be run in an CPL workspace, but a workspace could not be found.'
 | 
			
		||||
                    )
 | 
			
		||||
                    return
 | 
			
		||||
 | 
			
		||||
                if command.is_project_needed:
 | 
			
		||||
                    self._config.add_json_file('cpl-workspace.json', optional=True, output=False)
 | 
			
		||||
                    workspace: WorkspaceSettings = self._config.get_configuration(WorkspaceSettings)
 | 
			
		||||
                    error = None
 | 
			
		||||
                    project_name: Optional[str] = None
 | 
			
		||||
                    workspace: Optional[WorkspaceSettings] = None
 | 
			
		||||
 | 
			
		||||
                    if workspace is None:
 | 
			
		||||
                    if os.path.isfile(os.path.join(self._env.working_directory, 'cpl-workspace.json')):
 | 
			
		||||
                        self._config.add_json_file('cpl-workspace.json', optional=True, output=False)
 | 
			
		||||
                        workspace = self._config.get_configuration(WorkspaceSettings)
 | 
			
		||||
 | 
			
		||||
                    elif os.path.isfile(
 | 
			
		||||
                            os.path.join(
 | 
			
		||||
                                self._env.working_directory,
 | 
			
		||||
                                f'{os.path.basename(self._env.working_directory)}.json'
 | 
			
		||||
                            )
 | 
			
		||||
                    ):
 | 
			
		||||
                        project_name = os.path.basename(self._env.working_directory)
 | 
			
		||||
 | 
			
		||||
                    if workspace is None and project_name is None:
 | 
			
		||||
                        Error.error(
 | 
			
		||||
                            'The command requires to be run in an CPL workspace, but a workspace could not be found.'
 | 
			
		||||
                            'The command requires to be run in an CPL workspace or project, '
 | 
			
		||||
                            'but a workspace or project could not be found.'
 | 
			
		||||
                        )
 | 
			
		||||
                        return
 | 
			
		||||
 | 
			
		||||
                    project_name = workspace.default_project
 | 
			
		||||
                    if len(args) > 0:
 | 
			
		||||
                        project_name = args[0]
 | 
			
		||||
                        index = sys.argv.index(args[0]) + 1
 | 
			
		||||
                        if index < len(sys.argv):
 | 
			
		||||
                            args = sys.argv[index:]
 | 
			
		||||
                    if project_name is None:
 | 
			
		||||
                        project_name = workspace.default_project
 | 
			
		||||
 | 
			
		||||
                    self._config.add_configuration('ProjectName', project_name)
 | 
			
		||||
                    project_json = f'{project_name}.json'
 | 
			
		||||
 | 
			
		||||
                    if project_name not in workspace.projects:
 | 
			
		||||
                        Error.error(
 | 
			
		||||
                            f'Project {project_name} not found.'
 | 
			
		||||
                        )
 | 
			
		||||
                        return
 | 
			
		||||
                    if workspace is not None:
 | 
			
		||||
                        if project_name not in workspace.projects:
 | 
			
		||||
                            Error.error(
 | 
			
		||||
                                f'Project {project_name} not found.'
 | 
			
		||||
                            )
 | 
			
		||||
                            return
 | 
			
		||||
                        project_json = workspace.projects[project_name]
 | 
			
		||||
 | 
			
		||||
                    project_json = workspace.projects[project_name]
 | 
			
		||||
                    if not os.path.isfile(os.path.join(self._env.working_directory, project_json)):
 | 
			
		||||
                        Error.error(
 | 
			
		||||
                            'The command requires to be run in an CPL project, but a project could not be found.'
 | 
			
		||||
@@ -89,7 +95,7 @@ class CommandHandler(ABC):
 | 
			
		||||
 | 
			
		||||
                    self._config.add_json_file(project_json, optional=True, output=False)
 | 
			
		||||
 | 
			
		||||
                    self._config.environment.set_working_directory(
 | 
			
		||||
                    self._env.set_working_directory(
 | 
			
		||||
                        os.path.join(self._env.working_directory, os.path.dirname(project_json))
 | 
			
		||||
                    )
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,20 +9,24 @@ from watchdog.observers import Observer
 | 
			
		||||
from cpl.console.console import Console
 | 
			
		||||
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LiveServerService(FileSystemEventHandler):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, env: ApplicationEnvironmentABC, build_settings: BuildSettings):
 | 
			
		||||
    def __init__(self, env: ApplicationEnvironmentABC, project_settings: ProjectSettings,
 | 
			
		||||
                 build_settings: BuildSettings):
 | 
			
		||||
        """
 | 
			
		||||
        Service for the live development server
 | 
			
		||||
        :param env:
 | 
			
		||||
        :param project_settings:
 | 
			
		||||
        :param build_settings:
 | 
			
		||||
        """
 | 
			
		||||
        FileSystemEventHandler.__init__(self)
 | 
			
		||||
 | 
			
		||||
        self._env = env
 | 
			
		||||
        self._project_settings = project_settings
 | 
			
		||||
        self._build_settings = build_settings
 | 
			
		||||
 | 
			
		||||
        self._src_dir = os.path.join(self._env.working_directory, self._build_settings.source_path)
 | 
			
		||||
@@ -72,7 +76,13 @@ class LiveServerService(FileSystemEventHandler):
 | 
			
		||||
 | 
			
		||||
    def _start(self):
 | 
			
		||||
        self._start_observer()
 | 
			
		||||
        self._ls_thread = LiveServerThread(self._src_dir, self._build_settings, self._args)
 | 
			
		||||
        self._ls_thread = LiveServerThread(
 | 
			
		||||
            self._project_settings.python_executable,
 | 
			
		||||
            self._src_dir,
 | 
			
		||||
            self._args,
 | 
			
		||||
            self._env,
 | 
			
		||||
            self._build_settings
 | 
			
		||||
        )
 | 
			
		||||
        self._ls_thread.start()
 | 
			
		||||
        self._ls_thread.join()
 | 
			
		||||
        Console.close()
 | 
			
		||||
 
 | 
			
		||||
@@ -6,21 +6,29 @@ from datetime import datetime
 | 
			
		||||
 | 
			
		||||
from cpl.console.console import Console
 | 
			
		||||
from cpl.console.foreground_color_enum import ForegroundColorEnum
 | 
			
		||||
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
 | 
			
		||||
from cpl_cli.configuration import BuildSettings
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LiveServerThread(threading.Thread):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, path: str, build_settings: BuildSettings, args: list[str]):
 | 
			
		||||
    def __init__(self, executable: str, path: str, args: list[str], env: ApplicationEnvironmentABC,
 | 
			
		||||
                 build_settings: BuildSettings):
 | 
			
		||||
        """
 | 
			
		||||
        Thread to start the CPL project for the live development server
 | 
			
		||||
        :param executable:
 | 
			
		||||
        :param path:
 | 
			
		||||
        :param args:
 | 
			
		||||
        :param env:
 | 
			
		||||
        :param build_settings:
 | 
			
		||||
        """
 | 
			
		||||
        threading.Thread.__init__(self)
 | 
			
		||||
 | 
			
		||||
        self._executable = executable
 | 
			
		||||
        self._path = path
 | 
			
		||||
        self._build_settings = build_settings
 | 
			
		||||
        self._args = args
 | 
			
		||||
        self._env = env
 | 
			
		||||
        self._build_settings = build_settings
 | 
			
		||||
 | 
			
		||||
        self._main = ''
 | 
			
		||||
        self._command = []
 | 
			
		||||
@@ -38,11 +46,9 @@ class LiveServerThread(threading.Thread):
 | 
			
		||||
        Starts the CPL project
 | 
			
		||||
        :return:
 | 
			
		||||
        """
 | 
			
		||||
        src_path = ''
 | 
			
		||||
        main = self._build_settings.main
 | 
			
		||||
        if '.' in self._build_settings.main:
 | 
			
		||||
            length = len(self._build_settings.main.split('.')) - 1
 | 
			
		||||
            src_path = self._path.replace(f'{"/".join(self._build_settings.main.split(".")[:length])}/', '')
 | 
			
		||||
            main = self._build_settings.main.split('.')[length]
 | 
			
		||||
 | 
			
		||||
        self._main = os.path.join(self._path, f'{main}.py')
 | 
			
		||||
@@ -52,11 +58,11 @@ class LiveServerThread(threading.Thread):
 | 
			
		||||
 | 
			
		||||
        env_vars = os.environ
 | 
			
		||||
        if sys.platform == 'win32':
 | 
			
		||||
            env_vars['PYTHONPATH'] = f'{os.path.dirname(src_path)};' \
 | 
			
		||||
                                     f'{os.path.join(os.path.dirname(src_path), self._build_settings.source_path)}'
 | 
			
		||||
            env_vars['PYTHONPATH'] = f'{self._env.working_directory};' \
 | 
			
		||||
                                     f'{os.path.join(self._env.working_directory, self._build_settings.source_path)}'
 | 
			
		||||
        else:
 | 
			
		||||
            env_vars['PYTHONPATH'] = f'{os.path.dirname(src_path)}:' \
 | 
			
		||||
                                     f'{os.path.join(os.path.dirname(src_path), self._build_settings.source_path)}'
 | 
			
		||||
            env_vars['PYTHONPATH'] = f'{self._env.working_directory}:' \
 | 
			
		||||
                                     f'{os.path.join(self._env.working_directory, self._build_settings.source_path)}'
 | 
			
		||||
 | 
			
		||||
        Console.set_foreground_color(ForegroundColorEnum.green)
 | 
			
		||||
        Console.write_line('Read successfully')
 | 
			
		||||
@@ -65,5 +71,6 @@ class LiveServerThread(threading.Thread):
 | 
			
		||||
        Console.write_line(f'Started at {now.strftime("%Y-%m-%d %H:%M:%S")}\n\n')
 | 
			
		||||
        Console.set_foreground_color(ForegroundColorEnum.default)
 | 
			
		||||
 | 
			
		||||
        self._command = [sys.executable, self._main, ''.join(self._args)]
 | 
			
		||||
        os.chdir(self._env.working_directory)
 | 
			
		||||
        self._command = [self._executable, self._main, ''.join(self._args)]
 | 
			
		||||
        subprocess.run(self._command, env=env_vars)
 | 
			
		||||
 
 | 
			
		||||
@@ -40,9 +40,7 @@ class Startup(StartupABC):
 | 
			
		||||
        self._configuration.add_environment_variables('CPL_')
 | 
			
		||||
        self._configuration.add_json_file('appsettings.json', path=self._env.runtime_directory,
 | 
			
		||||
                                          optional=False, output=False)
 | 
			
		||||
        self._configuration.add_console_argument(
 | 
			
		||||
            ConsoleArgument('', 'build', ['b', 'B'], ' ', is_value_token_optional=True)
 | 
			
		||||
        )
 | 
			
		||||
        self._configuration.add_console_argument(ConsoleArgument('', 'build', ['b', 'B'], ''))
 | 
			
		||||
        self._configuration.add_console_argument(ConsoleArgument('', 'generate', ['g', 'G'], '', console_arguments=[
 | 
			
		||||
            ConsoleArgument('', 'abc', ['a', 'A'], ' '),
 | 
			
		||||
            ConsoleArgument('', 'class', ['c', 'C'], ' '),
 | 
			
		||||
@@ -59,12 +57,8 @@ class Startup(StartupABC):
 | 
			
		||||
            ConsoleArgument('', 'console', ['c', 'C'], ' '),
 | 
			
		||||
            ConsoleArgument('', 'library', ['l', 'L'], ' ')
 | 
			
		||||
        ]))
 | 
			
		||||
        self._configuration.add_console_argument(
 | 
			
		||||
            ConsoleArgument('', 'publish', ['p', 'P'], ' ', is_value_token_optional=True)
 | 
			
		||||
        )
 | 
			
		||||
        self._configuration.add_console_argument(
 | 
			
		||||
            ConsoleArgument('', 'start', ['s', 'S'], ' ', is_value_token_optional=True)
 | 
			
		||||
        )
 | 
			
		||||
        self._configuration.add_console_argument(ConsoleArgument('', 'publish', ['p', 'P'], ''))
 | 
			
		||||
        self._configuration.add_console_argument(ConsoleArgument('', 'start', ['s', 'S'], ''))
 | 
			
		||||
        self._configuration.add_console_argument(ConsoleArgument('', 'uninstall', ['ui', 'UI'], ' '))
 | 
			
		||||
        self._configuration.add_console_argument(ConsoleArgument('', 'update', ['u', 'U'], ''))
 | 
			
		||||
        self._configuration.add_console_argument(ConsoleArgument('', 'version', ['v', 'V'], ''))
 | 
			
		||||
 
 | 
			
		||||
@@ -16,12 +16,11 @@
 | 
			
		||||
    "LicenseName": "MIT",
 | 
			
		||||
    "LicenseDescription": "MIT, see LICENSE for more details.",
 | 
			
		||||
    "Dependencies": [
 | 
			
		||||
      "sh_cpl==2021.4.dev1",
 | 
			
		||||
      "discord.py==1.7.1"
 | 
			
		||||
      "sh_cpl==2021.4.dev1"
 | 
			
		||||
    ],
 | 
			
		||||
    "PythonVersion": ">=3.8",
 | 
			
		||||
    "PythonPath": {
 | 
			
		||||
      "linux": "general-env/bin/python3.9",
 | 
			
		||||
      "_linux": "../../../../cpl-env/bin/python3.9",
 | 
			
		||||
      "win32": ""
 | 
			
		||||
    },
 | 
			
		||||
    "Classifiers": []
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user