2022.6.5 - CLI Erweiterung #68

Merged
edraft merged 2 commits from 2022.6.5 into 2022.6 2022-05-22 18:34:45 +02:00
23 changed files with 129 additions and 72 deletions

View File

@ -1,6 +1,7 @@
import sys import sys
import traceback import traceback
from cpl_cli.error import Error
from cpl_core.application.application_abc import ApplicationABC from cpl_core.application.application_abc import ApplicationABC
from cpl_core.configuration.configuration_abc import ConfigurationABC from cpl_core.configuration.configuration_abc import ConfigurationABC
from cpl_core.console.console import Console from cpl_core.console.console import Console
@ -26,7 +27,16 @@ class CLI(ApplicationABC):
:return: :return:
""" """
try: try:
self._configuration.parse_console_arguments(self._services) result = self._configuration.parse_console_arguments(self._services)
if result:
return
if len(self._configuration.additional_arguments) == 0:
Error.error('Expected command')
return
unexpected_arguments = ', '.join(self._configuration.additional_arguments)
Error.error(f'Unexpected argument(s): {unexpected_arguments}')
except KeyboardInterrupt: except KeyboardInterrupt:
Console.write_line() Console.write_line()
sys.exit() sys.exit()

View File

@ -46,7 +46,7 @@ class AddService(CommandABC):
}, indent=2)) }, indent=2))
file.close() file.close()
def run(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:

View File

@ -22,7 +22,7 @@ class BuildService(CommandABC):
Usage: cpl build Usage: cpl build
""") """)
def run(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:

View File

@ -22,7 +22,7 @@ class CustomScriptService(CommandABC):
def help_message(self) -> str: def help_message(self) -> str:
return '' return ''
def run(self, args: list[str]): def execute(self, args: list[str]):
cmd = self._config.get_configuration('ACTIVE_EXECUTABLE') cmd = self._config.get_configuration('ACTIVE_EXECUTABLE')
for script in self._workspace.scripts: for script in self._workspace.scripts:

View File

@ -169,7 +169,7 @@ class GenerateService(CommandABC):
spinner_foreground_color=ForegroundColorEnum.cyan spinner_foreground_color=ForegroundColorEnum.cyan
) )
def run(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:

View File

@ -24,7 +24,7 @@ class HelpService(CommandABC):
Usage: cpl help Usage: cpl help
""") """)
def run(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:

View File

@ -184,7 +184,7 @@ class InstallService(CommandABC):
Pip.reset_executable() Pip.reset_executable()
def run(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:

View File

@ -242,7 +242,7 @@ class NewService(CommandABC):
except Exception as e: except Exception as e:
Console.error('Could not create project', str(e)) Console.error('Could not create project', str(e))
def run(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:

View File

@ -22,7 +22,7 @@ class PublishService(CommandABC):
Usage: cpl publish Usage: cpl publish
""") """)
def run(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:

View File

@ -67,7 +67,7 @@ class RemoveService(CommandABC):
self._create_file(path, ws_dict) self._create_file(path, ws_dict)
def run(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:

View File

@ -22,7 +22,7 @@ class StartService(CommandABC):
Usage: cpl start Usage: cpl start
""") """)
def run(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:

View File

@ -49,7 +49,7 @@ class UninstallService(CommandABC):
def _wait(self, t: int, *args, source: str = None, stdout=None, stderr=None): def _wait(self, t: int, *args, source: str = None, stdout=None, stderr=None):
time.sleep(t) time.sleep(t)
def run(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:

View File

@ -156,7 +156,7 @@ class UpdateService(CommandABC):
project.write(json.dumps(config, indent=2)) project.write(json.dumps(config, indent=2))
project.close() project.close()
def run(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:

View File

@ -26,7 +26,7 @@ class VersionService(CommandABC):
Usage: cpl version Usage: cpl version
""") """)
def run(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:

View File

@ -1,10 +1,10 @@
from abc import abstractmethod, ABC from abc import abstractmethod, ABC
from cpl_core.configuration.executable_argument import ExecutableArgument from cpl_core.configuration.argument_executable_abc import ArgumentExecutableABC
from cpl_core.console import Console from cpl_core.console import Console
class CommandABC(ExecutableArgument): class CommandABC(ArgumentExecutableABC):
@abstractmethod @abstractmethod
def __init__(self): def __init__(self):
@ -14,12 +14,12 @@ class CommandABC(ExecutableArgument):
@abstractmethod @abstractmethod
def help_message(self) -> str: pass def help_message(self) -> str: pass
def execute(self, args: list[str]): @abstractmethod
def execute(self, args: list[str]): pass
def run(self, args: list[str]):
if 'help' in args: if 'help' in args:
Console.write_line(self.help_message) Console.write_line(self.help_message)
return return
self.run(args) self.execute(args)
@abstractmethod
def run(self, args: list[str]): pass

View File

@ -1,15 +1,52 @@
from cpl_cli.startup_argument_extension import StartupArgumentExtension from typing import Type
from cpl_core.application.application_builder import ApplicationBuilder
import pkg_resources
from cpl_cli.cli import CLI from cpl_cli.cli import CLI
from cpl_cli.startup import Startup from cpl_cli.startup import Startup
from cpl_cli.startup_argument_extension import StartupArgumentExtension
from cpl_core.application.application_builder import ApplicationBuilder
from cpl_core.application.startup_extension_abc import StartupExtensionABC
def get_startup_extensions() -> list[Type[StartupExtensionABC]]:
blacklisted_packages = ['cpl-cli']
startup_extensions = []
installed_packages = pkg_resources.working_set
for p in installed_packages:
package = str(p).split(' ')[0]
if not package.startswith('cpl-') or package in blacklisted_packages:
continue
package = package.replace('-', '_')
loaded_package = __import__(package)
if '__cli_startup_extension__' not in dir(loaded_package):
continue
startup_extensions.append(loaded_package.__cli_startup_extension__)
return startup_extensions
def main(): def main():
app_builder = ApplicationBuilder(CLI) app_builder = ApplicationBuilder(CLI)
app_builder.use_startup(Startup) app_builder.use_startup(Startup)
app_builder.use_extension(StartupArgumentExtension) app_builder.use_extension(StartupArgumentExtension)
for extension in get_startup_extensions():
app_builder.use_extension(extension)
app_builder.build().run() app_builder.build().run()
if __name__ == '__main__': if __name__ == '__main__':
main() main()
# ((
# ( `)
# ; / ,
# / \/
# / |
# / ~/
# / ) ) ~ edraft
# ___// | /
# `--' \_~-,

View File

@ -206,55 +206,57 @@ class PublisherService(PublisherABC):
:return: :return:
""" """
for file in self._included_files: for file in self._included_files:
if file.endswith('__init__.py'): if not file.endswith('__init__.py'):
template_content = '' continue
module_file_lines: list[str] = []
title = self._get_module_name_from_dirs(file) template_content = ''
if title == '': module_file_lines: list[str] = []
title = self._project_settings.name
module_py_lines: list[str] = [] title = self._get_module_name_from_dirs(file)
imports = '' if title == '':
title = self._project_settings.name
with open(file, 'r') as py_file: module_py_lines: list[str] = []
module_file_lines = py_file.readlines() imports = ''
py_file.close()
if len(module_file_lines) == 0: with open(file, 'r') as py_file:
imports = '# imports:' module_file_lines = py_file.readlines()
else: py_file.close()
is_started = False
for line in module_file_lines:
if line.__contains__('# imports'):
is_started = True
if (line.__contains__('from') or line.__contains__('import')) and is_started: if len(module_file_lines) == 0:
module_py_lines.append(line.replace('\n', '')) imports = '# imports:'
else:
is_started = False
for line in module_file_lines:
if line.__contains__('# imports'):
is_started = True
if len(module_py_lines) > 0: if ((line.__contains__('from') or line.__contains__('import')) and is_started) or line.startswith('__cli_startup_extension__'):
imports = '\n'.join(module_py_lines) module_py_lines.append(line.replace('\n', ''))
template_content = stringTemplate(InitTemplate.get_init_py()).substitute( if len(module_py_lines) > 0:
Name=self._project_settings.name, imports = '\n'.join(module_py_lines)
Description=self._project_settings.description,
LongDescription=self._project_settings.long_description,
CopyrightDate=self._project_settings.copyright_date,
CopyrightName=self._project_settings.copyright_name,
LicenseName=self._project_settings.license_name,
LicenseDescription=self._project_settings.license_description,
Title=title if title is not None and title != '' else self._project_settings.name,
Author=self._project_settings.author,
Version=version.parse(self._project_settings.version.to_str()),
Major=self._project_settings.version.major,
Minor=self._project_settings.version.minor,
Micro=self._project_settings.version.micro,
Imports=imports
)
with open(file, 'w+') as py_file: template_content = stringTemplate(InitTemplate.get_init_py()).substitute(
py_file.write(template_content) Name=self._project_settings.name,
py_file.close() Description=self._project_settings.description,
LongDescription=self._project_settings.long_description,
CopyrightDate=self._project_settings.copyright_date,
CopyrightName=self._project_settings.copyright_name,
LicenseName=self._project_settings.license_name,
LicenseDescription=self._project_settings.license_description,
Title=title if title is not None and title != '' else self._project_settings.name,
Author=self._project_settings.author,
Version=version.parse(self._project_settings.version.to_str()),
Major=self._project_settings.version.major,
Minor=self._project_settings.version.minor,
Micro=self._project_settings.version.micro,
Imports=imports
)
with open(file, 'w+') as py_file:
py_file.write(template_content)
py_file.close()
def _dist_files(self): def _dist_files(self):
""" """

View File

@ -7,4 +7,4 @@ class ArgumentExecutableABC(ABC):
def __init__(self): pass def __init__(self): pass
@abstractmethod @abstractmethod
def run(self, args: list[str]): pass def execute(self, args: list[str]): pass

View File

@ -274,18 +274,19 @@ class Configuration(ConfigurationABC):
if config_model == search_type: if config_model == search_type:
return self._config[config_model] return self._config[config_model]
def parse_console_arguments(self, services: ServiceProviderABC, error: bool = None): def parse_console_arguments(self, services: ServiceProviderABC, error: bool = None) -> bool:
# sets environment variables as possible arguments as: --VAR=VALUE # sets environment variables as possible arguments as: --VAR=VALUE
for arg_name in ConfigurationVariableNameEnum.to_list(): for arg_name in ConfigurationVariableNameEnum.to_list():
self.add_console_argument(VariableArgument('--', str(arg_name).upper(), [str(arg_name).lower()], '=')) self.add_console_argument(VariableArgument('--', str(arg_name).upper(), [str(arg_name).lower()], '='))
success = False
try: try:
arg_list = sys.argv[1:] arg_list = sys.argv[1:]
executables: list[ExecutableArgument] = [] executables: list[ExecutableArgument] = []
self._parse_arguments(executables, arg_list, self._argument_types) self._parse_arguments(executables, arg_list, self._argument_types)
except Exception as e: except Exception as e:
Console.error('An error occurred while parsing arguments.') Console.error('An error occurred while parsing arguments.')
exit() sys.exit()
try: try:
prevent = False prevent = False
@ -309,5 +310,9 @@ class Configuration(ConfigurationABC):
self.add_configuration('ACTIVE_EXECUTABLE', exe.name) self.add_configuration('ACTIVE_EXECUTABLE', exe.name)
cmd.execute(self._additional_arguments) cmd.execute(self._additional_arguments)
prevent = exe.prevent_next_executable prevent = exe.prevent_next_executable
success = True
except Exception as e: except Exception as e:
Console.error('An error occurred while executing arguments.') Console.error('An error occurred while executing arguments.')
sys.exit()
return success

View File

@ -141,12 +141,16 @@ class ConfigurationABC(ABC):
pass pass
@abstractmethod @abstractmethod
def parse_console_arguments(self, services: 'ServiceProviderABC', error: bool = None): def parse_console_arguments(self, services: 'ServiceProviderABC', error: bool = None) -> bool:
r"""Reads the console arguments r"""Reads the console arguments
Parameter Parameter
--------- ---------
error: :class:`bool` error: :class:`bool`
Defines is invalid argument error will be shown or not Defines is invalid argument error will be shown or not
Returns
-------
Bool to specify if executables were executed or not.
""" """
pass pass

View File

@ -3,7 +3,6 @@ from typing import Type, Optional
from cpl_core.configuration.argument_executable_abc import ArgumentExecutableABC from cpl_core.configuration.argument_executable_abc import ArgumentExecutableABC
from cpl_core.configuration.argument_abc import ArgumentABC from cpl_core.configuration.argument_abc import ArgumentABC
from cpl_core.configuration.validator_abc import ValidatorABC from cpl_core.configuration.validator_abc import ValidatorABC
from cpl_core.console import Console
class ExecutableArgument(ArgumentABC): class ExecutableArgument(ArgumentABC):
@ -40,4 +39,4 @@ class ExecutableArgument(ArgumentABC):
""" """
if self._executable is None: if self._executable is None:
return return
self._executable.run(args) self._executable.execute(args)

View File

@ -11,6 +11,6 @@ class GenerateArgument(ArgumentExecutableABC):
self._config = config self._config = config
self._env = env self._env = env
def run(self, args: list[str]): def execute(self, args: list[str]):
Console.error('Generate:') Console.error('Generate:')
Console.write_line(args, self._env.environment_name) Console.write_line(args, self._env.environment_name)

View File

@ -7,5 +7,5 @@ class InstallArgument(ArgumentExecutableABC):
def __init__(self): def __init__(self):
ArgumentExecutableABC.__init__(self) ArgumentExecutableABC.__init__(self)
def run(self, args: list[str]): def execute(self, args: list[str]):
Console.write_line('Install:', args) Console.write_line('Install:', args)