more working

This commit is contained in:
2025-03-31 23:53:49 +03:00
parent 5c6fa5151a
commit cc8135b733
11 changed files with 103 additions and 104 deletions
+7 -8
View File
@@ -56,14 +56,14 @@ if __name__ == '__main__':
import re
from argenta.router import Router
from argenta.command import Command
from argenta.command.flag.registered_flag import Flags, Flag
from argenta.command.flag import Flags, Flag, InputFlags
router = Router()
registered_flags = Flags(
Flag(flag_name='host',
flag_prefix='--',
possible_flag_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')),
Flag(name='host',
prefix='--',
possible_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')),
Flag('port', '--', re.compile(r'^[0-9]{1,4}$')))
@@ -75,10 +75,10 @@ def handler():
@router.command(Command(trigger="ssh",
description='connect via ssh',
flags=registered_flags))
def handler_with_flags(flags: dict):
def handler_with_flags(flags: InputFlags):
for flag in flags:
print(f'Flag name: {flag['name']}\n'
f'Flag value: {flag['value']}')
print(f'Flag name: {flag.get_name()}\n'
f'Flag value: {flag.get_value()}')
```
---
@@ -299,7 +299,6 @@ Router(title: str = 'Commands group title:',
---
### Исключения
- `RepeatedCommandException` - Одна и та же команда зарегистрирована в одном роутере
- `RepeatedFlagNameException` - Повторяющиеся зарегистрированные флаги в команде
- `TooManyTransferredArgsException` - Слишком много зарегистрированных аргументов у обработчика команды
- `RequiredArgumentNotPassedException` - Не зарегистрирован обязательный аргумент у обработчика команды(аргумент, через который будут переданы флаги введённой команды)
+23 -22
View File
@@ -52,7 +52,7 @@ class App:
self._invalid_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'Incorrect flag syntax: "{raw_command}"')
self._repeated_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'Repeated input flags: "{raw_command}"')
self._empty_input_command_handler: Callable[[], None] = lambda: print_func('Empty input command')
self._unknown_command_handler: Callable[[Command], None] = lambda command: print_func(f"Unknown command: {command.get_trigger()}")
self._unknown_command_handler: Callable[[InputCommand], None] = lambda command: print_func(f"Unknown command: {command.get_trigger()}")
self._exit_command_handler: Callable[[], None] = lambda: print_func(self.farewell_message)
@@ -78,28 +78,12 @@ class App:
raw_command: str = input()
try:
input_command: InputCommand = InputCommand.parse_input_command(raw_command=raw_command)
except UnprocessedInputFlagException:
input_command: InputCommand = InputCommand.parse(raw_command=raw_command)
except (UnprocessedInputFlagException,
RepeatedInputFlagsException,
EmptyInputCommandException) as error:
self.print_func(self.line_separate)
self._invalid_input_flags_handler(raw_command)
self.print_func(self.line_separate)
if not self.repeat_command_groups:
self.print_func(self.prompt)
continue
except RepeatedInputFlagsException:
self.print_func(self.line_separate)
self._repeated_input_flags_handler(raw_command)
self.print_func(self.line_separate)
if not self.repeat_command_groups:
self.print_func(self.prompt)
continue
except EmptyInputCommandException:
self.print_func(self.line_separate)
self._empty_input_command_handler()
self._error_handler(error, raw_command)
self.print_func(self.line_separate)
if not self.repeat_command_groups:
@@ -203,6 +187,7 @@ class App:
for router in routers:
self.include_router(router)
def _validate_number_of_routers(self) -> None:
if not self._registered_routers:
raise NoRegisteredRoutersException()
@@ -259,3 +244,19 @@ class App:
)
)
self.print_func(self.command_group_description_separate)
def _error_handler(self,
error: UnprocessedInputFlagException |
RepeatedInputFlagsException |
EmptyInputCommandException,
raw_command: str) -> None:
match error:
case UnprocessedInputFlagException():
self._invalid_input_flags_handler(raw_command)
case RepeatedInputFlagsException():
self._repeated_input_flags_handler(raw_command)
case EmptyInputCommandException():
self._empty_input_command_handler()
+4
View File
@@ -0,0 +1,4 @@
__all__ = ('InputFlags', 'InputFlag', 'Flag', 'Flags')
from .models import InputFlags, InputFlag, Flags, Flag
+1 -1
View File
@@ -4,7 +4,7 @@ import re
@dataclass
class DefaultFlags:
class PredeterminedFlags:
HELP = Flag(name='help', possible_values=False)
SHORT_HELP = Flag(name='h', prefix='-', possible_values=False)
+16 -9
View File
@@ -4,11 +4,9 @@ from abc import ABC, abstractmethod
class BaseFlag:
def __init__(self, name: str,
prefix: Literal['-', '--', '---'] = '--',
possible_values: list[str] | Pattern[str] | False = True):
prefix: Literal['-', '--', '---'] = '--'):
self._name = name
self._prefix = prefix
self.possible_values = possible_values
def get_string_entity(self):
string_entity: str = self._prefix + self._name
@@ -25,9 +23,9 @@ class BaseFlag:
class InputFlag(BaseFlag):
def __init__(self, name: str,
prefix: Literal['-', '--', '---'] = '--',
possible_values: list[str] | Pattern[str] | False = True):
super().__init__(name, prefix, possible_values)
self._flag_value = None
value: str = None):
super().__init__(name, prefix)
self._flag_value = value
def get_value(self):
return self._flag_value
@@ -38,6 +36,12 @@ class InputFlag(BaseFlag):
class Flag(BaseFlag):
def __init__(self, name: str,
prefix: Literal['-', '--', '---'] = '--',
possible_values: list[str] | Pattern[str] | False = True):
super().__init__(name, prefix)
self.possible_values = possible_values
def validate_input_flag_value(self, input_flag_value: str | None):
if self.possible_values is False:
if input_flag_value is None:
@@ -45,9 +49,12 @@ class Flag(BaseFlag):
else:
return False
elif isinstance(self.possible_values, Pattern):
is_valid = bool(self.possible_values.match(input_flag_value))
if bool(is_valid):
return True
if isinstance(input_flag_value, str):
is_valid = bool(self.possible_values.match(input_flag_value))
if bool(is_valid):
return True
else:
return False
else:
return False
+31 -43
View File
@@ -5,30 +5,24 @@ from argenta.command.exceptions import (UnprocessedInputFlagException,
from typing import Generic, TypeVar, cast, Literal
BaseCommandType = TypeVar('BaseCommandType')
InputCommandType = TypeVar('InputCommandType')
class BaseCommand(Generic[BaseCommandType]):
def __init__(self, trigger: str,
description: str = None,
flags: Flag | Flags = None):
class BaseCommand:
def __init__(self, trigger: str):
self._trigger = trigger
self._description = f'description for "{self._trigger}" command' if not description else description
def get_trigger(self) -> str:
return self._trigger
def get_description(self) -> str:
return self._description
class Command(BaseCommand):
def __init__(self, trigger: str,
description: str = None,
flags: Flag | Flags = None):
super().__init__(trigger, description)
super().__init__(trigger)
self._registered_flags: Flags = flags if isinstance(flags, Flags) else Flags(flags) if isinstance(flags, Flag) else Flags()
self._description = f'description for "{self._trigger}" command' if not description else description
def get_registered_flags(self) -> Flags:
return self._registered_flags
@@ -49,13 +43,15 @@ class Command(BaseCommand):
return True
return False
def get_description(self) -> str:
return self._description
class InputCommand(BaseCommand):
class InputCommand(BaseCommand, Generic[InputCommandType]):
def __init__(self, trigger: str,
description: str = None,
input_flags: InputFlag | InputFlags = None):
super().__init__(trigger, description)
super().__init__(trigger)
self._input_flags: InputFlags = input_flags if isinstance(input_flags, InputFlags) else InputFlags(input_flags) if isinstance(input_flags, InputFlag) else InputFlags()
def _set_input_flags(self, input_flags: InputFlags):
@@ -65,53 +61,45 @@ class InputCommand(BaseCommand):
return self._input_flags
@staticmethod
def parse_input_command(raw_command: str) -> BaseCommandType:
def parse(raw_command: str) -> InputCommandType:
if not raw_command:
raise EmptyInputCommandException()
list_of_tokens = raw_command.split()
command = list_of_tokens[0]
list_of_tokens.pop(0)
command = list_of_tokens.pop(0)
input_flags: InputFlags = InputFlags()
current_flag_name = None
current_flag_value = None
current_flag_name, current_flag_value = None, None
for k, _ in enumerate(list_of_tokens):
if _.startswith('-'):
flag_prefix_last_symbol_index = _.rfind('-')
if current_flag_name or len(_) < 2 or len(_[:flag_prefix_last_symbol_index]) > 3:
if current_flag_name or len(_) < 2 or len(_[:_.rfind('-')]) > 3:
raise UnprocessedInputFlagException()
else:
current_flag_name = _
current_flag_name = _
else:
if not current_flag_name:
raise UnprocessedInputFlagException()
else:
current_flag_value = _
if current_flag_name:
if not len(list_of_tokens) == k + 1:
if not list_of_tokens[k + 1].startswith('-'):
continue
flag_prefix_last_symbol_index = current_flag_name.rfind('-')
flag_prefix = current_flag_name[:flag_prefix_last_symbol_index + 1]
flag_name = current_flag_name[flag_prefix_last_symbol_index + 1:]
input_flag = InputFlag(name=flag_name,
prefix=cast(Literal['-', '--', '---'], flag_prefix))
input_flag.set_value(current_flag_value)
current_flag_value = _
all_flags = [x.get_string_entity() for x in input_flags.get_flags()]
if current_flag_name:
if not len(list_of_tokens) == k+1:
if not list_of_tokens[k+1].startswith('-'): continue
input_flag = InputFlag(name=current_flag_name[current_flag_name.rfind('-')+1:],
prefix=cast(Literal['-', '--', '---'],
current_flag_name[:current_flag_name.rfind('-')+1]),
value=current_flag_value)
all_flags = [flag.get_string_entity() for flag in input_flags.get_flags()]
if input_flag.get_string_entity() not in all_flags:
input_flags.add_flag(input_flag)
else:
raise RepeatedInputFlagsException(input_flag)
current_flag_name = None
current_flag_value = None
current_flag_name, current_flag_value = None, None
if any([current_flag_name, current_flag_value]):
raise UnprocessedInputFlagException()
if len(input_flags.get_flags()) == 0:
return InputCommand(trigger=command)
else:
input_command = InputCommand(trigger=command)
input_command._set_input_flags(input_flags)
return input_command
return InputCommand(trigger=command, input_flags=input_flags)
+4 -4
View File
@@ -2,8 +2,8 @@ from pprint import pprint
from rich.console import Console
from argenta.command import Command
from argenta.command.flag.models import Flags, InputFlags
from argenta.command.flag.defaults import DefaultFlags
from argenta.command.flag import Flags, InputFlags, Flag
from argenta.command.flag.defaults import PredeterminedFlags
from argenta.router import Router
from .handlers_implementation.help_command import help_command
@@ -22,10 +22,10 @@ def command_help():
help_command()
@work_router.command(Command(trigger='P', description='Start Solving', flags=Flags(DefaultFlags.HOST, DefaultFlags.PORT)))
@work_router.command(Command(trigger='P', description='Start Solving', flags=Flags(PredeterminedFlags.HOST, PredeterminedFlags.PORT)))
def command_start_solving(args: InputFlags):
print('Solving...')
pprint(args)
pprint(args.get_flag('host'))
#start_solving_command()
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "argenta"
version = "0.4.1"
version = "0.4.5"
description = "python library for creating custom shells"
authors = [
{name = "kolo", email = "kolo.is.main@gmail.com"}
@@ -7,8 +7,8 @@ import re
from argenta.app import App
from argenta.command import Command
from argenta.router import Router
from argenta.command.flag.models import Flags
from argenta.command.flag.defaults import DefaultFlags
from argenta.command.flag.models import Flags, InputFlags
from argenta.command.flag.defaults import PredeterminedFlags
@@ -89,11 +89,11 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
@patch("sys.stdout", new_callable=io.StringIO)
def test_input_correct_command_with_one_correct_flag_an_one_incorrect_flag(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
router = Router()
flags = Flags(DefaultFlags.HOST)
flags = Flags(PredeterminedFlags.HOST)
@router.command(Command('test', flags=flags))
def test(args: dict):
print(f'connecting to host {args["host"]["value"]}')
def test(args: InputFlags):
print(f'connecting to host {args.get_flag('host').get_value()}')
app = App()
app.include_router(router)
@@ -185,8 +185,8 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
def test_input_correct_command_with_repeated_flags(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
router = Router()
@router.command(Command('test', flags=DefaultFlags.PORT))
def test(args):
@router.command(Command('test', flags=PredeterminedFlags.PORT))
def test(args: InputFlags):
print('test command')
app = App()
@@ -8,7 +8,7 @@ from argenta.app import App
from argenta.command.models import Command
from argenta.router import Router
from argenta.command.flag.models import Flag, Flags, InputFlags
from argenta.command.flag.defaults import DefaultFlags
from argenta.command.flag.defaults import PredeterminedFlags
@@ -90,7 +90,7 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
@patch("sys.stdout", new_callable=io.StringIO)
def test_input_correct_command_with_default_flag(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
router = Router()
flag = DefaultFlags.SHORT_HELP
flag = PredeterminedFlags.SHORT_HELP
@router.command(Command('test', flags=flag))
def test(args: dict):
@@ -109,7 +109,7 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
@patch("sys.stdout", new_callable=io.StringIO)
def test_input_correct_command_with_default_flag2(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
router = Router()
flag = DefaultFlags.INFO
flag = PredeterminedFlags.INFO
@router.command(Command('test', flags=flag))
def test(args: InputFlags):
@@ -129,7 +129,7 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
@patch("sys.stdout", new_callable=io.StringIO)
def test_input_correct_command_with_default_flag3(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
router = Router()
flag = DefaultFlags.HOST
flag = PredeterminedFlags.HOST
@router.command(Command('test', flags=flag))
def test(args: InputFlags):
@@ -148,7 +148,7 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
@patch("sys.stdout", new_callable=io.StringIO)
def test_input_correct_command_with_two_flags(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
router = Router()
flags = Flags(DefaultFlags.HOST, DefaultFlags.PORT)
flags = Flags(PredeterminedFlags.HOST, PredeterminedFlags.PORT)
@router.command(Command('test', flags=flags))
def test(args: InputFlags):
+4 -4
View File
@@ -8,17 +8,17 @@ import unittest
class TestInputCommand(unittest.TestCase):
def test_parse_correct_raw_command(self):
self.assertEqual(InputCommand.parse_input_command('ssh --host 192.168.0.3').get_trigger(), 'ssh')
self.assertEqual(InputCommand.parse('ssh --host 192.168.0.3').get_trigger(), 'ssh')
def test_parse_raw_command_without_flag_name_with_value(self):
with self.assertRaises(UnprocessedInputFlagException):
InputCommand.parse_input_command('ssh 192.168.0.3')
InputCommand.parse('ssh 192.168.0.3')
def test_parse_raw_command_with_repeated_flag_name(self):
with self.assertRaises(RepeatedInputFlagsException):
InputCommand.parse_input_command('ssh --host 192.168.0.3 --host 172.198.0.43')
InputCommand.parse('ssh --host 192.168.0.3 --host 172.198.0.43')
def test_parse_empty_raw_command(self):
with self.assertRaises(EmptyInputCommandException):
InputCommand.parse_input_command('')
InputCommand.parse('')