From 71943a19119f7ed683b2e1a34f85d4d48d6812a8 Mon Sep 17 00:00:00 2001 From: ldericher <40151420+ldericher@users.noreply.github.com> Date: Wed, 20 Oct 2021 14:32:45 +0200 Subject: [PATCH] "kiwi init" as in previous version --- kiwi_scp/commands/cmd_init.py | 52 +++++++++++++++++++++++++---- kiwi_scp/config.py | 12 +++++-- kiwi_scp/misc.py | 23 +++++++++++++ kiwi_scp/subcommands/init.py | 63 ----------------------------------- tests/test_config.py | 2 ++ 5 files changed, 79 insertions(+), 73 deletions(-) delete mode 100644 kiwi_scp/subcommands/init.py diff --git a/kiwi_scp/commands/cmd_init.py b/kiwi_scp/commands/cmd_init.py index 2e38817..5e6126a 100644 --- a/kiwi_scp/commands/cmd_init.py +++ b/kiwi_scp/commands/cmd_init.py @@ -1,20 +1,58 @@ +import logging +import os +from ipaddress import IPv4Network +from pathlib import Path + import click from .cli import KiwiCTX, pass_kiwi_ctx +from .._constants import KIWI_CONF_NAME +from ..config import Config +from ..misc import user_query @click.command( "init", short_help="Initializes kiwi-scp" ) -@click.argument( - "path", - required=False, - type=click.Path(resolve_path=True) +@click.option( + "-f/-F", + "--force/--no-force", + help=f"use default values even if {KIWI_CONF_NAME} is present", +) +@click.option( + "-s/-S", + "--show/--no-show", + help=f"show effective {KIWI_CONF_NAME} contents instead", ) @pass_kiwi_ctx -def cmd(ctx: KiwiCTX, path): +def cmd(ctx: KiwiCTX, force: bool, show: bool): """Initialize or reconfigure a kiwi-scp instance""" - click.echo(f"Hello init, kiwi version {ctx.config.version}") - pass + current_config = Config() if force else ctx.config + + if show: + # just show the currently effective kiwi.yml + click.echo_via_pager(current_config.kiwi_yml) + return + + # check force switch + if force and os.path.isfile(KIWI_CONF_NAME): + logging.warning(f"Overwriting an existing '{KIWI_CONF_NAME}'!") + + # build new kiwi dict + kiwi_dict = current_config.kiwi_dict + kiwi_dict.update({ + "version": user_query("kiwi-scp version to use in this instance", current_config.version), + "storage": { + "directory": user_query("local directory for service data", current_config.storage.directory, Path), + }, + "network": { + "name": user_query("name for local network hub", current_config.network.name), + "cidr": user_query("CIDRv4 block for local network hub", current_config.network.cidr, IPv4Network), + }, + }) + + # write out as new kiwi.yml + with open(ctx.instance.joinpath(KIWI_CONF_NAME), "w") as file: + file.write(Config.parse_obj(kiwi_dict).kiwi_yml) diff --git a/kiwi_scp/config.py b/kiwi_scp/config.py index 025185d..cb9a0de 100644 --- a/kiwi_scp/config.py +++ b/kiwi_scp/config.py @@ -142,7 +142,7 @@ class Config(BaseModel): @classmethod @functools.lru_cache(maxsize=5) def from_instance(cls, instance: Path): - """parses an actual kiwi.yml from disk""" + """parses an actual kiwi.yml from disk (cached)""" try: with open(instance.joinpath(KIWI_CONF_NAME)) as kc: @@ -151,7 +151,14 @@ class Config(BaseModel): except FileNotFoundError: # return the defaults if no kiwi.yml found - return cls() + return cls.from_default() + + @classmethod + @functools.lru_cache(maxsize=1) + def from_default(cls): + """returns the default config (cached)""" + + return cls() @property def kiwi_dict(self) -> Dict[str, Any]: @@ -352,4 +359,3 @@ class Config(BaseModel): else: # undefined format raise ValueError("Invalid Network Format") - diff --git a/kiwi_scp/misc.py b/kiwi_scp/misc.py index ed91da9..7202fd3 100644 --- a/kiwi_scp/misc.py +++ b/kiwi_scp/misc.py @@ -1,3 +1,26 @@ +from typing import Any, Type + +import click + + +def user_query(description: str, default: Any, cast_to: Type[Any] = str): + # prompt user as per argument + while True: + try: + str_value = input(f"Enter {description} [{default}] ").strip() + if str_value: + return cast_to(str_value) + else: + return default + + except EOFError: + click.echo("Input aborted.") + return default + + except Exception as e: + click.echo(f"Invalid input: {e}") + + def _surround(string, bang): midlane = f"{bang * 3} {string} {bang * 3}" sidelane = bang * len(midlane) diff --git a/kiwi_scp/subcommands/init.py b/kiwi_scp/subcommands/init.py deleted file mode 100644 index 1ca9c6a..0000000 --- a/kiwi_scp/subcommands/init.py +++ /dev/null @@ -1,63 +0,0 @@ -# system -import logging -import os - -# local -from .._constants import KIWI_CONF_NAME -from ..config import DefaultConfig, LoadedConfig -from ..subcommand import SubCommand - - -class InitCommand(SubCommand): - """kiwi init""" - - def __init__(self): - super().__init__( - 'init', - action=f"Initializing '{KIWI_CONF_NAME}' in", - description="Initialize or reconfigure kiwi-scp instance" - ) - - # -f switch: Initialize with default config - self._sub_parser.add_argument( - '-f', '--force', - action='store_true', - help=f"use default values even if {KIWI_CONF_NAME} is present" - ) - - # -s switch: Show current config instead - self._sub_parser.add_argument( - '-s', '--show', - action='store_true', - help=f"show effective {KIWI_CONF_NAME} contents instead" - ) - - def _run_instance(self, runner, args): - config = LoadedConfig.get() - - # check show switch - if args.show: - print(config) - return True - - # check force switch - if args.force and os.path.isfile(KIWI_CONF_NAME): - logging.warning(f"Overwriting existing '{KIWI_CONF_NAME}'!") - config = DefaultConfig.get() - - # version - config.user_query('version') - - # runtime - config.user_query('runtime:storage') - - # markers - config.user_query('markers:project') - config.user_query('markers:disabled') - - # network - config.user_query('network:name') - config.user_query('network:cidr') - - config.save() - return True diff --git a/tests/test_config.py b/tests/test_config.py index e00f2fb..a2fdee3 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -19,6 +19,8 @@ def test_default(): c = Config() version = toml.load("./pyproject.toml")["tool"]["poetry"]["version"] + assert c == Config.from_default() + assert c.version == version assert len(c.shells) == 1 assert c.shells[0] == Path("/bin/bash")