mirror of
https://github.com/yavook/kiwi-scp.git
synced 2024-12-25 10:33:01 +00:00
KiwiCommand API
This commit is contained in:
parent
52f0e9b8a3
commit
2e37291a68
4 changed files with 71 additions and 62 deletions
|
@ -5,7 +5,7 @@ from typing import List, Tuple, Iterable, Any, Type
|
|||
|
||||
import click
|
||||
|
||||
from ..instance import Instance
|
||||
from ..instance import Instance, Project, Services
|
||||
|
||||
|
||||
class KiwiCLI(click.MultiCommand):
|
||||
|
@ -42,8 +42,8 @@ class KiwiCommand:
|
|||
click.secho(header, fg="green", bold=True)
|
||||
|
||||
@staticmethod
|
||||
def print_error(header: str):
|
||||
click.secho(header, file=sys.stderr, fg="red", bold=True)
|
||||
def print_error(error: str):
|
||||
click.secho(error, file=sys.stderr, fg="red", bold=True)
|
||||
|
||||
@staticmethod
|
||||
def print_list(content: Iterable[str]):
|
||||
|
@ -77,24 +77,22 @@ class KiwiCommand:
|
|||
|
||||
@classmethod
|
||||
def run_for_instance(cls, instance: Instance, **kwargs) -> None:
|
||||
for project in instance.config.projects:
|
||||
cls.run_for_project(instance, project.name, **kwargs)
|
||||
for project_config in instance.config.projects:
|
||||
project = instance.get_project(project_config.name)
|
||||
cls.run_for_existing_project(instance, project, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def run_for_project(cls, instance: Instance, project_name: str, **kwargs) -> None:
|
||||
project = instance.get_project(project_name)
|
||||
|
||||
if project is None:
|
||||
click.secho(f"No project '{project_name}' in kiwi-scp instance at '{instance.directory}'.", fg="red", bold=True)
|
||||
return
|
||||
|
||||
service_names = [service.name for service in project.get_services().content]
|
||||
|
||||
cls.run_for_services(instance, project_name, service_names, **kwargs)
|
||||
def run_for_new_project(cls, instance: Instance, project_name: str, **kwargs) -> None:
|
||||
raise Exception
|
||||
|
||||
@classmethod
|
||||
def run_for_services(cls, instance: Instance, project_name: str, service_names: List[str], **kwargs) -> None:
|
||||
pass
|
||||
def run_for_existing_project(cls, instance: Instance, project: Project, **kwargs) -> None:
|
||||
service_names = [service.name for service in project.services.content]
|
||||
cls.run_for_services(instance, project, service_names, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def run_for_services(cls, instance: Instance, project: Project, service_names: List[str], **kwargs) -> None:
|
||||
raise Exception
|
||||
|
||||
|
||||
class KiwiCommandType(Enum):
|
||||
|
|
|
@ -4,7 +4,7 @@ import click
|
|||
|
||||
from .cli import KiwiCommandType, KiwiCommand
|
||||
from .decorators import kiwi_command
|
||||
from ..instance import Instance
|
||||
from ..instance import Instance, Project
|
||||
|
||||
|
||||
@click.option(
|
||||
|
@ -34,37 +34,29 @@ class CMD(KiwiCommand):
|
|||
)
|
||||
|
||||
@classmethod
|
||||
def run_for_project(cls, instance: Instance, project_name: str, show: bool = None, **kwargs) -> None:
|
||||
project = instance.get_project(project_name)
|
||||
|
||||
if project is None:
|
||||
KiwiCommand.print_error(f"No project '{project_name}' in kiwi-scp instance at '{instance.directory}'.")
|
||||
return
|
||||
|
||||
services = project.get_services()
|
||||
def run_for_existing_project(cls, instance: Instance, project: Project, show: bool = None, **kwargs) -> None:
|
||||
if show:
|
||||
KiwiCommand.print_header(f"Showing config for all services in project '{project_name}'.")
|
||||
click.echo_via_pager(str(services))
|
||||
KiwiCommand.print_header(f"Showing config for all services in project '{project.name}'.")
|
||||
click.echo_via_pager(str(project.services))
|
||||
|
||||
else:
|
||||
KiwiCommand.print_header(f"Services in project '{project_name}':")
|
||||
KiwiCommand.print_list(service.name for service in services.content)
|
||||
KiwiCommand.print_header(f"Services in project '{project.name}':")
|
||||
KiwiCommand.print_list(service.name for service in project.services.content)
|
||||
|
||||
@classmethod
|
||||
def run_for_services(cls, instance: Instance, project_name: str, service_names: List[str], show: bool = None,
|
||||
def run_for_new_project(cls, instance: Instance, project_name: str, **kwargs) -> None:
|
||||
KiwiCommand.print_error(f"Project '{project_name}' not in kiwi-scp instance at '{instance.directory}'!")
|
||||
|
||||
@classmethod
|
||||
def run_for_services(cls, instance: Instance, project: Project, service_names: List[str], show: bool = None,
|
||||
**kwargs) -> None:
|
||||
project = instance.get_project(project_name)
|
||||
|
||||
if project is None:
|
||||
KiwiCommand.print_error(f"No project '{project_name}' in kiwi-scp instance at '{instance.directory}'.")
|
||||
return
|
||||
|
||||
services = project.get_services(service_names)
|
||||
services = project.services.filter_existing(service_names)
|
||||
if show:
|
||||
service_names = [service.name for service in services.content]
|
||||
KiwiCommand.print_header(
|
||||
f"Showing config for services '{', '.join(service_names)}' in project '{project_name}'.")
|
||||
f"Showing config for matching services '{', '.join(service_names)}' in project '{project.name}'.")
|
||||
click.echo_via_pager(str(services))
|
||||
|
||||
else:
|
||||
KiwiCommand.print_header(f"Matching services in project '{project_name}':")
|
||||
KiwiCommand.print_header(f"Matching services in project '{project.name}':")
|
||||
KiwiCommand.print_list(service.name for service in services.content)
|
||||
|
|
|
@ -12,13 +12,14 @@ _pass_instance = click.make_pass_decorator(
|
|||
)
|
||||
|
||||
_project_arg = click.argument(
|
||||
"project",
|
||||
"project_name",
|
||||
metavar="[PROJECT]",
|
||||
required=False,
|
||||
type=str,
|
||||
)
|
||||
|
||||
_services_arg = click.argument(
|
||||
"services",
|
||||
"service_names",
|
||||
metavar="[SERVICE]...",
|
||||
nargs=-1,
|
||||
type=str,
|
||||
|
@ -40,24 +41,35 @@ def kiwi_command(
|
|||
**decorator_kwargs,
|
||||
)
|
||||
@_pass_instance
|
||||
def cmd(ctx: Instance, project: Optional[str] = None, services: Optional[Tuple[str]] = None,
|
||||
def cmd(ctx: Instance, project_name: Optional[str] = None, service_names: Optional[Tuple[str]] = None,
|
||||
**kwargs) -> None:
|
||||
|
||||
_logger.debug(f"{ctx.directory!r}: {project!r}, {services!r}")
|
||||
if project is None:
|
||||
_logger.debug(f"{ctx.directory!r}: {project_name!r}, {service_names!r}")
|
||||
if project_name is None:
|
||||
# run for whole instance
|
||||
_logger.debug(f"running for instance, kwargs={kwargs}")
|
||||
command_cls.run_for_instance(ctx, **kwargs)
|
||||
|
||||
elif not services:
|
||||
elif not service_names:
|
||||
# run for one entire project
|
||||
_logger.debug(f"running for project {project}, kwargs={kwargs}")
|
||||
command_cls.run_for_project(ctx, project, **kwargs)
|
||||
project = ctx.get_project(project_name)
|
||||
if project is not None:
|
||||
_logger.debug(f"running for existing project {project}, kwargs={kwargs}")
|
||||
command_cls.run_for_existing_project(ctx, project, **kwargs)
|
||||
|
||||
else:
|
||||
_logger.debug(f"running for new project {project_name}, kwargs={kwargs}")
|
||||
command_cls.run_for_new_project(ctx, project_name, **kwargs)
|
||||
|
||||
else:
|
||||
# run for some services
|
||||
_logger.debug(f"running for services {services} in project {project}, kwargs={kwargs}")
|
||||
command_cls.run_for_services(ctx, project, list(services), **kwargs)
|
||||
project = ctx.get_project(project_name)
|
||||
if project is not None:
|
||||
_logger.debug(f"running for services {service_names} in project {project}, kwargs={kwargs}")
|
||||
command_cls.run_for_services(ctx, project, list(service_names), **kwargs)
|
||||
|
||||
else:
|
||||
KiwiCommand.print_error(f"Project '{project_name}' not in kiwi-scp instance at '{ctx.directory}'!")
|
||||
|
||||
if command_type is KiwiCommandType.PROJECT:
|
||||
cmd = _project_arg(cmd)
|
||||
|
|
|
@ -43,6 +43,16 @@ class Services:
|
|||
}
|
||||
}).strip()
|
||||
|
||||
def __bool__(self) -> bool:
|
||||
return bool(self.content)
|
||||
|
||||
def filter_existing(self, service_names: List[str]):
|
||||
return Services([
|
||||
service
|
||||
for service in self.content
|
||||
if service.name in service_names
|
||||
])
|
||||
|
||||
|
||||
@attr.s
|
||||
class Project:
|
||||
|
@ -54,21 +64,18 @@ class Project:
|
|||
with open(directory.joinpath(COMPOSE_FILE_NAME), "r") as cf:
|
||||
return YAML().load(cf)
|
||||
|
||||
def get_services(self, service_names: Optional[List[str]] = None) -> Services:
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return self.directory.name
|
||||
|
||||
@property
|
||||
def services(self) -> Services:
|
||||
yml = Project._parse_compose_file(self.directory)
|
||||
services = [
|
||||
|
||||
return Services([
|
||||
Service(name, description)
|
||||
for name, description in yml["services"].items()
|
||||
]
|
||||
|
||||
if not service_names:
|
||||
return Services(services)
|
||||
else:
|
||||
return Services([
|
||||
service
|
||||
for service in services
|
||||
if service.name in service_names
|
||||
])
|
||||
])
|
||||
|
||||
|
||||
@attr.s
|
||||
|
|
Loading…
Reference in a new issue