diff --git a/src/zinolib/config/models.py b/src/zinolib/config/models.py new file mode 100644 index 0000000..0311f08 --- /dev/null +++ b/src/zinolib/config/models.py @@ -0,0 +1,17 @@ +from pydantic import BaseModel +from typing import Optional + + +class UserConfig(BaseModel): + username: str + password: str + + +class ServerV1Config(BaseModel): + server: str + port: str = "8001" + + +class Options(BaseModel): + autoremove: bool = False + timeout: int = 30 diff --git a/src/zinolib/config/zino1.py b/src/zinolib/config/zino1.py new file mode 100644 index 0000000..0ebb014 --- /dev/null +++ b/src/zinolib/config/zino1.py @@ -0,0 +1,52 @@ +from pydantic import BaseModel + +from . import tcl +from .models import UserConfig, ServerV1Config, Options + + +def _parse_tcl(config_dict, section): + fixed_dict = tcl.normalize(config_dict) + connection = fixed_dict["connections"][section] + options = fixed_dict["globals"] + connection['password'] = connection.pop("secret") + return connection, options + + +class ZinoV1Config(UserConfig, ServerV1Config, Options): + """ + How to use:: + + Make a config-class from the tcl-config stored on disk:: + + > config = ZinoV1Config.from_tcl() + + Get the actual user and Zino1 secret and update the config-object:: + + > config.set_userauth(actual_username, secret) + + Read some command-line arguments via argparse.ArgumentParser and update the + config:: + + > config.update_from_args(args) + """ + + @classmethod + def from_tcl(cls, section="default"): + config_dict = tcl.parse_tcl_config() + connection, options = _parse_tcl(config_dict, section) + return cls(**connection, **options) + + def set_userauth(self, username, password): + self.username = username + self.password = password + + def update_from_args(self, args): + """ + Assumes argparse-style args namespace object + + arg-names not found in the config-object are ignored. + """ + for arg in vars(args): + value = getattr(args, arg, None) + if arg in vars(self): + setattr(self, arg, value) diff --git a/tests/test_config_tcl.py b/tests/test_zinolib_config_tcl.py similarity index 100% rename from tests/test_config_tcl.py rename to tests/test_zinolib_config_tcl.py diff --git a/tests/test_config_utils.py b/tests/test_zinolib_config_utils.py similarity index 100% rename from tests/test_config_utils.py rename to tests/test_zinolib_config_utils.py diff --git a/tests/test_zinolib_config_zino1.py b/tests/test_zinolib_config_zino1.py new file mode 100644 index 0000000..27934b4 --- /dev/null +++ b/tests/test_zinolib_config_zino1.py @@ -0,0 +1,74 @@ +import unittest +from argparse import ArgumentParser + + +from zinolib.config.zino1 import ZinoV1Config, _parse_tcl + + +class ParseTclTest(unittest.TestCase): + + def test_parse_tcl_golden_path(self): + section = "default" + config_dict = { + "default": { + "Port": "8001", + "Secret": "0123456789", + "Server": "example.org", + "Sortby": '"upd-rev"', + "User": "admin", + }, + "dev-server": { + "Port": "8001", + "Secret": "0123456789", + "Server": "example.com", + "User": "admin", + }, + } + expected_connection = { + "port": "8001", + "password": "0123456789", + "server": "example.org", + "username": "admin", + } + expected_option = { + "sort_by": '"upd-rev"', + } + connection, options = _parse_tcl(config_dict, section) + self.assertEqual(expected_connection, connection) + self.assertEqual(expected_option, options) + + +class ZinoV1ConfigTest(unittest.TestCase): + + example_connection = { + "port": "8001", + "password": "0123456789", + "server": "example.org", + "username": "admin", + } + + def manually_create_config(self, connection=None): + connection = connection or self.example_connection + options = {} + return ZinoV1Config(**connection, **options) + + def test_manually_create_config(self): + config = self.manually_create_config() + self.assertEqual(config.port, "8001") + + def test_set_userauth(self): + config = self.manually_create_config() + self.assertEqual(config.username, "admin") + config.set_userauth('foo', 'barfybarf') + self.assertEqual(config.username, "foo") + + def test_update_from_args(self): + parser = ArgumentParser() + parser.add_argument("password") + parser.add_argument("unknown") + args = parser.parse_args(["x", "y"]) + config = self.manually_create_config() + self.assertEqual(config.password, "0123456789") + config.update_from_args(args) + self.assertEqual(config.password, "x") + self.assertNotIn("unknown", vars(config))