From 9da09d56cfb11fd536364f87c2ae9b9a91431dea Mon Sep 17 00:00:00 2001 From: ldericher Date: Tue, 11 Aug 2020 14:03:00 +0200 Subject: [PATCH] Massive QoL reworks --- src/kiwi-config.py | 13 +----- src/kiwi/__init__.py | 16 +++++-- src/kiwi/_constants.py | 4 ++ src/kiwi/config.py | 13 +++--- src/kiwi/{core.py => parser.py} | 14 +++--- src/kiwi/runner.py | 18 +++++--- src/kiwi/subcommands/_utils.py | 8 ++-- src/kiwi/subcommands/init.py | 53 ++++++++++++---------- src/kiwi/subcommands/logs.py | 32 ++++++------- src/kiwi/subcommands/show.py | 5 +- src/{default.kiwi.yml => kiwi_default.yml} | 3 -- src/kiwi_header.yml | 3 ++ 12 files changed, 93 insertions(+), 89 deletions(-) create mode 100644 src/kiwi/_constants.py rename src/kiwi/{core.py => parser.py} (82%) rename src/{default.kiwi.yml => kiwi_default.yml} (63%) create mode 100644 src/kiwi_header.yml diff --git a/src/kiwi-config.py b/src/kiwi-config.py index 87789e7..c399ab0 100755 --- a/src/kiwi-config.py +++ b/src/kiwi-config.py @@ -20,20 +20,11 @@ def set_verbosity(logger, handler, verbosity): def main(): - kiwi.Parser().get_parser().add_argument( - '-v', '--verbosity', - action='count', default=0 - ) - - args = kiwi.Parser().get_args() - log_handler = logging.StreamHandler() logging.getLogger().addHandler(log_handler) - set_verbosity(logging.getLogger(), log_handler, args.verbosity) + set_verbosity(logging.getLogger(), log_handler, kiwi.verbosity()) - logging.debug(f"main CLI args: {args}") - - kiwi.Runner().run(args.command) + kiwi.run() if __name__ == "__main__": diff --git a/src/kiwi/__init__.py b/src/kiwi/__init__.py index f5decab..2f4a363 100644 --- a/src/kiwi/__init__.py +++ b/src/kiwi/__init__.py @@ -1,7 +1,17 @@ -from .core import Parser +from .parser import Parser from .runner import Runner + +def verbosity(): + _ = Runner() + return Parser().get_args().verbosity + + +def run(): + Runner().run() + + __all__ = [ - 'Parser', - 'Runner' + 'verbosity', + 'run' ] diff --git a/src/kiwi/_constants.py b/src/kiwi/_constants.py new file mode 100644 index 0000000..e16de2c --- /dev/null +++ b/src/kiwi/_constants.py @@ -0,0 +1,4 @@ +import os + +KIWI_ROOT = os.getenv('KIWI_ROOT', ".") +KIWI_CONF_NAME = os.getenv('KIWI_CONF_NAME', "kiwi.yml") diff --git a/src/kiwi/config.py b/src/kiwi/config.py index 1f98ef1..7e467cf 100644 --- a/src/kiwi/config.py +++ b/src/kiwi/config.py @@ -3,12 +3,13 @@ import re import os import yaml -from .core import KIWI_ROOT, KIWI_CONF_NAME +from ._constants import KIWI_ROOT, KIWI_CONF_NAME ########### # CONSTANTS -DEFAULT_KIWI_CONF_NAME = f"{KIWI_ROOT}/default.kiwi.yml" +HEADER_KIWI_CONF_NAME = f"{KIWI_ROOT}/kiwi_header.yml" +DEFAULT_KIWI_CONF_NAME = f"{KIWI_ROOT}/kiwi_default.yml" VERSION_TAG_NAME = f"{KIWI_ROOT}/version-tag" @@ -42,11 +43,9 @@ class Config: # insert newline before every main key yml_string = re.sub(r'^(\S)', r'\n\1', yml_string, flags=re.MULTILINE) - # extract header comment from default config - with open(DEFAULT_KIWI_CONF_NAME, 'r') as stream: - yml_header = stream.read().strip() - yml_header = re.sub(r'^[^#].*', r'', yml_header, flags=re.MULTILINE).strip() - yml_string = "{}\n{}".format(yml_header, yml_string) + # load header comment from file + with open(HEADER_KIWI_CONF_NAME, 'r') as stream: + yml_string = stream.read() + yml_string return yml_string diff --git a/src/kiwi/core.py b/src/kiwi/parser.py similarity index 82% rename from src/kiwi/core.py rename to src/kiwi/parser.py index 9f06fa7..858fed9 100644 --- a/src/kiwi/core.py +++ b/src/kiwi/parser.py @@ -1,11 +1,4 @@ import argparse -import os - -########### -# CONSTANTS - -KIWI_ROOT = os.getenv('KIWI_ROOT', ".") -KIWI_CONF_NAME = os.getenv('KIWI_CONF_NAME', "kiwi.yml") class Parser: @@ -17,6 +10,11 @@ class Parser: def __init__(self): self.__parser = argparse.ArgumentParser(description='kiwi-config') + self.__parser.add_argument( + '-v', '--verbosity', + action='count', default=0 + ) + self.__subparsers = self.__parser.add_subparsers() self.__subparsers.required = True self.__subparsers.dest = 'command' @@ -40,4 +38,4 @@ class Parser: Parser.__instance = Parser.__Parser() def __getattr__(self, item): - return getattr(self.__instance, item) + return getattr(self.__instance, item) \ No newline at end of file diff --git a/src/kiwi/runner.py b/src/kiwi/runner.py index b65d4f7..75cc6bc 100644 --- a/src/kiwi/runner.py +++ b/src/kiwi/runner.py @@ -1,3 +1,7 @@ +import logging + +from .config import LoadedConfig +from .parser import Parser from .subcommands import * ########### @@ -18,10 +22,14 @@ class Runner: for cmd in SUBCOMMANDS: self.__commands.append(cmd()) - def run(self, command_name): + def run(self): + config = LoadedConfig.get() + args = Parser().get_args() + for cmd in self.__commands: - if str(cmd) == command_name: - cmd.run() + if str(cmd) == args.command: + logging.debug(f"Running '{cmd}' with args: {args}") + cmd.run(config, args) return True return False @@ -34,7 +42,3 @@ class Runner: def __getattr__(self, item): return getattr(self.__instance, item) - - -if __name__ == 'kiwi.runner': - _ = Runner() diff --git a/src/kiwi/subcommands/_utils.py b/src/kiwi/subcommands/_utils.py index 47458ab..6de617b 100644 --- a/src/kiwi/subcommands/_utils.py +++ b/src/kiwi/subcommands/_utils.py @@ -2,7 +2,7 @@ import logging import os import subprocess -from ..core import Parser +from ..parser import Parser from ..config import LoadedConfig @@ -28,16 +28,16 @@ def get_exe_key(exe_name): class SubCommand: __name = None - _parser = None + _sub_parser = None def __init__(self, name, **kwargs): self.__name = name - self._parser = Parser().get_subparsers().add_parser(name, **kwargs) + self._sub_parser = Parser().get_subparsers().add_parser(name, **kwargs) def __str__(self): return self.__name - def run(self): + def run(self, config, args): pass diff --git a/src/kiwi/subcommands/init.py b/src/kiwi/subcommands/init.py index 00b0554..bba50be 100644 --- a/src/kiwi/subcommands/init.py +++ b/src/kiwi/subcommands/init.py @@ -1,15 +1,19 @@ import logging import os -from ..core import KIWI_CONF_NAME, Parser -from ..config import DefaultConfig, LoadedConfig +from .._constants import KIWI_CONF_NAME +from ..config import DefaultConfig from ._utils import SubCommand, is_executable, find_exe_file, get_exe_key def user_input(config, key, prompt): # prompt user as per argument - result = input("{} [{}] ".format(prompt, config[key])).strip() + try: + result = input("{} [{}] ".format(prompt, config[key])).strip() + except EOFError: + print() + result = None # store result if present if result: @@ -38,38 +42,41 @@ class InitCommand(SubCommand): description="Create a new kiwi-config instance" ) - self._parser.add_argument( + self._sub_parser.add_argument( '-f', '--force', action='store_true', help=f"use default values even if {KIWI_CONF_NAME} is present" ) - def run(self): + def run(self, config, args): logging.info(f"Initializing kiwi-config instance in '{os.getcwd()}'") - if Parser().get_args().force and os.path.isfile(KIWI_CONF_NAME): + if args.force and os.path.isfile(KIWI_CONF_NAME): logging.warning(f"Overwriting existing '{KIWI_CONF_NAME}'!") config = DefaultConfig.get() - else: - config = LoadedConfig.get() - # version - user_input(config, 'version', "Enter kiwi-config version for this instance") + try: + # 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") - # executables - user_input_exe(config, 'docker') - user_input_exe(config, 'docker-compose') - user_input_exe(config, 'sudo') + # executables + user_input_exe(config, 'docker') + user_input_exe(config, 'docker-compose') + user_input_exe(config, 'sudo') - config.save() + config.save() + + except KeyboardInterrupt: + print() + logging.warning(f"'{self}' aborted, input discarded.") diff --git a/src/kiwi/subcommands/logs.py b/src/kiwi/subcommands/logs.py index 7228cef..5ae932a 100644 --- a/src/kiwi/subcommands/logs.py +++ b/src/kiwi/subcommands/logs.py @@ -1,8 +1,5 @@ import logging -from ..config import LoadedConfig -from ..core import Parser - from ._utils import SubCommand, DockerCommand @@ -13,26 +10,23 @@ class LogsCommand(SubCommand): description="Show logs of a project or service(s) of a project" ) - self._parser.add_argument( + self._sub_parser.add_argument( '-f', '--follow', action='store_true', help="output appended data as log grows" ) - self._parser.add_argument( + self._sub_parser.add_argument( 'project', type=str, help="select a project in this instance" ) - self._parser.add_argument( + self._sub_parser.add_argument( 'services', metavar='service', nargs='*', type=str, help="select service(s) in a project" ) - def run(self): - config = LoadedConfig.get() - cli_args = Parser().get_args() - - project_name = cli_args.project + def run(self, config, args): + project_name = args.project project_marker = config['markers:project'] project_dir = f'{project_name}{project_marker}' @@ -41,22 +35,22 @@ class LogsCommand(SubCommand): 'COMPOSE_PROJECT_NAME': project_name } - args = ['logs', '-t'] - if cli_args.follow: - args = [*args, '-f', '--tail=10'] + process_args = ['logs', '-t'] + if args.follow: + process_args = [*process_args, '-f', '--tail=10'] - if cli_args.services: - args = [*args, *cli_args.services] + if args.services: + process_args = [*process_args, *args.services] try: - if cli_args.follow: + if args.follow: DockerCommand('docker-compose').run( - args, + process_args, cwd=project_dir, env=environment ) else: DockerCommand('docker-compose').run_less( - args, + process_args, cwd=project_dir, env=environment ) except KeyboardInterrupt: diff --git a/src/kiwi/subcommands/show.py b/src/kiwi/subcommands/show.py index 6785485..1deb830 100644 --- a/src/kiwi/subcommands/show.py +++ b/src/kiwi/subcommands/show.py @@ -1,5 +1,3 @@ -from ..config import LoadedConfig - from ._utils import SubCommand @@ -10,6 +8,5 @@ class ShowCommand(SubCommand): description="Show effective kiwi.yml" ) - def run(self): - config = LoadedConfig.get() + def run(self, config, args): print(config) diff --git a/src/default.kiwi.yml b/src/kiwi_default.yml similarity index 63% rename from src/default.kiwi.yml rename to src/kiwi_default.yml index b729709..9bfce99 100644 --- a/src/default.kiwi.yml +++ b/src/kiwi_default.yml @@ -1,6 +1,3 @@ -###################################### -# kiwi-config instance configuration # -###################################### version: runtime: storage: /var/kiwi diff --git a/src/kiwi_header.yml b/src/kiwi_header.yml new file mode 100644 index 0000000..95d3b8f --- /dev/null +++ b/src/kiwi_header.yml @@ -0,0 +1,3 @@ +###################################### +# kiwi-config instance configuration # +######################################