Added validators (closes #59)

This commit is contained in:
Sven Heidemann 2022-05-20 10:27:55 +02:00
parent ccca904cb8
commit dac3d9c6bb
9 changed files with 119 additions and 25 deletions

View File

@ -1,7 +1,6 @@
import os import os
from typing import Optional from typing import Optional
from cpl_cli import CommandABC
from cpl_cli.command.add_service import AddService from cpl_cli.command.add_service import AddService
from cpl_cli.command.build_service import BuildService from cpl_cli.command.build_service import BuildService
from cpl_cli.command.custom_script_service import CustomScriptService from cpl_cli.command.custom_script_service import CustomScriptService
@ -16,6 +15,8 @@ from cpl_cli.command.uninstall_service import UninstallService
from cpl_cli.command.update_service import UpdateService from cpl_cli.command.update_service import UpdateService
from cpl_cli.command.version_service import VersionService from cpl_cli.command.version_service import VersionService
from cpl_cli.configuration.workspace_settings import WorkspaceSettings from cpl_cli.configuration.workspace_settings import WorkspaceSettings
from cpl_cli.validators.project_validator import ProjectValidator
from cpl_cli.validators.workspace_validator import WorkspaceValidator
from cpl_core.application import StartupExtensionABC from cpl_core.application import StartupExtensionABC
from cpl_core.configuration.argument_type_enum import ArgumentTypeEnum from cpl_core.configuration.argument_type_enum import ArgumentTypeEnum
from cpl_core.configuration.configuration_abc import ConfigurationABC from cpl_core.configuration.configuration_abc import ConfigurationABC
@ -37,9 +38,7 @@ class StartupArgumentExtension(StartupExtensionABC):
for file in f: for file in f:
if file.endswith('.json'): if file.endswith('.json'):
f_name = file.split('.json')[0] f_name = file.split('.json')[0]
if f_name == name or \ if f_name == name or String.convert_to_camel_case(f_name).lower() == String.convert_to_camel_case(name).lower():
String.convert_to_camel_case(f_name).lower() == String.convert_to_camel_case(
name).lower():
project_name = f_name project_name = f_name
break break
@ -62,7 +61,7 @@ class StartupArgumentExtension(StartupExtensionABC):
config.create_console_argument(ArgumentTypeEnum.Executable, '', 'add', ['a', 'A'], AddService, True) \ config.create_console_argument(ArgumentTypeEnum.Executable, '', 'add', ['a', 'A'], AddService, True) \
.add_console_argument(ArgumentTypeEnum.Flag, '--', 'simulate', ['s', 'S']) .add_console_argument(ArgumentTypeEnum.Flag, '--', 'simulate', ['s', 'S'])
config.create_console_argument(ArgumentTypeEnum.Executable, '', 'build', ['b', 'B'], BuildService, True) config.create_console_argument(ArgumentTypeEnum.Executable, '', 'build', ['b', 'B'], BuildService, True, validators=[ProjectValidator])
config.create_console_argument(ArgumentTypeEnum.Executable, '', 'generate', ['g', 'G'], GenerateService, True) \ config.create_console_argument(ArgumentTypeEnum.Executable, '', 'generate', ['g', 'G'], GenerateService, True) \
.add_console_argument(ArgumentTypeEnum.Variable, '', 'abc', ['a', 'A'], ' ') \ .add_console_argument(ArgumentTypeEnum.Variable, '', 'abc', ['a', 'A'], ' ') \
.add_console_argument(ArgumentTypeEnum.Variable, '', 'class', ['c', 'C'], ' ') \ .add_console_argument(ArgumentTypeEnum.Variable, '', 'class', ['c', 'C'], ' ') \
@ -87,24 +86,25 @@ class StartupArgumentExtension(StartupExtensionABC):
.add_console_argument(ArgumentTypeEnum.Flag, '--', 'simulate', ['s', 'S']) .add_console_argument(ArgumentTypeEnum.Flag, '--', 'simulate', ['s', 'S'])
config.create_console_argument(ArgumentTypeEnum.Executable, '', 'version', ['v', 'V'], VersionService, True) config.create_console_argument(ArgumentTypeEnum.Executable, '', 'version', ['v', 'V'], VersionService, True)
config.for_each_argument( config.for_each_argument(lambda a: a.add_console_argument(ArgumentTypeEnum.Flag, '--', 'help', ['h', 'H']))
lambda a: a.add_console_argument(ArgumentTypeEnum.Flag, '--', 'help', ['h', 'H'])
)
config.create_console_argument(ArgumentTypeEnum.Executable, '', 'help', ['h', 'H'], HelpService) config.create_console_argument(ArgumentTypeEnum.Executable, '', 'help', ['h', 'H'], HelpService)
self._read_cpl_environment(config, env) self._read_cpl_environment(config, env)
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
services.add_transient(CommandABC, AddService) services.add_transient(WorkspaceValidator)
services.add_transient(CommandABC, BuildService) services.add_transient(ProjectValidator)
services.add_transient(CommandABC, CustomScriptService)
services.add_transient(CommandABC, GenerateService) services.add_transient(AddService)
services.add_transient(CommandABC, HelpService) services.add_transient(BuildService)
services.add_transient(CommandABC, InstallService) services.add_transient(CustomScriptService)
services.add_transient(CommandABC, NewService) services.add_transient(GenerateService)
services.add_transient(CommandABC, PublishService) services.add_transient(HelpService)
services.add_transient(CommandABC, RemoveService) services.add_transient(InstallService)
services.add_transient(CommandABC, StartService) services.add_transient(NewService)
services.add_transient(CommandABC, UninstallService) services.add_transient(PublishService)
services.add_transient(CommandABC, UpdateService) services.add_transient(RemoveService)
services.add_transient(CommandABC, VersionService) services.add_transient(StartService)
services.add_transient(UninstallService)
services.add_transient(UpdateService)
services.add_transient(VersionService)

View File

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
"""
cpl-cli sh-edraft Common Python library CLI
~~~~~~~~~~~~~~~~~~~
sh-edraft Common Python library Command Line Interface
:copyright: (c) 2020 - 2022 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'cpl_cli.validators'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.6.3.dev6'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='6', micro='3.dev6')

View File

@ -0,0 +1,18 @@
from cpl_cli import Error
from cpl_cli.configuration import WorkspaceSettings, ProjectSettings
from cpl_core.configuration.validator_abc import ValidatorABC
class ProjectValidator(ValidatorABC):
def __init__(self, workspace: WorkspaceSettings, project: ProjectSettings):
self._workspace = workspace
self._project = project
ValidatorABC.__init__(self)
def validate(self) -> bool:
result = self._project is not None or self._workspace is not None
if not result:
Error.error('The command requires to be run in an CPL project, but a project could not be found.')
return result

View File

@ -0,0 +1,17 @@
from cpl_cli import Error
from cpl_cli.configuration import WorkspaceSettings
from cpl_core.configuration.validator_abc import ValidatorABC
class WorkspaceValidator(ValidatorABC):
def __init__(self, workspace: WorkspaceSettings):
self._workspace = workspace
ValidatorABC.__init__(self)
def validate(self) -> bool:
result = self._workspace is not None
if not result:
Error.error('The command requires to be run in an CPL workspace, but a workspace could not be found.')
return result

View File

@ -13,6 +13,7 @@ from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
from cpl_core.configuration.configuration_variable_name_enum import ConfigurationVariableNameEnum from cpl_core.configuration.configuration_variable_name_enum import ConfigurationVariableNameEnum
from cpl_core.configuration.executable_argument import ExecutableArgument from cpl_core.configuration.executable_argument import ExecutableArgument
from cpl_core.configuration.flag_argument import FlagArgument from cpl_core.configuration.flag_argument import FlagArgument
from cpl_core.configuration.validator_abc import ValidatorABC
from cpl_core.configuration.variable_argument import VariableArgument from cpl_core.configuration.variable_argument import VariableArgument
from cpl_core.console.console import Console from cpl_core.console.console import Console
from cpl_core.console.foreground_color_enum import ForegroundColorEnum from cpl_core.console.foreground_color_enum import ForegroundColorEnum
@ -245,7 +246,7 @@ class Configuration(ConfigurationABC):
def create_console_argument(self, arg_type: ArgumentTypeEnum, token: str, name: str, aliases: list[str], def create_console_argument(self, arg_type: ArgumentTypeEnum, token: str, name: str, aliases: list[str],
*args, **kwargs) -> ArgumentABC: *args, **kwargs) -> ArgumentABC:
argument = ArgumentBuilder.build_argument(arg_type, token, name, aliases, *args, *kwargs) argument = ArgumentBuilder.build_argument(arg_type, token, name, aliases, *args, **kwargs)
self._argument_types.append(argument) self._argument_types.append(argument)
return argument return argument
@ -285,6 +286,18 @@ class Configuration(ConfigurationABC):
for exe in executables: for exe in executables:
if prevent: if prevent:
continue continue
abort = False
for validator_type in exe.validators:
validator: ValidatorABC = services.get_service(validator_type)
result = validator.validate()
abort = not result
if abort:
break
if abort:
continue
cmd: CommandABC = services.get_service(exe.executable_type) cmd: CommandABC = services.get_service(exe.executable_type)
self.add_configuration('ACTIVE_EXECUTABLE', exe.name) self.add_configuration('ACTIVE_EXECUTABLE', exe.name)
cmd.execute(self._additional_arguments) cmd.execute(self._additional_arguments)

View File

@ -2,6 +2,8 @@ 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.console import Console
class ExecutableArgument(ArgumentABC): class ExecutableArgument(ArgumentABC):
@ -11,13 +13,16 @@ class ExecutableArgument(ArgumentABC):
name: str, name: str,
aliases: list[str], aliases: list[str],
executable: Type[ArgumentExecutableABC], executable: Type[ArgumentExecutableABC],
prevent_next_executable: bool = False,
validators: list[Type[ValidatorABC]] = None,
console_arguments: list['ArgumentABC'] = None console_arguments: list['ArgumentABC'] = None
): ):
self._executable_type = executable self._executable_type = executable
self._validators = validators
self._executable: Optional[ArgumentExecutableABC] = None self._executable: Optional[ArgumentExecutableABC] = None
ArgumentABC.__init__(self, token, name, aliases, console_arguments) ArgumentABC.__init__(self, token, name, aliases, prevent_next_executable, console_arguments)
@property @property
def executable_type(self) -> type: def executable_type(self) -> type:
@ -26,6 +31,10 @@ class ExecutableArgument(ArgumentABC):
def set_executable(self, executable: ArgumentExecutableABC): def set_executable(self, executable: ArgumentExecutableABC):
self._executable = executable self._executable = executable
@property
def validators(self) -> list[Type[ValidatorABC]]:
return self._validators
def run(self, args: list[str]): def run(self, args: list[str]):
r"""Executes runnable if exists r"""Executes runnable if exists
""" """

View File

@ -7,7 +7,8 @@ class FlagArgument(ArgumentABC):
token: str, token: str,
name: str, name: str,
aliases: list[str], aliases: list[str],
prevent_next_executable: bool = False,
console_arguments: list['ArgumentABC'] = None console_arguments: list['ArgumentABC'] = None
): ):
ArgumentABC.__init__(self, token, name, aliases, console_arguments) ArgumentABC.__init__(self, token, name, aliases, prevent_next_executable, console_arguments)

View File

@ -0,0 +1,10 @@
from abc import ABC, abstractmethod
class ValidatorABC(ABC):
@abstractmethod
def __init__(self): pass
@abstractmethod
def validate(self) -> bool: pass

View File

@ -8,12 +8,13 @@ class VariableArgument(ArgumentABC):
name: str, name: str,
aliases: list[str], aliases: list[str],
value_token: str, value_token: str,
prevent_next_executable: bool = False,
console_arguments: list['ArgumentABC'] = None console_arguments: list['ArgumentABC'] = None
): ):
self._value_token = value_token self._value_token = value_token
self._value: str = '' self._value: str = ''
ArgumentABC.__init__(self, token, name, aliases, console_arguments) ArgumentABC.__init__(self, token, name, aliases, prevent_next_executable, console_arguments)
@property @property
def value_token(self) -> str: def value_token(self) -> str: