From d9871fbbd31ceb90a88b193fb60af5c7865742d6 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Tue, 12 Mar 2024 11:18:21 +0100 Subject: [PATCH 1/7] FIX: fix `Precommit.dumps()` method --- .../utilities/precommit/__init__.py | 3 ++- tests/utilities/precommit/test_class.py | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/utilities/precommit/test_class.py diff --git a/src/compwa_policy/utilities/precommit/__init__.py b/src/compwa_policy/utilities/precommit/__init__.py index 3c3ea51a..70efd79d 100644 --- a/src/compwa_policy/utilities/precommit/__init__.py +++ b/src/compwa_policy/utilities/precommit/__init__.py @@ -60,7 +60,8 @@ def load(cls: type[T], source: IO | Path | str = CONFIG_PATH.precommit) -> T: def dumps(self) -> str: with io.StringIO() as stream: - return self.parser.dump(self.document, stream) + self.parser.dump(self.document, stream) + return stream.getvalue() def find_repo(self, search_pattern: str) -> Repo | None: """Find pre-commit repo definition in pre-commit config.""" diff --git a/tests/utilities/precommit/test_class.py b/tests/utilities/precommit/test_class.py new file mode 100644 index 00000000..f9edc02e --- /dev/null +++ b/tests/utilities/precommit/test_class.py @@ -0,0 +1,19 @@ +from pathlib import Path + +import pytest + +from compwa_policy.utilities.precommit import Precommit + + +@pytest.fixture +def this_dir() -> Path: + return Path(__file__).parent + + +class TestPrecommit: + def test_dumps(self, this_dir: Path): + precommit = Precommit.load(this_dir / ".pre-commit-config.yaml") + yaml = precommit.dumps() + with open(this_dir / ".pre-commit-config.yaml") as file: + expected = file.read() + assert yaml == expected From 71a999597d138cd473233a2a430f659ce8169bde Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Tue, 12 Mar 2024 11:18:22 +0100 Subject: [PATCH 2/7] MAINT: define unit test for `editorconfig` module --- .../editorconfig/.pre-commit-config-bad.yaml | 5 ++++ .../.pre-commit-config-good-no-python.yaml | 7 +++++ .../editorconfig/.pre-commit-config-good.yaml | 11 ++++++++ .../check_dev_files/editorconfig/__init__.py | 0 .../editorconfig/test_editorconfig.py | 28 +++++++++++++++++++ 5 files changed, 51 insertions(+) create mode 100644 tests/check_dev_files/editorconfig/.pre-commit-config-bad.yaml create mode 100644 tests/check_dev_files/editorconfig/.pre-commit-config-good-no-python.yaml create mode 100644 tests/check_dev_files/editorconfig/.pre-commit-config-good.yaml create mode 100644 tests/check_dev_files/editorconfig/__init__.py create mode 100644 tests/check_dev_files/editorconfig/test_editorconfig.py diff --git a/tests/check_dev_files/editorconfig/.pre-commit-config-bad.yaml b/tests/check_dev_files/editorconfig/.pre-commit-config-bad.yaml new file mode 100644 index 00000000..d1e01790 --- /dev/null +++ b/tests/check_dev_files/editorconfig/.pre-commit-config-bad.yaml @@ -0,0 +1,5 @@ +repos: + - repo: https://github.com/editorconfig-checker/editorconfig-checker.python + rev: 2.7.3 + hooks: + - id: editorconfig-checker diff --git a/tests/check_dev_files/editorconfig/.pre-commit-config-good-no-python.yaml b/tests/check_dev_files/editorconfig/.pre-commit-config-good-no-python.yaml new file mode 100644 index 00000000..5de1a635 --- /dev/null +++ b/tests/check_dev_files/editorconfig/.pre-commit-config-good-no-python.yaml @@ -0,0 +1,7 @@ +repos: + - repo: https://github.com/editorconfig-checker/editorconfig-checker.python + rev: 2.7.3 + hooks: + - id: editorconfig-checker + name: editorconfig + alias: ec diff --git a/tests/check_dev_files/editorconfig/.pre-commit-config-good.yaml b/tests/check_dev_files/editorconfig/.pre-commit-config-good.yaml new file mode 100644 index 00000000..0f28f1e4 --- /dev/null +++ b/tests/check_dev_files/editorconfig/.pre-commit-config-good.yaml @@ -0,0 +1,11 @@ +repos: + - repo: https://github.com/editorconfig-checker/editorconfig-checker.python + rev: 2.7.3 + hooks: + - id: editorconfig-checker + name: editorconfig + alias: ec + exclude: >- + (?x)^( + .*\.py + )$ diff --git a/tests/check_dev_files/editorconfig/__init__.py b/tests/check_dev_files/editorconfig/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/check_dev_files/editorconfig/test_editorconfig.py b/tests/check_dev_files/editorconfig/test_editorconfig.py new file mode 100644 index 00000000..e21fdfa3 --- /dev/null +++ b/tests/check_dev_files/editorconfig/test_editorconfig.py @@ -0,0 +1,28 @@ +from pathlib import Path + +import pytest + +from compwa_policy.check_dev_files.editorconfig import _update_precommit_config +from compwa_policy.errors import PrecommitError +from compwa_policy.utilities.precommit import ModifiablePrecommit + + +@pytest.mark.parametrize("no_python", [True, False]) +def test_update_precommit_config(no_python: bool): + this_dir = Path(__file__).parent + with open(this_dir / ".pre-commit-config-bad.yaml") as file: + src = file.read() + + with pytest.raises( + PrecommitError, match=r"Updated editorconfig-checker hook" + ), ModifiablePrecommit.load(src) as precommit: + _update_precommit_config(precommit, no_python) + + result = precommit.dumps() + if no_python: + expected_file = this_dir / ".pre-commit-config-good-no-python.yaml" + else: + expected_file = this_dir / ".pre-commit-config-good.yaml" + with open(expected_file) as file: + expected = file.read() + assert result == expected From 840fff03b41840f5cc7e74726b914adf269f3c79 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Tue, 12 Mar 2024 11:18:23 +0100 Subject: [PATCH 3/7] MAINT: test `ModifiablePrecommit` as context manager --- tests/utilities/precommit/test_class.py | 46 ++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/tests/utilities/precommit/test_class.py b/tests/utilities/precommit/test_class.py index f9edc02e..2af4f35e 100644 --- a/tests/utilities/precommit/test_class.py +++ b/tests/utilities/precommit/test_class.py @@ -1,8 +1,10 @@ +import io from pathlib import Path import pytest -from compwa_policy.utilities.precommit import Precommit +from compwa_policy.errors import PrecommitError +from compwa_policy.utilities.precommit import ModifiablePrecommit, Precommit @pytest.fixture @@ -10,10 +12,44 @@ def this_dir() -> Path: return Path(__file__).parent +@pytest.fixture +def example_config(this_dir: Path) -> str: + with open(this_dir / ".pre-commit-config.yaml") as file: + return file.read() + + +class TestModifiablePrecommit: + def test_no_context_manager(self, example_config: str): + with pytest.raises( + expected_exception=RuntimeError, + match=r"^Modifications can only be made within a context$", + ): + precommit = ModifiablePrecommit.load(example_config) + precommit.document["fail_fast"] = True + precommit.append_to_changelog("Fake modification") + + def test_context_manager_path(self, this_dir: Path, example_config: str): + with pytest.raises( + PrecommitError, + match=r"Fake modification$", + ), ModifiablePrecommit.load(this_dir / ".pre-commit-config.yaml") as precommit: + precommit.append_to_changelog("Fake modification") + yaml = precommit.dumps() + assert yaml == example_config + + def test_context_manager_string_stream(self, example_config: str): + stream = io.StringIO(example_config) + with pytest.raises( + PrecommitError, match=r"Fake modification$" + ), ModifiablePrecommit.load(stream) as precommit: + precommit.append_to_changelog("Fake modification") + stream.seek(0) + yaml = stream.read() + assert yaml == example_config + + class TestPrecommit: - def test_dumps(self, this_dir: Path): + def test_dumps(self, this_dir: Path, example_config: str): precommit = Precommit.load(this_dir / ".pre-commit-config.yaml") yaml = precommit.dumps() - with open(this_dir / ".pre-commit-config.yaml") as file: - expected = file.read() - assert yaml == expected + assert yaml == example_config From 97cac9c1d85de08b6458bafdae3c0f063f914de8 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Tue, 12 Mar 2024 11:18:24 +0100 Subject: [PATCH 4/7] FIX: return `bool` at `__exit__()` --- src/compwa_policy/utilities/executor.py | 9 +++++++-- src/compwa_policy/utilities/precommit/__init__.py | 6 ++++-- src/compwa_policy/utilities/pyproject/__init__.py | 6 ++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/compwa_policy/utilities/executor.py b/src/compwa_policy/utilities/executor.py index fd809ce9..6337d41f 100644 --- a/src/compwa_policy/utilities/executor.py +++ b/src/compwa_policy/utilities/executor.py @@ -105,14 +105,19 @@ def __exit__( exc_type: type[BaseException] | None, exc_value: BaseException | None, tb: TracebackType | None, - ) -> None: + ) -> bool: + if exc_type is not None and not issubclass(exc_type, PrecommitError): + return False + if isinstance(exc_value, PrecommitError): + self.__error_messages.append(str("\n".join(exc_value.args))) error_msg = self.merge_messages() if error_msg: if self.__raise_exception: - raise PrecommitError(error_msg) from exc_value + raise PrecommitError(error_msg) print(error_msg) # noqa: T201 if os.getenv("COMPWA_POLICY_DEBUG") is not None: self.print_execution_times() + return True def merge_messages(self) -> str: stripped_messages = (s.strip() for s in self.__error_messages) diff --git a/src/compwa_policy/utilities/precommit/__init__.py b/src/compwa_policy/utilities/precommit/__init__.py index 70efd79d..d82b374a 100644 --- a/src/compwa_policy/utilities/precommit/__init__.py +++ b/src/compwa_policy/utilities/precommit/__init__.py @@ -89,9 +89,11 @@ def __exit__( exc_type: type[BaseException] | None, exc_value: BaseException | None, tb: TracebackType | None, - ) -> None: + ) -> bool: + if exc_type is not None and not issubclass(exc_type, PrecommitError): + return False if not self.__changelog: - return + return True if self.parser is None: self.dump(self.source) msg = "The following modifications were made" diff --git a/src/compwa_policy/utilities/pyproject/__init__.py b/src/compwa_policy/utilities/pyproject/__init__.py index 86dff787..0c384d00 100644 --- a/src/compwa_policy/utilities/pyproject/__init__.py +++ b/src/compwa_policy/utilities/pyproject/__init__.py @@ -159,9 +159,11 @@ def __exit__( exc_type: type[BaseException] | None, exc_value: BaseException | None, tb: TracebackType | None, - ) -> None: + ) -> bool: + if exc_type is not None and not issubclass(exc_type, PrecommitError): + return False if not self._changelog: - return + return True if self._source is None: self.dump(self._source) msg = "The following modifications were made" From 973ef9b83485f6b6c8485ccbccb5950f3ae65750 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Tue, 12 Mar 2024 11:18:25 +0100 Subject: [PATCH 5/7] FIX: correctly dump to file if exiting context --- src/compwa_policy/utilities/precommit/__init__.py | 2 +- src/compwa_policy/utilities/pyproject/__init__.py | 2 +- tests/check_dev_files/editorconfig/test_editorconfig.py | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/compwa_policy/utilities/precommit/__init__.py b/src/compwa_policy/utilities/precommit/__init__.py index d82b374a..e4e4e651 100644 --- a/src/compwa_policy/utilities/precommit/__init__.py +++ b/src/compwa_policy/utilities/precommit/__init__.py @@ -94,7 +94,7 @@ def __exit__( return False if not self.__changelog: return True - if self.parser is None: + if self.parser is not None: self.dump(self.source) msg = "The following modifications were made" if isinstance(self.source, Path): diff --git a/src/compwa_policy/utilities/pyproject/__init__.py b/src/compwa_policy/utilities/pyproject/__init__.py index 0c384d00..1ad203b1 100644 --- a/src/compwa_policy/utilities/pyproject/__init__.py +++ b/src/compwa_policy/utilities/pyproject/__init__.py @@ -164,7 +164,7 @@ def __exit__( return False if not self._changelog: return True - if self._source is None: + if self._source is not None: self.dump(self._source) msg = "The following modifications were made" if isinstance(self._source, (Path, str)): diff --git a/tests/check_dev_files/editorconfig/test_editorconfig.py b/tests/check_dev_files/editorconfig/test_editorconfig.py index e21fdfa3..2a3690f7 100644 --- a/tests/check_dev_files/editorconfig/test_editorconfig.py +++ b/tests/check_dev_files/editorconfig/test_editorconfig.py @@ -1,3 +1,4 @@ +import io from pathlib import Path import pytest @@ -13,9 +14,10 @@ def test_update_precommit_config(no_python: bool): with open(this_dir / ".pre-commit-config-bad.yaml") as file: src = file.read() + stream = io.StringIO(src) with pytest.raises( PrecommitError, match=r"Updated editorconfig-checker hook" - ), ModifiablePrecommit.load(src) as precommit: + ), ModifiablePrecommit.load(stream) as precommit: _update_precommit_config(precommit, no_python) result = precommit.dumps() From 6e462ba8c1f1e4ef1848e8a669cda602cef17287 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Tue, 12 Mar 2024 11:43:49 +0100 Subject: [PATCH 6/7] FIX: reset string stream on load --- src/compwa_policy/utilities/precommit/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compwa_policy/utilities/precommit/__init__.py b/src/compwa_policy/utilities/precommit/__init__.py index e4e4e651..d7e39e2f 100644 --- a/src/compwa_policy/utilities/precommit/__init__.py +++ b/src/compwa_policy/utilities/precommit/__init__.py @@ -150,6 +150,7 @@ def _load_roundtrip_precommit_config( parser = create_prettier_round_trip_yaml() if isinstance(source, str): with io.StringIO(source) as stream: + stream.seek(0) config = parser.load(stream) else: config = parser.load(source) From ba7130bdc4829a41c3daa82ba947923a7201eaff Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Tue, 12 Mar 2024 11:45:13 +0100 Subject: [PATCH 7/7] Revert "FIX: reset string stream on load" This reverts commit 6e462ba8c1f1e4ef1848e8a669cda602cef17287. --- src/compwa_policy/utilities/precommit/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compwa_policy/utilities/precommit/__init__.py b/src/compwa_policy/utilities/precommit/__init__.py index d7e39e2f..e4e4e651 100644 --- a/src/compwa_policy/utilities/precommit/__init__.py +++ b/src/compwa_policy/utilities/precommit/__init__.py @@ -150,7 +150,6 @@ def _load_roundtrip_precommit_config( parser = create_prettier_round_trip_yaml() if isinstance(source, str): with io.StringIO(source) as stream: - stream.seek(0) config = parser.load(stream) else: config = parser.load(source)