diff --git a/src/kiwi-config.py b/src/kiwi-config.py index 25eb590..f0da7c1 100755 --- a/src/kiwi-config.py +++ b/src/kiwi-config.py @@ -1,10 +1,40 @@ #!/usr/bin/env python3 +import logging + import kiwi +from kiwi.subcommands import * def main(): - kiwi.Runner.setup_all() - kiwi.Runner.run() + logging.basicConfig( + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", + level=logging.NOTSET + ) + + commands = [ + InitCommand, + ShowCommand, + LogsCommand + ] + + for cmd in commands: + cmd.setup() + + args = kiwi.Parser.get_args() + + if args.verbose >= 2: + log_level = logging.DEBUG + elif args.verbose >= 1: + log_level = logging.INFO + else: + log_level = logging.WARNING + + logging.getLogger().setLevel(log_level) + + for cmd in commands: + if cmd.command == args.command: + cmd.run() + return if __name__ == "__main__": diff --git a/src/kiwi/__init__.py b/src/kiwi/__init__.py index 247ace4..ded6eea 100644 --- a/src/kiwi/__init__.py +++ b/src/kiwi/__init__.py @@ -1,3 +1,5 @@ -from .runner import Runner +from .core import Parser -__all__ = ['Runner'] \ No newline at end of file +__all__ = [ + 'Parser' +] diff --git a/src/kiwi/core.py b/src/kiwi/core.py index 4316fcc..1ded8e5 100644 --- a/src/kiwi/core.py +++ b/src/kiwi/core.py @@ -9,32 +9,35 @@ KIWI_CONF_NAME = os.getenv('KIWI_CONF_NAME', "kiwi.yml") class Parser: - __instance = None + __parser = None __subparsers = None __args = None @classmethod - def __init_instance(cls): - if not cls.__instance: - cls.__instance = argparse.ArgumentParser(description='kiwi-config') + def get_parser(cls): + if cls.__parser is None: + cls.__parser = argparse.ArgumentParser(description='kiwi-config') - cls.__subparsers = Parser.__instance.add_subparsers() - cls.__subparsers.required = True - cls.__subparsers.dest = 'command' + cls.__parser.add_argument( + '-v', '--verbose', + action='count', default=0 + ) - @classmethod - def get_instance(cls): - cls.__init_instance() - return cls.__instance + return cls.__parser @classmethod def get_subparsers(cls): - cls.__init_instance() + if cls.__subparsers is None: + cls.__subparsers = cls.get_parser().add_subparsers() + cls.__subparsers.required = True + cls.__subparsers.dest = 'command' + return cls.__subparsers @classmethod def get_args(cls): - if not cls.__args: - cls.__args = cls.get_instance().parse_args() + if cls.__args is None: + cls.__args = cls.get_parser().parse_args() return cls.__args + diff --git a/src/kiwi/runner.py b/src/kiwi/runner.py deleted file mode 100644 index a0da00f..0000000 --- a/src/kiwi/runner.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import List - -from .core import Parser -from .subcommands import * - - -class Runner: - __commands: List[SubCommand] = [ - InitCommand, - ShowCommand, - LogsCommand - ] - - @classmethod - def setup_all(cls): - for cmd in cls.__commands: - cmd.setup() - - @classmethod - def run(cls): - args = Parser.get_args() - - for cmd in cls.__commands: - if cmd.command == args.command: - cmd.run() - return diff --git a/src/kiwi/subcommands/__init__.py b/src/kiwi/subcommands/__init__.py index d1a8d83..5219579 100644 --- a/src/kiwi/subcommands/__init__.py +++ b/src/kiwi/subcommands/__init__.py @@ -1,12 +1,9 @@ -from ._utils import SubCommand - from .init import InitCommand from .show import ShowCommand from .logs import LogsCommand __all__ = [ - 'SubCommand', 'InitCommand', 'ShowCommand', 'LogsCommand' -] \ No newline at end of file +] diff --git a/src/kiwi/subcommands/init.py b/src/kiwi/subcommands/init.py index 2791784..429a073 100644 --- a/src/kiwi/subcommands/init.py +++ b/src/kiwi/subcommands/init.py @@ -16,23 +16,35 @@ def user_input(config, key, prompt): config[key] = result +def is_executable(filename): + if filename is None: + return False + + return os.path.isfile(filename) and os.access(filename, os.X_OK) + + def find_exe(program_name): for path in os.environ["PATH"].split(os.pathsep): exe_file = os.path.join(path, program_name) - if os.path.isfile(exe_file) and os.access(exe_file, os.X_OK): + if is_executable(exe_file): return exe_file return None -def user_input_exe(config, program_name): - exe_file = find_exe(program_name) - key = 'executables:' + program_name +def user_input_exe(config, key): + exe_file = config[key] + program_name = key.split(':')[1] - if exe_file is not None: - config[key] = exe_file - else: - user_input(config, key, "Enter path to '{}' executable".format(program_name)) + if not is_executable(exe_file): + logging.warning("Reconfiguring '%s' executable path.", program_name) + exe_file = find_exe(program_name) + + if exe_file is not None: + logging.info("Found executable at '%s'.", exe_file) + config[key] = exe_file + else: + user_input(config, key, f"Enter path to '{program_name}' executable") class InitCommand(SubCommand): @@ -48,12 +60,12 @@ class InitCommand(SubCommand): parser.add_argument( '-f', '--force', action='store_true', - help="Use default values even if {} is present".format(KIWI_CONF_NAME) + help=f"Use default values even if {KIWI_CONF_NAME} is present" ) @classmethod def run(cls): - logging.info("Initializing kiwi-config instance in '%s'", os.getcwd()) + logging.info(f"Initializing kiwi-config instance in '{os.getcwd()}'") if Parser.get_args().force and os.path.isfile(KIWI_CONF_NAME): logging.warning("Overwriting existing '%s'!", KIWI_CONF_NAME) @@ -61,18 +73,23 @@ class InitCommand(SubCommand): else: config = LoadedConfig.get() + # version user_input(config, 'version', "Enter kiwi-config version for this instance") + # 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") + # network user_input(config, 'network:name', "Enter name for local docker network") user_input(config, 'network:cidr', "Enter CIDR block for local docker network") - user_input_exe(config, 'docker') - user_input_exe(config, 'docker-compose') - user_input_exe(config, 'sudo') + # executables + user_input_exe(config, 'executables:docker') + user_input_exe(config, 'executables:docker-compose') + user_input_exe(config, 'executables:sudo') config.save()