diff --git a/src/sh_edraft/cli/command/base/command_base.py b/src/sh_edraft/cli/command/base/command_base.py index bc63204b..89bb476a 100644 --- a/src/sh_edraft/cli/command/base/command_base.py +++ b/src/sh_edraft/cli/command/base/command_base.py @@ -1,5 +1,7 @@ from abc import ABC, abstractmethod +from sh_edraft.console.console import Console + class CommandBase(ABC): diff --git a/src/sh_edraft/cli/cpl_cli/cli.py b/src/sh_edraft/cli/cpl_cli/cli.py index b5d24415..d74f807b 100644 --- a/src/sh_edraft/cli/cpl_cli/cli.py +++ b/src/sh_edraft/cli/cpl_cli/cli.py @@ -1,8 +1,11 @@ import sys +import traceback from sh_edraft.cli.cpl_cli.commands.help import Help from sh_edraft.cli.cpl_cli.commands.new import New +from sh_edraft.cli.cpl_cli.commands.version import Version from sh_edraft.cli.interpreter.interpreter import Interpreter +from sh_edraft.console.console import Console class CLI: @@ -13,14 +16,15 @@ class CLI: def setup(self): self._interpreter.add_command(New()) self._interpreter.add_command(Help()) + self._interpreter.add_command(Version()) def main(self): - print('CPL CLI:') string = ' '.join(sys.argv[1:]) try: self._interpreter.interpret(string) except Exception as e: - print(e) + tb = traceback.format_exc() + Console.error(str(e), tb) def main(): diff --git a/src/sh_edraft/cli/cpl_cli/commands/help.py b/src/sh_edraft/cli/cpl_cli/commands/help.py index 3a723f14..21885eb1 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/help.py +++ b/src/sh_edraft/cli/cpl_cli/commands/help.py @@ -1,4 +1,5 @@ from sh_edraft.cli.command.base.command_base import CommandBase +from sh_edraft.console.console import Console class Help(CommandBase): @@ -7,4 +8,4 @@ class Help(CommandBase): CommandBase.__init__(self) def run(self, args: list[str]): - print('Commands:') + Console.write_line('Available Commands:') diff --git a/src/sh_edraft/cli/cpl_cli/commands/new.py b/src/sh_edraft/cli/cpl_cli/commands/new.py index 697d43c9..c9d63353 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/new.py +++ b/src/sh_edraft/cli/cpl_cli/commands/new.py @@ -1,6 +1,7 @@ import os from sh_edraft.cli.command.base.command_base import CommandBase +from sh_edraft.console.console import Console class New(CommandBase): @@ -10,13 +11,21 @@ class New(CommandBase): def run(self, args: list[str]): rel_path = f'{os.path.dirname(__file__)}/../' + if len(args) == 0: + Console.error(f'Expected arguments {args}') + return + + elif len(args) != 2: + Console.error(f'Invalid arguments {args}') + return + if not os.path.isdir(f'{rel_path}/templates/{args[0]}'): - print(f'Unexpected argument {args[0]}') + Console.error(f'Unexpected argument {args[0]}') sub_args = args[1:] if len(sub_args) != 1: - print(f'Unexpected argument {sub_args[1]}') + Console.error(f'Unexpected argument {sub_args[1]}') if not (sub_args[0].startswith('.') or sub_args[0].startswith('/')): full_path = f'./{sub_args[0]}' diff --git a/src/sh_edraft/cli/cpl_cli/commands/version.py b/src/sh_edraft/cli/cpl_cli/commands/version.py new file mode 100644 index 00000000..0f7a4a47 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/commands/version.py @@ -0,0 +1,30 @@ +import pkgutil +import sys +import platform + +import sh_edraft +from sh_edraft import cli +from sh_edraft.cli.command.base.command_base import CommandBase +from sh_edraft.console.console import Console + + +class Version(CommandBase): + + def __init__(self): + CommandBase.__init__(self) + + def run(self, args: list[str]): + Console.set_foreground_color('yellow') + Console.banner('CPL CLI') + Console.set_foreground_color('default') + Console.write_line(f'Common Python Library CLI: {cli.__version__}') + Console.write_line(f'Python: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}') + Console.write_line(f'OS: {platform.system()} {platform.processor()}') + + Console.write_line('\nCPL:') + packages = [] + for importer, modname, is_pkg in pkgutil.iter_modules(sh_edraft.__path__): + module = importer.find_module(modname).load_module(modname) + packages.append([f'{modname}:', module.__version__]) + + Console.table(['Name', 'Version'], packages) diff --git a/src/sh_edraft/cli/interpreter/interpreter.py b/src/sh_edraft/cli/interpreter/interpreter.py index 7ee549ed..5a7f38d8 100644 --- a/src/sh_edraft/cli/interpreter/interpreter.py +++ b/src/sh_edraft/cli/interpreter/interpreter.py @@ -1,4 +1,5 @@ from sh_edraft.cli.command.base.command_base import CommandBase +from sh_edraft.console.console import Console class Interpreter: @@ -16,13 +17,12 @@ class Interpreter: input_list = input_string.split(' ') commands = [type(cmd).__name__.lower() for cmd in self._commands] command = input_list[0] - args = input_list[1:] - print(command) + args = input_list[1:] if len(input_list) > 2 else [] if command in commands: cmd = next((cmd for cmd in self._commands if type(cmd).__name__.lower() == command), None) if cmd is not None: cmd.run(args) else: - print(f'Unexpected command {command}') + Console.error(f'Unexpected command {command}') else: - print(f'Unexpected command {command}') + Console.error(f'Unexpected command {command}') diff --git a/src/sh_edraft/console/console.py b/src/sh_edraft/console/console.py index 2418cf8a..b2b722da 100644 --- a/src/sh_edraft/console/console.py +++ b/src/sh_edraft/console/console.py @@ -1,5 +1,8 @@ import os from typing import Union, Optional + +import pyfiglet +from tabulate import tabulate from termcolor import colored from sh_edraft.console.model.background_color import BackgroundColor @@ -7,6 +10,8 @@ from sh_edraft.console.model.foreground_color import ForegroundColor class Console: + _is_first_write = True + _background_color: BackgroundColor = BackgroundColor.default _foreground_color: ForegroundColor = ForegroundColor.default _x: Optional[int] = None @@ -64,6 +69,9 @@ class Console: if cls._disabled: return + if cls._is_first_write: + cls._is_first_write = False + args = [] colored_args = [] @@ -88,6 +96,11 @@ class Console: Useful public methods """ + @classmethod + def banner(cls, string: str): + ascii_banner = pyfiglet.figlet_format(string) + cls.write_line(ascii_banner) + @staticmethod def clear(): os.system('cls' if os.name == 'nt' else 'clear') @@ -103,6 +116,15 @@ class Console: def disable(cls): cls._disabled = True + @classmethod + def error(cls, string: str, tb: str = None): + cls.set_foreground_color('red') + if tb is not None: + cls.write_line(f'{string} -> {tb}') + else: + cls.write_line(string) + cls.set_foreground_color('default') + @classmethod def enable(cls): cls._disabled = False @@ -126,6 +148,12 @@ class Console: cls._background_color = BackgroundColor.default cls._foreground_color = ForegroundColor.default + @classmethod + def table(cls, header: list[str], values: list[list[str]]): + table = tabulate(values, headers=header) + + Console.write_line(table) + @classmethod def write(cls, *args): string = ' '.join(map(str, args)) @@ -139,11 +167,13 @@ class Console: @classmethod def write_line(cls, *args): string = ' '.join(map(str, args)) - cls._output('') + if not cls._is_first_write: + cls._output('') cls._output(string, end='') @classmethod def write_line_at(cls, x: int, y: int, *args): string = ' '.join(map(str, args)) - cls._output('', end='') + if not cls._is_first_write: + cls._output('', end='') cls._output(string, x, y, end='')