From 534b9e4ac7d4652781ea43e7538062fd2015f703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 9 Aug 2022 08:20:23 +0200 Subject: [PATCH] Add: Introduce new dataclass for storing the autohooks settings The settigs contain the mode and the list of activated plugin modules. The class allows to write the mode and plugins to a toml file like the pyproject.toml. --- autohooks/settings.py | 37 +++++++++++++++++++ tests/test_settings.py | 84 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/autohooks/settings.py b/autohooks/settings.py index 0c96b4b9..988dfa93 100644 --- a/autohooks/settings.py +++ b/autohooks/settings.py @@ -15,7 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from dataclasses import dataclass, field from enum import Enum +from pathlib import Path +from typing import Iterable + +import tomlkit class Mode(Enum): @@ -51,3 +56,35 @@ def from_string(modestring: str) -> "Mode": def __str__(self) -> str: return self.name.lower() # pylint: disable=no-member + + +@dataclass +class AutohooksSettings: + mode: Mode = Mode.UNDEFINED + pre_commit: Iterable[str] = field(default_factory=list) + + def write(self, filename: Path) -> None: + """ + Write the current AutohooksSettings to a TOML file + + If the TOML file already exists only the [tool.autohooks] section is + overridden. + """ + if filename.exists(): + toml_doc = tomlkit.loads(filename.read_text()) + else: + toml_doc = tomlkit.document() + + if "tool" not in toml_doc: + toml_doc["tool"] = tomlkit.table(is_super_table=True) + if "autohooks" not in toml_doc["tool"]: + toml_doc["tool"]["autohooks"] = tomlkit.table() + + config_dict = { + "mode": str(self.mode.get_effective_mode()), + "pre-commit": self.pre_commit, + } + + toml_doc["tool"]["autohooks"].update(config_dict) + + filename.write_text(tomlkit.dumps(toml_doc), encoding="utf8") diff --git a/tests/test_settings.py b/tests/test_settings.py index 361397ee..593605ce 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -15,9 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +# pylint: disable=invalid-name + import unittest -from autohooks.settings import Mode +from autohooks.settings import AutohooksSettings, Mode +from tests import tempdir, testfile class ModeTestCase(unittest.TestCase): @@ -77,5 +80,84 @@ def test_string_conversion(self): self.assertEqual(str(Mode.UNDEFINED), "undefined") +pyproject_toml_1 = """ +[tool.autohooks] +pre-commit = ['foo', 'bar'] +plugins.foo.bar = 'ipsum' +plugins.foo.lorem = 'dolor' + +[tool.autohooks.plugins.bar] +foo = 'bar' +""" + + +class AutohooksSettingsTestCase(unittest.TestCase): + def test_create_empty(self): + settings = AutohooksSettings() + self.assertEqual(settings.mode, Mode.UNDEFINED) + self.assertEqual(settings.pre_commit, []) + + def test_create(self): + settings = AutohooksSettings(mode=Mode.POETRY, pre_commit=["a", "b"]) + + self.assertEqual(settings.mode, Mode.POETRY) + self.assertEqual(settings.pre_commit, ["a", "b"]) + + def test_save_settings_new_empty(self): + settings = AutohooksSettings() + expected = """[tool.autohooks] +mode = "pythonpath" +pre-commit = [] +""" + with tempdir() as tmp_path: + toml = tmp_path / "test.toml" + settings.write(toml) + + self.assertEqual(settings.mode, Mode.UNDEFINED) + self.assertEqual(settings.pre_commit, []) + + self.assertEqual(toml.read_text(encoding="utf8"), expected) + + def test_save_empty_override(self): + settings = AutohooksSettings() + expected = """ +[tool.autohooks] +pre-commit = [] +mode = "pythonpath" +plugins.foo.bar = 'ipsum' +plugins.foo.lorem = 'dolor' + +[tool.autohooks.plugins.bar] +foo = 'bar' +""" + with testfile(pyproject_toml_1) as toml: + settings.write(toml) + + self.assertEqual(settings.mode, Mode.UNDEFINED) + self.assertEqual(settings.pre_commit, []) + + self.assertEqual(toml.read_text(encoding="utf8"), expected) + + def test_save_override(self): + settings = AutohooksSettings(mode=Mode.POETRY, pre_commit=["a", "b"]) + expected = """ +[tool.autohooks] +pre-commit = ["a", "b"] +mode = "poetry" +plugins.foo.bar = 'ipsum' +plugins.foo.lorem = 'dolor' + +[tool.autohooks.plugins.bar] +foo = 'bar' +""" + with testfile(pyproject_toml_1) as toml: + settings.write(toml) + + self.assertEqual(settings.mode, Mode.POETRY) + self.assertEqual(settings.pre_commit, ["a", "b"]) + + self.assertEqual(toml.read_text(encoding="utf8"), expected) + + if __name__ == "__main__": unittest.main()