diff --git a/src/kiwi/runner.py b/src/kiwi/runner.py index a783382..f772372 100644 --- a/src/kiwi/runner.py +++ b/src/kiwi/runner.py @@ -42,7 +42,14 @@ class Runner: if str(cmd) == args.command: # command found logging.debug(f"Running '{cmd}' with args: {args}") - cmd.run(LoadedConfig.get(), args) + + try: + cmd.run(LoadedConfig.get(), args) + + except KeyboardInterrupt: + print() + logging.warning(f"'{cmd}' aborted, inputs may have been discarded.") + return True # command not found diff --git a/src/kiwi/subcommands/_subcommand.py b/src/kiwi/subcommands/_subcommand.py index 653c9fe..b886d92 100644 --- a/src/kiwi/subcommands/_subcommand.py +++ b/src/kiwi/subcommands/_subcommand.py @@ -41,15 +41,20 @@ class ProjectCommand(SubCommand): class ServiceCommand(ProjectCommand): - """this command concerns services in a project""" + """this command concerns service(s) in a project""" - def __init__(self, name, nargs='*', **kwargs): + def __init__(self, name, nargs=1, **kwargs): super().__init__( name, **kwargs ) + services = "service" + + if not nargs == 1: + services = "services" + self._sub_parser.add_argument( 'services', metavar='service', nargs=nargs, type=str, - help="select service(s) in a project" + help=f"select {services} in a project" ) diff --git a/src/kiwi/subcommands/cmd.py b/src/kiwi/subcommands/cmd.py index 52cb6ff..56cd5f4 100644 --- a/src/kiwi/subcommands/cmd.py +++ b/src/kiwi/subcommands/cmd.py @@ -7,23 +7,22 @@ from .utils.dockercommand import DockerCommand class CmdCommand(ProjectCommand): + """kiwi cmd""" + def __init__(self): super().__init__( 'cmd', description="Run raw docker-compose command in a project" ) - # arguments for docker-compose command + # command string after docker-compose self._sub_parser.add_argument( 'compose_cmd', metavar='cmd', type=str, - help="runs `docker-compose " + help="runs `docker-compose `" ) def run(self, config, args): - try: - import shlex - DockerCommand('docker-compose').run(config, args, shlex.split(args.compose_cmd)) + import shlex - except KeyboardInterrupt: - logging.debug("Subprocess aborted.") - print() + # run with split compose_cmd argument + DockerCommand('docker-compose').run(config, args, shlex.split(args.compose_cmd)) diff --git a/src/kiwi/subcommands/init.py b/src/kiwi/subcommands/init.py index 8d2c2b1..af54bcd 100644 --- a/src/kiwi/subcommands/init.py +++ b/src/kiwi/subcommands/init.py @@ -43,29 +43,25 @@ class InitCommand(SubCommand): def run(self, config, args): logging.info(f"Initializing '{KIWI_CONF_NAME}' in '{os.getcwd()}'") + # check force switch if args.force and os.path.isfile(KIWI_CONF_NAME): from ..config import DefaultConfig logging.warning(f"Overwriting existing '{KIWI_CONF_NAME}'!") config = DefaultConfig.get() - try: - # version - user_input(config, 'version', "Enter kiwi-config version for this instance") + # version + user_input(config, 'version', "Enter kiwi-config version for this instance") - # runtime - user_input(config, 'runtime:storage', "Enter local directory for service data") + # runtime + user_input(config, 'runtime:storage', "Enter local directory for service data") - # markers - user_input(config, 'markers:project', "Enter marker string for project directories") - user_input(config, 'markers:down', "Enter marker string for disabled projects") + # markers + user_input(config, 'markers:project', "Enter marker string for project directories") + user_input(config, 'markers:down', "Enter marker string for disabled projects") - # network - user_input(config, 'network:name', "Enter name for local docker network") - user_input(config, 'network:cidr', "Enter CIDR block for local docker network") + # network + user_input(config, 'network:name', "Enter name for local docker network") + user_input(config, 'network:cidr', "Enter CIDR block for local docker network") - config.save() - - except KeyboardInterrupt: - print() - logging.warning(f"'{self}' aborted, input discarded.") + config.save() diff --git a/src/kiwi/subcommands/logs.py b/src/kiwi/subcommands/logs.py index c38a635..8909f8f 100644 --- a/src/kiwi/subcommands/logs.py +++ b/src/kiwi/subcommands/logs.py @@ -9,7 +9,7 @@ from .utils.dockercommand import DockerCommand class LogsCommand(ServiceCommand): def __init__(self): super().__init__( - 'logs', + 'logs', nargs='*', description="Show logs of a project or service(s) of a project" ) @@ -20,19 +20,19 @@ class LogsCommand(ServiceCommand): ) def run(self, config, args): - compose_args = ['logs', '-t'] + # include timestamps + compose_cmd = ['logs', '-t'] + + # handle following the log output if args.follow: - compose_args = [*compose_args, '-f', '--tail=10'] + compose_cmd = [*compose_cmd, '-f', '--tail=10'] + # append if one or more services are given if args.services: - compose_args = [*compose_args, *args.services] + compose_cmd = [*compose_cmd, *args.services] - try: - if args.follow: - DockerCommand('docker-compose').run(config, args, compose_args) - else: - DockerCommand('docker-compose').run_less(config, args, compose_args) - - except KeyboardInterrupt: - logging.debug("Subprocess aborted.") - print() + # use 'less' viewer if output will be static + if args.follow: + DockerCommand('docker-compose').run(config, args, compose_cmd) + else: + DockerCommand('docker-compose').run_less(config, args, compose_cmd) diff --git a/src/kiwi/subcommands/shell.py b/src/kiwi/subcommands/shell.py index 8622c89..7967b3e 100644 --- a/src/kiwi/subcommands/shell.py +++ b/src/kiwi/subcommands/shell.py @@ -7,26 +7,26 @@ from ._subcommand import ServiceCommand from .utils.dockercommand import DockerCommand -def _service_has_shell(config, args, exec_service, try_shell): +def _service_has_shell(config, args, compose_cmd, shell): try: # test if desired shell exists DockerCommand('docker-compose').run( - config, args, [*exec_service, '/bin/sh', '-c', f"which {try_shell}"], + config, args, [*compose_cmd, '/bin/sh', '-c', f"which {shell}"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL ) return True except subprocess.CalledProcessError: # fallback - logging.info(f"Shell '{try_shell}' not found in container") + logging.info(f"Shell '{shell}' not found in container") return False class ShellCommand(ServiceCommand): def __init__(self): super().__init__( - 'sh', 1, - description="Spawn shell inside project's service" + 'sh', + description="Spawn shell inside a project's service" ) # -s switch: Select shell @@ -36,22 +36,18 @@ class ShellCommand(ServiceCommand): ) def run(self, config, args): - try: - exec_service = ['exec', args.services[0]] - exec_shell = args.shell + compose_cmd = ['exec', args.services[0]] + shell = args.shell - if not _service_has_shell(config, args, exec_service, exec_shell): - # fallback - exec_shell = '/bin/bash' + if not _service_has_shell(config, args, compose_cmd, shell): + # fallback + shell = '/bin/bash' - if not _service_has_shell(config, args, exec_service, exec_shell): - exec_shell = '/bin/sh' + if not _service_has_shell(config, args, compose_cmd, shell): + # safe fallback + shell = '/bin/sh' - # spawn shell - DockerCommand('docker-compose').run( - config, args, [*exec_service, exec_shell] - ) - - except KeyboardInterrupt: - logging.debug("Subprocess aborted.") - print() + # spawn shell + DockerCommand('docker-compose').run( + config, args, [*compose_cmd, shell] + )