From cb5e934c4a425e1b48f9d0e9470412dbf2a1ddca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Val=C3=AD=C4=8Dek?= Date: Sun, 26 Jun 2022 05:22:19 +0200 Subject: [PATCH] ClonerConfig + tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Václav Valíček --- repo_cloner/lib/cloner_config.py | 42 ++++++++++++++ repo_cloner/lib/default_cloner_config.py | 2 +- repo_cloner/process_repository_dir.py | 39 ++++++++++++- tests/lib/test_cloner_config.py | 74 ++++++++++++++++++++++++ tests/lib/test_default_cloner_config.py | 1 - 5 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 repo_cloner/lib/cloner_config.py create mode 100644 tests/lib/test_cloner_config.py diff --git a/repo_cloner/lib/cloner_config.py b/repo_cloner/lib/cloner_config.py new file mode 100644 index 0000000..1f4e194 --- /dev/null +++ b/repo_cloner/lib/cloner_config.py @@ -0,0 +1,42 @@ +from repo_cloner.lib.default_cloner_config import DefaultClonerConfig + + +class ClonerConfig(DefaultClonerConfig): + def __init__(self): + super().__init__() + self.__properties = list(filter(self.has_property, dir(self))) + self.__values = {} + + def __try_default(self, key: str, default_value): + if not self.has_property(key): + raise KeyError(f"{key} is not recognized config option") + if key in self.__values: + return self.__values[key] + return default_value + + @property + def cloner_project_name(self) -> str: + return self.__try_default("cloner_project_name", super(ClonerConfig, self).cloner_project_name) + + @property + def cloner_repo_url(self) -> str: + return self.__try_default("cloner_repo_url", super(ClonerConfig, self).cloner_repo_url) + + @property + def cloner_interval(self) -> int: + return self.__try_default("cloner_interval", super(ClonerConfig, self).cloner_interval) + + @property + def cloner_submodules(self) -> bool: + return self.__try_default("cloner_submodules", super(ClonerConfig, self).cloner_submodules) + + @property + def cloner_submodule_depth(self) -> int: + return self.__try_default("cloner_submodule_depth", super(ClonerConfig, self).cloner_submodule_depth) + + def _set_property(self, key: str, value): + if not self.has_property(key): + raise KeyError(f"{key} is not recognized config option") + if not isinstance(value, type(self.__getattribute__(key))): + raise ValueError(f"Invalid value for key {key}: type is {type(value)}") + self.__values[key] = value diff --git a/repo_cloner/lib/default_cloner_config.py b/repo_cloner/lib/default_cloner_config.py index d4f5e05..f3aeada 100644 --- a/repo_cloner/lib/default_cloner_config.py +++ b/repo_cloner/lib/default_cloner_config.py @@ -1,6 +1,6 @@ class DefaultClonerConfig: def __init__(self): - properties = list(filter(lambda prop: not str(prop).startswith("__"), dir(self))) + properties = list(filter(lambda prop: not str(prop).startswith("_"), dir(self))) self.__properties: list = properties @property diff --git a/repo_cloner/process_repository_dir.py b/repo_cloner/process_repository_dir.py index 4e95f40..f772fde 100755 --- a/repo_cloner/process_repository_dir.py +++ b/repo_cloner/process_repository_dir.py @@ -1,8 +1,25 @@ #!/usr/bin/env python3 import argparse +import os from repo_cloner.lib.repo_dir_structure import RepoDirStructure +from git.config import GitConfigParser +import logging as l + +l.basicConfig(level = 0) + + +def config_try_override(config_writer: GitConfigParser, section: str, option: str, value: str): + if not section in config_writer.sections(): + l.debug(f"CFG Creating section: {section}") + config_writer.add_section(section) + if not config_writer.has_option(section, option): + l.debug(f"CFG Creating option: {option}") + config_writer.add_value(section, option, "") + + l.debug(f"Setting {section}.{option} = {value}") + config_writer.set(section, option, value) def main(): @@ -13,9 +30,27 @@ def main(): args = parser.parse_args() dirs = RepoDirStructure(args.base_dir) - print(dirs) - dirs.exists + + os.environ['XDG_CONFIG_HOME'] = dirs.conf_dir + + from git import Repo + r = Repo("/home/vasek/dev/repo-cloner") + path: str = r._get_config_path("user") + print(path) + path = os.path.dirname(path) + print(path) + if not os.path.isdir(path): + os.mkdir(path) + + cred_store: str = os.path.join(path, "git-credentials") + ssh_identity: str = os.path.join(dirs.conf_dir, "ssh", "identity") + + with r.config_writer("user") as cfgw: + config_try_override(cfgw, "credential", "helper", f"store --file={cred_store}") + config_try_override(cfgw, "core", "sshcommand", + f"ssh -i {ssh_identity} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes -q") if __name__ == "__main__": + main() diff --git a/tests/lib/test_cloner_config.py b/tests/lib/test_cloner_config.py new file mode 100644 index 0000000..164440a --- /dev/null +++ b/tests/lib/test_cloner_config.py @@ -0,0 +1,74 @@ +from repo_cloner.lib.cloner_config import ClonerConfig +import pytest + + +def test_init(): + x = ClonerConfig() + + assert x._ClonerConfig__properties == ['cloner_interval', 'cloner_project_name', 'cloner_repo_url', + 'cloner_submodule_depth', 'cloner_submodules'] + assert isinstance(x._ClonerConfig__values, dict) + assert len(dict(x._ClonerConfig__values)) == 0 + + +def test_try_default(): + x = ClonerConfig() + assert 888 == x._ClonerConfig__try_default("cloner_interval", 888) + with pytest.raises(KeyError) as exc: + x._ClonerConfig__try_default("nonexistent_key", 888) + assert exc.exconly() == "KeyError: 'nonexistent_key is not recognized config option'" + + x._ClonerConfig__values['cloner_interval'] = 666 + assert 666 == x._ClonerConfig__try_default("cloner_interval", 888) + + +def test_cloner_project_name(): + x = ClonerConfig() + assert x.cloner_project_name == "" + x._ClonerConfig__values['cloner_project_name'] = "asdfgh" + assert x.cloner_project_name == "asdfgh" + + +def test_cloner_repo_url(): + x = ClonerConfig() + assert x.cloner_repo_url == "" + x._ClonerConfig__values['cloner_repo_url'] = "asdfgh" + assert x.cloner_repo_url == "asdfgh" + + +def test_cloner_interval(): + x = ClonerConfig() + assert x.cloner_interval == 5 + x._ClonerConfig__values['cloner_interval'] = 0 + assert x.cloner_interval == 0 + + +def test_cloner_submodules(): + x = ClonerConfig() + assert x.cloner_submodules == True + x._ClonerConfig__values['cloner_submodules'] = False + assert not x.cloner_submodules + + +def test_cloner_submodule_depth(): + x = ClonerConfig() + assert x.cloner_submodule_depth == 50000 + x._ClonerConfig__values['cloner_submodule_depth'] = -1 + assert x.cloner_submodule_depth == -1 + + +def test_set_property(): + x = ClonerConfig() + assert x.cloner_interval == 5 + x._set_property("cloner_interval", 0) + assert x.cloner_interval == 0 + + # invalid type + with pytest.raises(ValueError) as exc: + x._set_property("cloner_interval", "č") + assert exc.exconly() == "ValueError: Invalid value for key cloner_interval: type is " + + # undefined property + with pytest.raises(KeyError) as exc: + x._set_property("nonexistent_key", 888) + assert exc.exconly() == "KeyError: 'nonexistent_key is not recognized config option'" diff --git a/tests/lib/test_default_cloner_config.py b/tests/lib/test_default_cloner_config.py index cd79520..49a517e 100644 --- a/tests/lib/test_default_cloner_config.py +++ b/tests/lib/test_default_cloner_config.py @@ -33,4 +33,3 @@ def test_has_property(): assert x.has_property("cloner_interval") assert x.has_property("cloner_submodules") assert x.has_property("cloner_submodule_depth") - \ No newline at end of file