Type hinting in CLI, KiwiCommand class names, removed kiwi_command name parameter
This commit is contained in:
parent
512ee9ba87
commit
9095b57b23
5 changed files with 31 additions and 27 deletions
|
@ -1,7 +1,8 @@
|
|||
import importlib
|
||||
import os
|
||||
import sys
|
||||
from enum import Enum, auto
|
||||
from typing import List, Tuple, Iterable, Any, Type
|
||||
from typing import List, Tuple, Iterable, Type, Optional, TypeVar
|
||||
|
||||
import click
|
||||
|
||||
|
@ -11,42 +12,50 @@ from ..instance import Instance, Project
|
|||
class KiwiCLI(click.MultiCommand):
|
||||
"""Command Line Interface spread over multiple files in this directory"""
|
||||
|
||||
def list_commands(self, ctx):
|
||||
def list_commands(self, ctx: click.Context) -> List[str]:
|
||||
"""list all the commands defined by cmd_*.py files in this directory"""
|
||||
|
||||
return (
|
||||
return [
|
||||
filename[4:-3]
|
||||
for filename in os.listdir(os.path.abspath(os.path.dirname(__file__)))
|
||||
if filename.startswith("cmd_") and filename.endswith(".py")
|
||||
)
|
||||
]
|
||||
|
||||
def get_command(self, ctx, name):
|
||||
def get_command(self, ctx: click.Context, cmd_name: str) -> Optional[click.Command]:
|
||||
"""import and return a specific command"""
|
||||
|
||||
try:
|
||||
mod = __import__(f"kiwi_scp.commands.cmd_{name}", None, None, ["CMD"])
|
||||
cmd_module = importlib.import_module(f"kiwi_scp.commands.cmd_{cmd_name}")
|
||||
|
||||
except ImportError:
|
||||
return
|
||||
return mod.CMD
|
||||
|
||||
for cmd_name in dir(cmd_module):
|
||||
member = getattr(cmd_module, cmd_name)
|
||||
if isinstance(member, click.Command):
|
||||
return member
|
||||
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class KiwiCommand:
|
||||
@staticmethod
|
||||
def print_multi_color(*content: Tuple[str, str]):
|
||||
def print_multi_color(*content: Tuple[str, str]) -> None:
|
||||
for message, color in content:
|
||||
click.secho(message, fg=color, nl=False)
|
||||
click.echo()
|
||||
|
||||
@staticmethod
|
||||
def print_header(header: str):
|
||||
def print_header(header: str) -> None:
|
||||
click.secho(header, fg="green", bold=True)
|
||||
|
||||
@staticmethod
|
||||
def print_error(error: str):
|
||||
def print_error(error: str) -> None:
|
||||
click.secho(error, file=sys.stderr, fg="red", bold=True)
|
||||
|
||||
@staticmethod
|
||||
def print_list(content: Iterable[str]):
|
||||
def print_list(content: Iterable[str]) -> None:
|
||||
for item in content:
|
||||
KiwiCommand.print_multi_color(
|
||||
(" - ", "green"),
|
||||
|
@ -54,7 +63,7 @@ class KiwiCommand:
|
|||
)
|
||||
|
||||
@staticmethod
|
||||
def user_query(description: str, default: Any, cast_to: Type[Any] = str):
|
||||
def user_query(description: str, default: T, cast_to: Type[T] = str) -> T:
|
||||
# prompt user as per argument
|
||||
while True:
|
||||
try:
|
||||
|
|
|
@ -15,17 +15,16 @@ from ..instance import Instance, Project
|
|||
)
|
||||
@click.argument(
|
||||
"compose_cmd",
|
||||
metavar="CMD",
|
||||
metavar="COMMAND",
|
||||
)
|
||||
@kiwi_command(
|
||||
"cmd",
|
||||
KiwiCommandType.PROJECT,
|
||||
cmd_type=KiwiCommandType.PROJECT,
|
||||
short_help="Run docker-compose command",
|
||||
# ignore arguments looking like options
|
||||
# just pass everything down to docker-compose
|
||||
context_settings={"ignore_unknown_options": True},
|
||||
)
|
||||
class CMD(KiwiCommand):
|
||||
class CmdCommand(KiwiCommand):
|
||||
"""Run raw docker-compose command in a project"""
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -30,11 +30,10 @@ _logger = logging.getLogger(__name__)
|
|||
help=f"use default values even if {KIWI_CONF_NAME} is present",
|
||||
)
|
||||
@kiwi_command(
|
||||
"init",
|
||||
KiwiCommandType.INSTANCE,
|
||||
cmd_type=KiwiCommandType.INSTANCE,
|
||||
short_help="Initializes kiwi-scp",
|
||||
)
|
||||
class CMD(KiwiCommand):
|
||||
class InitCommand(KiwiCommand):
|
||||
"""Initialize or reconfigure a kiwi-scp instance"""
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -13,11 +13,10 @@ from ..instance import Instance, Project
|
|||
help=f"show actual config contents instead",
|
||||
)
|
||||
@kiwi_command(
|
||||
"list",
|
||||
KiwiCommandType.SERVICE,
|
||||
cmd_type=KiwiCommandType.SERVICE,
|
||||
short_help="Inspect a kiwi-scp instance",
|
||||
)
|
||||
class CMD(KiwiCommand):
|
||||
class ListCommand(KiwiCommand):
|
||||
"""List projects in this instance, services inside a project or service(s) inside a project"""
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -29,14 +29,12 @@ _logger = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def kiwi_command(
|
||||
name: str,
|
||||
command_type: KiwiCommandType,
|
||||
cmd_type: KiwiCommandType = KiwiCommandType.SERVICE,
|
||||
**decorator_kwargs,
|
||||
) -> Callable:
|
||||
def decorator(command_cls: Type[KiwiCommand]) -> Callable:
|
||||
|
||||
@click.command(
|
||||
name,
|
||||
help=command_cls.__doc__,
|
||||
**decorator_kwargs,
|
||||
)
|
||||
|
@ -71,10 +69,10 @@ def kiwi_command(
|
|||
else:
|
||||
KiwiCommand.print_error(f"Project '{project_name}' not in kiwi-scp instance at '{ctx.directory}'!")
|
||||
|
||||
if command_type is KiwiCommandType.PROJECT:
|
||||
if cmd_type is KiwiCommandType.PROJECT:
|
||||
cmd = _project_arg(cmd)
|
||||
|
||||
elif command_type is KiwiCommandType.SERVICE:
|
||||
elif cmd_type is KiwiCommandType.SERVICE:
|
||||
cmd = _project_arg(cmd)
|
||||
cmd = _services_arg(cmd)
|
||||
|
||||
|
|
Loading…
Reference in a new issue