gs_manager/cli.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Console script for game_server_manager."""
import inspect
import logging
from typing import List
import click
from gs_manager.command import DEFAULT_CONFIG, Config, ConfigCommandClass
from gs_manager.command.types import Server, ServerClass
from gs_manager.logger import get_logger
from gs_manager.servers import (
STATUS_FAILED,
STATUS_PARTIAL_FAIL,
STATUS_SUCCESS,
EmptyServer,
)
@click.group(
cls=ConfigCommandClass,
chain=True,
invoke_without_command=True,
add_help_option=False,
)
# Generic Parameters
@click.option(
"-c",
"--config-file",
type=click.Path(),
default=DEFAULT_CONFIG,
help="Config file to read vars from",
)
@click.option(
"-p",
"--server-path",
type=click.Path(),
default=Config.server_path,
help="The root path for the game server",
)
@click.option(
"-s",
"--save",
is_flag=True,
help=("Save config to YML file after loading"),
)
@click.option(
"-d", "--debug", is_flag=True, help="Show extra debug information"
)
@click.option(
"-t",
"--server-type",
type=ServerClass(),
help="Type of gameserver to run",
default=Config.server_type,
)
@click.option("-h", "--help", is_flag=True, help="Shows this message and exit")
@click.pass_context
def main(
context: click.Context,
config_file: str,
server_path: str,
save: bool,
debug: bool,
server_type: Server,
help: bool,
**kwargs,
):
""" Console script for gs_manager """
logger = get_logger()
logger.debug("Initial Context:")
logger.debug(context.params)
logger.debug(context.args)
if isinstance(context.obj, EmptyServer):
server: EmptyServer = context.obj
config: Config = server.config
logger.debug("Main Server Config:")
logger.debug(config.__dict__)
for name, instance_config in config.instances.items():
logger.debug(f"Instance Server Config ({name}):")
logger.debug(instance_config.__dict__)
add_subcommands(server, logger)
else:
config: Config = context.obj
if help or context.invoked_subcommand is None:
click.echo(context.get_help())
if save:
config.save_config()
@main.resultcallback()
def process_result(results: List[int], **kwargs) -> None:
logger = get_logger()
logger.debug("result callback")
logger.debug(results)
logger.debug(kwargs)
partial_failed = results.count(STATUS_PARTIAL_FAIL)
failed = results.count(STATUS_FAILED)
return_code = STATUS_SUCCESS
total = len(results)
if failed > 0:
return_code = STATUS_PARTIAL_FAIL
if partial_failed > 0:
return_code = STATUS_PARTIAL_FAIL
if failed == total:
return_code = STATUS_FAILED
click.get_current_context().exit(return_code)
def add_global_options(
server: EmptyServer,
command: click.Command,
logger: logging.getLoggerClass(),
):
options = server.config.global_options["all"]
if server.supports_multi_instance:
options += server.config.global_options["instance_enabled"]
for option in options:
command.params.append(click.Option(**option))
logger.debug("Found global options:")
logger.debug(options)
def add_subcommands(server: EmptyServer, logger: logging.getLoggerClass()):
all_members = inspect.getmembers(server)
subcommands = []
for member in all_members:
if isinstance(member[1], click.Command):
add_global_options(server, member[1], logger)
main.add_command(member[1], name=member[0])
subcommands.append(member[0])
logger.debug("Found subcommands:")
logger.debug(subcommands)
if __name__ == "__main__":
main()