1
0
Fork 0
mirror of https://github.com/yavook/kiwi-scp.git synced 2024-11-22 12:53:00 +00:00
kiwi-scp/kiwi_scp/commands/cli.py

74 lines
2.3 KiB
Python

import importlib
import os
from gettext import gettext as _
from typing import List, Optional
import click
class KiwiCLI(click.MultiCommand):
"""Command Line Interface spread over multiple files in this directory"""
def list_commands(self, ctx: click.Context) -> List[str]:
"""list all the commands defined by cmd_*.py files in this directory"""
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: click.Context, cmd_name: str) -> Optional[click.Command]:
"""import and return a specific command"""
try:
cmd_module = importlib.import_module(f"kiwi_scp.commands.cmd_{cmd_name}")
except ImportError:
return
member_name = f"{cmd_name.capitalize()}Command"
if member_name in dir(cmd_module):
member = getattr(cmd_module, member_name)
if isinstance(member, click.Command):
return member
else:
raise Exception("Fail class")
else:
raise Exception("Fail member name")
def format_commands(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
commands = {
"Operation": [
"up", "down", "restart", "update",
],
"Instance Management": [
"init", "list",
],
"Project and Service Management": [
"new", "enable", "disable", "logs", "shell", "cmd",
],
"Image Handling": [
"build", "pull", "push",
],
}
# allow for 3 times the default spacing
cmd_names = set(self.list_commands(ctx))
limit = formatter.width - 6 - max(len(cmd_name) for cmd_name in cmd_names)
for purpose, cmd_list in commands.items():
with formatter.section(_(f"Commands for {purpose}")):
formatter.write_dl([
(cmd_name, self.get_command(ctx, cmd_name).get_short_help_str(limit))
for cmd_name in cmd_list
])
cmd_names -= set(cmd_list)
if len(cmd_names) > 0:
raise Exception(f"Some commands were not registered in a group above: {cmd_names}")